diff --git a/src/auth/magic_link/MagicLinkAuthController.ts b/src/auth/magic_link/MagicLinkAuthController.ts index 9d01242..209ef30 100644 --- a/src/auth/magic_link/MagicLinkAuthController.ts +++ b/src/auth/magic_link/MagicLinkAuthController.ts @@ -9,6 +9,7 @@ import {AuthError, PendingApprovalAuthError, RegisterCallback} from "../AuthGuar import geoip from "geoip-lite"; import AuthController from "../AuthController"; import NunjucksComponent from "../../components/NunjucksComponent"; +import RedirectBackComponent from "../../components/RedirectBackComponent"; 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, { - redirect_uri: req.query.redirect_uri?.toString() || NunjucksComponent.getPreviousURL(req), + redirect_uri: req.query.redirect_uri?.toString() || RedirectBackComponent.getPreviousURL(req), })); } else { // Confirm registration req diff --git a/src/components/NunjucksComponent.ts b/src/components/NunjucksComponent.ts index c21ef4c..b274ee7 100644 --- a/src/components/NunjucksComponent.ts +++ b/src/components/NunjucksComponent.ts @@ -1,6 +1,6 @@ import nunjucks, {Environment} from "nunjucks"; import config from "config"; -import {Express, Request, Router} from "express"; +import {Express, Router} from "express"; import ApplicationComponent from "../ApplicationComponent"; import Controller from "../Controller"; import {ServerError} from "../HttpError"; @@ -9,13 +9,6 @@ import {ParsedUrlQueryInput} from "querystring"; import * as util from "util"; export default class NunjucksComponent extends ApplicationComponent { - 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 env?: Environment; @@ -72,14 +65,6 @@ export default class NunjucksComponent extends ApplicationComponent { 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(); }); } diff --git a/src/components/RedirectBackComponent.ts b/src/components/RedirectBackComponent.ts new file mode 100644 index 0000000..a10fdbe --- /dev/null +++ b/src/components/RedirectBackComponent.ts @@ -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 { + public static getPreviousURL(req: Request, defaultUrl?: string): string | undefined { + return req.session?.previousUrl || defaultUrl; + } + + public async handle(router: Router): Promise { + 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(); + }); + } +} \ No newline at end of file diff --git a/test/_app.ts b/test/_app.ts index 254352b..95c023c 100644 --- a/test/_app.ts +++ b/test/_app.ts @@ -14,6 +14,7 @@ import AuthComponent from "../src/auth/AuthComponent"; import AuthGuard from "../src/auth/AuthGuard"; import MagicLink from "../src/auth/models/MagicLink"; import FormHelperComponent from "../src/components/FormHelperComponent"; +import RedirectBackComponent from "../src/components/RedirectBackComponent"; export default function useApp(appSupplier?: (port: number) => TestApp) { let app: Application; @@ -61,6 +62,7 @@ export class TestApp extends Application { // Base this.use(new NunjucksComponent('test/views')); this.use(new LogRequestsComponent()); + this.use(new RedirectBackComponent()); // Services this.use(mysqlComponent);