gristlabs_grist-core/app/server/lib/expressWrap.ts
George Gevoian 99f3422217 (core) Add new Grist sign-up page
Summary:
Available at login.getgrist.com/signup, the new sign-up page
includes similar options available on the hosted Cognito sign-up
page, such as support for registering with Google. All previous
redirects to Cognito for sign-up should now redirect to the new
Grist sign-up page.

Login is still handled with the hosted Cognito login page, and there
is a link to go there from the new sign-up page.

Test Plan: Browser, project and server tests.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D3249
2022-02-14 10:32:47 -08:00

71 lines
2.5 KiB
TypeScript

import {RequestWithLogin} from 'app/server/lib/Authorizer';
import * as log from 'app/server/lib/log';
import * as express from 'express';
/**
* Wrapper for async express endpoints to catch errors and forward them to the error handler.
*/
export function expressWrap(callback: express.RequestHandler): express.RequestHandler {
return async (req, res, next) => {
try {
await callback(req, res, next);
} catch (err) {
next(err);
}
};
}
interface JsonErrorHandlerOptions {
shouldLogBody?: boolean;
shouldLogParams?: boolean;
}
/**
* Returns a custom error-handling middleware that responds to errors in json.
*
* Currently allows for toggling of logging request bodies and params.
*/
const buildJsonErrorHandler = (options: JsonErrorHandlerOptions = {}): express.ErrorRequestHandler => {
return (err, req, res, _next) => {
const mreq = req as RequestWithLogin;
log.warn(
"Error during api call to %s: (%s)%s%s%s",
req.path, err.message, mreq.userId !== undefined ? ` user ${mreq.userId}` : '',
options.shouldLogParams !== false ? ` params ${JSON.stringify(req.params)}` : '',
options.shouldLogBody !== false ? ` body ${JSON.stringify(req.body)}` : '',
);
let details = err.details && {...err.details};
const status = details?.status || err.status || 500;
if (details) {
// Remove some details exposed for websocket API only.
delete details.accessMode;
delete details.status; // TODO: reconcile err.status and details.status, no need for both.
if (Object.keys(details).length === 0) { details = undefined; }
}
res.status(status).json({error: err.message || 'internal error', details});
};
};
/**
* Error-handling middleware that responds to errors in json. The status code is taken from
* error.status property (for which ApiError is convenient), and defaults to 500.
*/
export const jsonErrorHandler: express.ErrorRequestHandler = buildJsonErrorHandler();
/**
* Variant of `jsonErrorHandler` that skips logging request bodies and params.
*
* Should be used for sensitive routes, such as those under '/api/auth/'.
*/
export const secureJsonErrorHandler: express.ErrorRequestHandler = buildJsonErrorHandler({
shouldLogBody: false,
shouldLogParams: false,
});
/**
* Middleware that responds with a 404 status and a json error object.
*/
export const jsonNotFoundHandler: express.RequestHandler = (req, res, next) => {
res.status(404).json({error: `not found: ${req.url}`});
};