Give the redirectBack function its own Component back

This commit is contained in:
Alice Gaudon 2020-07-28 10:03:25 +02:00
parent 6b85a538c1
commit 3a4755ce98
4 changed files with 47 additions and 17 deletions

View File

@ -9,6 +9,7 @@ import {AuthError, PendingApprovalAuthError, RegisterCallback} from "../AuthGuar
import geoip from "geoip-lite"; import geoip from "geoip-lite";
import AuthController from "../AuthController"; import AuthController from "../AuthController";
import NunjucksComponent from "../../components/NunjucksComponent"; import NunjucksComponent from "../../components/NunjucksComponent";
import RedirectBackComponent from "../../components/RedirectBackComponent";
export default abstract class MagicLinkAuthController extends AuthController { export default abstract class MagicLinkAuthController extends AuthController {
@ -109,7 +110,7 @@ export default abstract class MagicLinkAuthController extends AuthController {
); );
res.redirect(Controller.route('magic_link_lobby', undefined, { res.redirect(Controller.route('magic_link_lobby', undefined, {
redirect_uri: req.query.redirect_uri?.toString() || NunjucksComponent.getPreviousURL(req), redirect_uri: req.query.redirect_uri?.toString() || RedirectBackComponent.getPreviousURL(req),
})); }));
} else { } else {
// Confirm registration req // Confirm registration req

View File

@ -1,6 +1,6 @@
import nunjucks, {Environment} from "nunjucks"; import nunjucks, {Environment} from "nunjucks";
import config from "config"; import config from "config";
import {Express, Request, Router} from "express"; import {Express, Router} from "express";
import ApplicationComponent from "../ApplicationComponent"; import ApplicationComponent from "../ApplicationComponent";
import Controller from "../Controller"; import Controller from "../Controller";
import {ServerError} from "../HttpError"; import {ServerError} from "../HttpError";
@ -9,13 +9,6 @@ import {ParsedUrlQueryInput} from "querystring";
import * as util from "util"; import * as util from "util";
export default class NunjucksComponent extends ApplicationComponent<void> { export default class NunjucksComponent extends ApplicationComponent<void> {
public static getPreviousURL(req: Request, defaultUrl?: string): string {
let referrer = req.headers.referer?.toString() || req.headers.referrer?.toString() || defaultUrl || '/';
if (referrer.startsWith('https://') || referrer.startsWith('http://')) return '/';
else if (!referrer.startsWith('/')) referrer = req.url + (req.url.endsWith('/') ? '' : '/') + referrer;
return referrer;
}
private readonly viewsPath: string; private readonly viewsPath: string;
private env?: Environment; private env?: Environment;
@ -72,14 +65,6 @@ export default class NunjucksComponent extends ApplicationComponent<void> {
res.locals.app = config.get('app'); res.locals.app = config.get('app');
// Redirect back
res.redirectBack = (defaultUrl?: string) => {
res.redirect(NunjucksComponent.getPreviousURL(req, defaultUrl));
};
res.locals.getPreviousURL = (defaultURL?: string) => {
return NunjucksComponent.getPreviousURL(req, defaultURL);
};
next(); next();
}); });
} }

View File

@ -0,0 +1,42 @@
import ApplicationComponent from "../ApplicationComponent";
import {Request, Router} from "express";
import {ServerError} from "../HttpError";
import onFinished from "on-finished";
import Logger from "../Logger";
export default class RedirectBackComponent extends ApplicationComponent<void> {
public static getPreviousURL(req: Request, defaultUrl?: string): string | undefined {
return req.session?.previousUrl || defaultUrl;
}
public async handle(router: Router): Promise<void> {
router.use((req, res, next) => {
res.redirectBack = (defaultUrl?: string) => {
const previousUrl = RedirectBackComponent.getPreviousURL(req, defaultUrl);
if (!previousUrl) throw new ServerError(`Couldn't redirect you back.`);
res.redirect(previousUrl);
};
res.locals.getPreviousURL = (defaultUrl?: string) => {
return RedirectBackComponent.getPreviousURL(req, defaultUrl);
};
onFinished(res, (err) => {
if (req.session) {
const contentType = (res.getHeaders())['content-type'];
if (!err && res.statusCode === 200 && (contentType && typeof contentType !== 'number' && contentType.indexOf('text/html') >= 0)) {
req.session!.previousUrl = req.originalUrl;
Logger.debug('Prev url set to', req.session!.previousUrl);
req.session!.save((err) => {
if (err) {
Logger.error(err, 'Error while saving session');
}
});
}
}
});
next();
});
}
}

View File

@ -14,6 +14,7 @@ import AuthComponent from "../src/auth/AuthComponent";
import AuthGuard from "../src/auth/AuthGuard"; import AuthGuard from "../src/auth/AuthGuard";
import MagicLink from "../src/auth/models/MagicLink"; import MagicLink from "../src/auth/models/MagicLink";
import FormHelperComponent from "../src/components/FormHelperComponent"; import FormHelperComponent from "../src/components/FormHelperComponent";
import RedirectBackComponent from "../src/components/RedirectBackComponent";
export default function useApp(appSupplier?: (port: number) => TestApp) { export default function useApp(appSupplier?: (port: number) => TestApp) {
let app: Application; let app: Application;
@ -61,6 +62,7 @@ export class TestApp extends Application {
// Base // Base
this.use(new NunjucksComponent('test/views')); this.use(new NunjucksComponent('test/views'));
this.use(new LogRequestsComponent()); this.use(new LogRequestsComponent());
this.use(new RedirectBackComponent());
// Services // Services
this.use(mysqlComponent); this.use(mysqlComponent);