Refactor & unit tests
This commit is contained in:
17
src/utilities/errors.ts
Normal file
17
src/utilities/errors.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export class BadRequestError extends Error {
|
||||
constructor(message: string | undefined = undefined) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
export class UnauthorizedError extends Error {
|
||||
constructor(message: string | undefined = undefined) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
export class NotFoundError extends Error {
|
||||
constructor(message: string | undefined = undefined) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
57
src/utilities/guard.ts
Normal file
57
src/utilities/guard.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import {BunRequest as Request} from 'bun';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import {Claims} from "../orm/orm.ts";
|
||||
|
||||
export function guardRedirect(method: Function, redirectMethod: Function, guardedClaims: string[] | undefined = undefined) {
|
||||
try {
|
||||
return guard(method, guardedClaims);
|
||||
} catch (e) {
|
||||
return redirectMethod();
|
||||
}
|
||||
}
|
||||
|
||||
export function guard(method: Function, guardedClaims: string[] | undefined = undefined):(r:Request)=>Promise<Response> {
|
||||
return async (request: Request): Promise<Response> => {
|
||||
const authHeader: string | null = request.headers.get('Authorization')?.replace(/^Bearer /, '') as string ?? null;
|
||||
try {
|
||||
const userClaims: Claims = jwt.verify(authHeader as string, process.env.JWT_SECRET_KEY as string) as Claims;
|
||||
console.log('Claims?', guardedClaims !== undefined, !userClaims.claims.some(x => guardedClaims?.includes(x)))
|
||||
if (guardedClaims !== undefined && !userClaims.claims.some(x => guardedClaims.includes(x))) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
return method(await unwrap(request, userClaims));
|
||||
} catch (e) {
|
||||
return Response.json({message: 'Authentication failed.'}, {status: 401})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class UnwrappedRequest {
|
||||
readonly json: any;
|
||||
readonly request: Request;
|
||||
readonly params: { [x: string]: string };
|
||||
readonly claims: Claims;
|
||||
|
||||
constructor(input: any) {
|
||||
this.json = input.json;
|
||||
this.request = input.request;
|
||||
this.claims = input.claims;
|
||||
this.params = input.params;
|
||||
}
|
||||
}
|
||||
|
||||
export async function unwrap(request: Request, claims: Claims | null = null) {
|
||||
return new UnwrappedRequest({
|
||||
request,
|
||||
claims,
|
||||
json: request.body ? await request.json() : null,
|
||||
params: request.params,
|
||||
})
|
||||
}
|
||||
|
||||
export function unwrapMethod(methodToUnwrap:((r:UnwrappedRequest)=>Response)|((r:UnwrappedRequest)=>Promise<Response>)):(r:Request)=>Promise<Response> {
|
||||
return async (request: Request) => {
|
||||
const unwrappedRequest = await unwrap(request);
|
||||
return await methodToUnwrap(unwrappedRequest);
|
||||
};
|
||||
}
|
||||
18
src/utilities/responseHelper.ts
Normal file
18
src/utilities/responseHelper.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import {BadRequestError, NotFoundError, UnauthorizedError} from "./errors";
|
||||
|
||||
export class ErrorResponse extends Response {
|
||||
//@ts-ignore
|
||||
constructor(error: Error) {
|
||||
if(error instanceof BadRequestError) {
|
||||
return Response.json({message: error.message}, {status: 400});
|
||||
}
|
||||
else if(error instanceof UnauthorizedError){
|
||||
return Response.json({message: error.message}, {status: 401});
|
||||
}
|
||||
else if(error instanceof NotFoundError){
|
||||
return Response.json({message: error.message}, {status: 404});
|
||||
}
|
||||
|
||||
return Response.json({message: error.message}, {status: 500});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user