aboutsummaryrefslogtreecommitdiff
path: root/src/server/RouteManager.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/RouteManager.ts')
-rw-r--r--src/server/RouteManager.ts59
1 files changed, 32 insertions, 27 deletions
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index 41204964e..d072b7709 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -1,6 +1,6 @@
import RouteSubscriber from "./RouteSubscriber";
import { DashUserModel } from "./authentication/models/user_model";
-import * as express from 'express';
+import { Request, Response, Express } from 'express';
import { cyan, red, green } from 'colors';
export enum Method {
@@ -9,21 +9,22 @@ export enum Method {
}
export interface CoreArguments {
- req: express.Request;
- res: express.Response;
+ req: Request;
+ res: Response;
isRelease: boolean;
}
-export type OnValidation = (core: CoreArguments & { user: DashUserModel }) => any | Promise<any>;
-export type OnUnauthenticated = (core: CoreArguments) => any | Promise<any>;
-export type OnError = (core: CoreArguments & { error: any }) => any | Promise<any>;
+export type AuthorizedCore = CoreArguments & { user: DashUserModel };
+export type SecureHandler = (core: AuthorizedCore) => any | Promise<any>;
+export type PublicHandler = (core: CoreArguments) => any | Promise<any>;
+export type ErrorHandler = (core: CoreArguments & { error: any }) => any | Promise<any>;
export interface RouteInitializer {
method: Method;
subscription: string | RouteSubscriber | (string | RouteSubscriber)[];
- onValidation: OnValidation;
- onUnauthenticated?: OnUnauthenticated;
- onError?: OnError;
+ secureHandler: SecureHandler;
+ publicHandler?: PublicHandler;
+ errorHandler?: ErrorHandler;
}
const registered = new Map<string, Set<Method>>();
@@ -34,7 +35,7 @@ enum RegistrationError {
}
export default class RouteManager {
- private server: express.Express;
+ private server: Express;
private _isRelease: boolean;
private failedRegistrations: { route: string, reason: RegistrationError }[] = [];
@@ -42,7 +43,7 @@ export default class RouteManager {
return this._isRelease;
}
- constructor(server: express.Express, isRelease: boolean) {
+ constructor(server: Express, isRelease: boolean) {
this.server = server;
this._isRelease = isRelease;
}
@@ -67,10 +68,9 @@ export default class RouteManager {
console.log('please remove all duplicate routes before continuing');
}
if (malformedCount) {
- console.log(`please ensure all routes adhere to ^\/[A-Za-z]+(\/\:[A-Za-z]+)*$`);
+ console.log(`please ensure all routes adhere to ^\/$|^\/[A-Za-z]+(\/\:[A-Za-z?]+)*$`);
}
- console.log();
- process.exit(0);
+ process.exit(1);
} else {
console.log(green("all server routes have been successfully registered:"));
Array.from(registered.keys()).sort().forEach(route => console.log(cyan(route)));
@@ -83,29 +83,34 @@ export default class RouteManager {
* @param initializer
*/
addSupervisedRoute = (initializer: RouteInitializer): void => {
- const { method, subscription, onValidation, onUnauthenticated, onError } = initializer;
+ const { method, subscription, secureHandler, publicHandler, errorHandler } = initializer;
+
const isRelease = this._isRelease;
- const supervised = async (req: express.Request, res: express.Response) => {
- const { user, originalUrl: target } = req;
+ const supervised = async (req: Request, res: Response) => {
+ let { user } = req;
+ const { originalUrl: target } = req;
+ if (process.env.DB === "MEM" && !user) {
+ user = { id: "guest", email: "", userDocumentId: "guestDocId" };
+ }
const core = { req, res, isRelease };
const tryExecute = async (toExecute: (args: any) => any | Promise<any>, args: any) => {
try {
await toExecute(args);
} catch (e) {
console.log(red(target), user && ("email" in user) ? "<user logged out>" : undefined);
- if (onError) {
- onError({ ...core, error: e });
+ if (errorHandler) {
+ errorHandler({ ...core, error: e });
} else {
_error(res, `The server encountered an internal error when serving ${target}.`, e);
}
}
};
if (user) {
- await tryExecute(onValidation, { ...core, user });
+ await tryExecute(secureHandler, { ...core, user });
} else {
req.session!.target = target;
- if (onUnauthenticated) {
- await tryExecute(onUnauthenticated, core);
+ if (publicHandler) {
+ await tryExecute(publicHandler, core);
if (!res.headersSent) {
res.redirect("/login");
}
@@ -128,7 +133,7 @@ export default class RouteManager {
} else {
route = subscriber.build;
}
- if (!/^\/[A-Za-z]+(\/\:[A-Za-z]+)*$/g.test(route)) {
+ if (!/^\/$|^\/[A-Za-z]+(\/\:[A-Za-z?]+)*$/g.test(route)) {
this.failedRegistrations.push({
reason: RegistrationError.Malformed,
route
@@ -174,22 +179,22 @@ export const STATUS = {
PERMISSION_DENIED: 403
};
-export function _error(res: express.Response, message: string, error?: any) {
+export function _error(res: Response, message: string, error?: any) {
console.error(message);
res.statusMessage = message;
res.status(STATUS.EXECUTION_ERROR).send(error);
}
-export function _success(res: express.Response, body: any) {
+export function _success(res: Response, body: any) {
res.status(STATUS.OK).send(body);
}
-export function _invalid(res: express.Response, message: string) {
+export function _invalid(res: Response, message: string) {
res.statusMessage = message;
res.status(STATUS.BAD_REQUEST).send();
}
-export function _permission_denied(res: express.Response, message?: string) {
+export function _permission_denied(res: Response, message?: string) {
if (message) {
res.statusMessage = message;
}