Skip to content

Commit

Permalink
Refactor development and start scripts in package.json; streamline au…
Browse files Browse the repository at this point in the history
…thentication logic in context.ts; enhance error formatting in formatError.ts; improve session handling in Session.ts
  • Loading branch information
jthoward64 committed Jan 17, 2025
1 parent 198bc27 commit 1519134
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 36 deletions.
4 changes: 2 additions & 2 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
"bs": "yarn run build && yarn run start",
"build": "tsc",
"check": "tsc --noEmit",
"dev": "tsc --watch & node --import @sentry/node/preload --enable-source-maps --watch-path=./dist --watch-path=../common/dist ./dist/src/index.js",
"dev": "tsc --watch & node --enable-source-maps --watch-path=./dist --watch-path=../common/dist ./dist/src/index.js start",
"lint": "eslint .",
"migrate-and-start": "yarn dlx prisma migrate deploy && yarn run start",
"start": "node --import @sentry/node/preload --enable-source-maps ./dist/src/index.js start",
"start": "node --enable-source-maps ./dist/src/index.js start",
"repl": "node --enable-source-maps ./dist/src/index.js repl",
"test": "jest"
},
Expand Down
1 change: 1 addition & 0 deletions packages/server/src/entry/server/Express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export class ExpressModule {
err,
this.isDevelopment
);

if (
formatted.extensions &&
"code" in formatted.extensions &&
Expand Down
26 changes: 4 additions & 22 deletions packages/server/src/lib/auth/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,28 +100,10 @@ export const authenticate: ContextFunction<
[ExpressContextFunctionArgument],
GraphQLContext
> = async ({ req }): Promise<GraphQLContext> => {
// Get the token from the cookies or the Authorization header
let token = (req.cookies as Partial<Record<string, string>>).token
? String((req.cookies as Partial<Record<string, string>>).token)
: undefined;
if (!token) {
let authorizationHeader =
req.headers.Authorization || req.headers.authorization;
if (Array.isArray(authorizationHeader)) {
authorizationHeader = authorizationHeader[0];
}
if (authorizationHeader?.startsWith("Bearer ")) {
token = authorizationHeader.substring("Bearer ".length);
}
}
let person: Person | null = null;
let authSource: AuthSource = AuthSource.None;
if (token) {
({ person, authSource } = req.session ?? {
authSource: AuthSource.None,
person: null,
});
}
const { person, authSource } = req.session ?? {
authSource: AuthSource.None,
person: null,
};

let userContext: UserContext | undefined = undefined;
if (person) {
Expand Down
24 changes: 18 additions & 6 deletions packages/server/src/lib/formatError.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { unwrapResolverError } from "@apollo/server/errors";
import type { GraphQLFormattedErrorWithExtensions } from "@ukdanceblue/common/error";
import { ErrorCode, FormattedConcreteError } from "@ukdanceblue/common/error";
import {
ConcreteError,
ErrorCode,
FormattedConcreteError,
} from "@ukdanceblue/common/error";
import type { GraphQLFormattedError } from "graphql";
import { GraphQLError } from "graphql";
import jwt from "jsonwebtoken";
Expand All @@ -25,16 +29,24 @@ export function formatError(
return error.toJSON();
}

let stacktrace: string[] | undefined;
if (error instanceof Error) {
stacktrace = error.stack?.split("\n") ?? [];
} else if (error instanceof ConcreteError) {
stacktrace = error.stack?.split("\n") ?? [];
}

const formattedError: Writable<GraphQLFormattedErrorWithExtensions> = {
...originalFormattedError,
extensions: {
...originalFormattedError.extensions,
code: ErrorCode.Unknown.description,
stacktrace:
shouldIncludeSensitiveInfo &&
Array.isArray(originalFormattedError.extensions?.stacktrace)
? originalFormattedError.extensions.stacktrace.map(String)
: [],
stacktrace: shouldIncludeSensitiveInfo
? stacktrace ||
(Array.isArray(originalFormattedError.extensions?.stacktrace)
? originalFormattedError.extensions.stacktrace.map(String)
: [])
: [],
},
};

Expand Down
21 changes: 15 additions & 6 deletions packages/server/src/repositories/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,21 @@ export class SessionRepository extends buildDefaultRepository("Session", {}) {
verify(
token,
this.jwtSecret,
{ complete: false, issuer: JWT_ISSUER },
{
complete: false,
issuer: JWT_ISSUER,
},
(err, decoded) => {
if (err) {
resolve(Err(toBasicError(err)));
} else if (!decoded) {
resolve(Err(new InvariantError("No decoded token")));
} else if (typeof decoded !== "string") {
} else if (typeof decoded !== "object") {
resolve(Err(new InvariantError("Decoded token is not a string")));
} else if (!decoded.sub) {
resolve(Err(new InvariantError("No sub in decoded token")));
} else {
resolve(Ok(decoded));
resolve(Ok(decoded.sub));
}
}
);
Expand Down Expand Up @@ -161,9 +166,13 @@ export class SessionRepository extends buildDefaultRepository("Session", {}) {
return new AsyncResult<string, RepositoryError>(
new Promise((resolve) => {
sign(
session.uuid,
{
iss: JWT_ISSUER,
sub: session.uuid,
exp: Math.floor(session.expiresAt.getTime() / 1000),
},
this.jwtSecret,
{ issuer: JWT_ISSUER },
{},
(err, token) => {
if (err) {
resolve(Err(toBasicError(err)));
Expand Down Expand Up @@ -237,7 +246,7 @@ export class SessionRepository extends buildDefaultRepository("Session", {}) {
next();
} else {
const result = this.verifySession(token, {
ip: req.ip,
ip: req.ips[0] ?? req.ip,
userAgent: req.headers["user-agent"],
})
.andThen(
Expand Down

0 comments on commit 1519134

Please sign in to comment.