diff --git a/src/auth/AuthController.ts b/src/auth/AuthController.ts new file mode 100644 index 0000000..e52e979 --- /dev/null +++ b/src/auth/AuthController.ts @@ -0,0 +1,34 @@ +import Controller from "../Controller"; +import {NextFunction, Request, Response} from "express"; +import {REQUIRE_AUTH_MIDDLEWARE, REQUIRE_GUEST_MIDDLEWARE} from "./AuthComponent"; + +export default abstract class AuthController extends Controller { + public getRoutesPrefix(): string { + return '/auth'; + } + + public routes() { + this.get('/', this.getAuth, 'auth', REQUIRE_GUEST_MIDDLEWARE); + this.post('/', this.postAuth, 'auth', REQUIRE_GUEST_MIDDLEWARE); + this.get('/check', this.getCheckAuth, 'check_auth'); + this.post('/logout', this.postLogout, 'logout', REQUIRE_AUTH_MIDDLEWARE); + } + + protected async getAuth(req: Request, res: Response, next: NextFunction): Promise { + const registerEmail = req.flash('register_confirm_email'); + res.render('auth/auth', { + register_confirm_email: registerEmail.length > 0 ? registerEmail[0] : null, + }); + } + + protected abstract async postAuth(req: Request, res: Response, next: NextFunction): Promise; + + protected abstract async getCheckAuth(req: Request, res: Response, next: NextFunction): Promise; + + protected async postLogout(req: Request, res: Response, next: NextFunction): Promise { + await req.authGuard.logout(req.session!); + req.flash('success', 'Successfully logged out.'); + res.redirectBack('/'); + } + +} \ No newline at end of file diff --git a/src/auth/magic_link/MagicLinkAuthController.ts b/src/auth/magic_link/MagicLinkAuthController.ts index a75c38d..3135126 100644 --- a/src/auth/magic_link/MagicLinkAuthController.ts +++ b/src/auth/magic_link/MagicLinkAuthController.ts @@ -1,16 +1,16 @@ -import {Request, Response} from "express"; +import {NextFunction, Request, Response} from "express"; import Controller from "../../Controller"; import MagicLink from "../models/MagicLink"; -import {REQUIRE_AUTH_MIDDLEWARE, REQUIRE_GUEST_MIDDLEWARE} from "../AuthComponent"; import {BadRequestError} from "../../HttpError"; import UserEmail from "../models/UserEmail"; import MagicLinkController from "./MagicLinkController"; import {MailTemplate} from "../../Mail"; import {AuthError, PendingApprovalAuthError} from "../AuthGuard"; import geoip from "geoip-lite"; +import AuthController from "../AuthController"; -export default abstract class MagicLinkAuthController extends Controller { +export default abstract class MagicLinkAuthController extends AuthController { public static async checkAndAuth(req: Request, res: Response, magicLink: MagicLink): Promise { if (magicLink.getSessionID() !== req.sessionID!) throw new BadOwnerMagicLink(); if (!await magicLink.isAuthorized()) throw new UnauthorizedMagicLink(); @@ -49,33 +49,17 @@ export default abstract class MagicLinkAuthController extends Controller { this.magicLinkMailTemplate = magicLinkMailTemplate; } - - public getRoutesPrefix(): string { - return '/auth'; - } - - routes(): void { - this.get('/', this.getAuth, 'auth', REQUIRE_GUEST_MIDDLEWARE); - this.post('/', this.postAuth, 'auth', REQUIRE_GUEST_MIDDLEWARE); - this.get('/check', this.getCheckAuth, 'check_auth'); - this.get('/logout', this.getLogout, 'logout', REQUIRE_AUTH_MIDDLEWARE); - } - - protected async getAuth(request: Request, response: Response): Promise { - const registerEmail = request.flash('register_confirm_email'); - + protected async getAuth(request: Request, response: Response, next: NextFunction): Promise { const link = await MagicLink.bySessionID(request.sessionID!, [this.loginMagicLinkActionType, this.registerMagicLinkActionType]); if (link && await link.isValid()) { response.redirect(Controller.route('magic_link_lobby')); return; } - response.render('auth', { - register_confirm_email: registerEmail.length > 0 ? registerEmail[0] : null, - }); + await super.getAuth(request, response, next); } - protected async postAuth(req: Request, res: Response): Promise { + protected async postAuth(req: Request, res: Response, next: NextFunction): Promise { const email = req.body.email; if (!email) throw new BadRequestError('Email not specified.', 'Please try again.', req.originalUrl); @@ -118,7 +102,7 @@ export default abstract class MagicLinkAuthController extends Controller { /** * Check whether a magic link is authorized, and authenticate if yes */ - protected async getCheckAuth(req: Request, res: Response): Promise { + protected async getCheckAuth(req: Request, res: Response, next: NextFunction): Promise { const magicLink = await MagicLink.bySessionID(req.sessionID!, [this.loginMagicLinkActionType, this.registerMagicLinkActionType]); if (!magicLink) { @@ -149,12 +133,6 @@ export default abstract class MagicLinkAuthController extends Controller { }); return; } - - protected async getLogout(req: Request, res: Response): Promise { - await req.authGuard.logout(req.session!); - req.flash('success', 'Successfully logged out.'); - res.redirectBack('/'); - } } export class BadOwnerMagicLink extends AuthError { diff --git a/views/auth/auth.njk b/views/auth/auth.njk new file mode 100644 index 0000000..3e4e380 --- /dev/null +++ b/views/auth/auth.njk @@ -0,0 +1,42 @@ +{% extends 'layouts/base.njk' %} +{% import 'macros.njk' as macros %} + +{% set title = 'Authentication / Registration' %} +{% set decription = 'Join ' + app.name + ' and share your files!' %} +{% set h1 = 'Authentication and registration' %} + +{% block body %} +
+
+ {% if register_confirm_email %} +
+

Register

+ {{ macros.message('question', 'Do you wish to create a new account with ' + register_confirm_email + '?', false, false) }} + {{ macros.message('warning', 'If you already have an account, please log in with your existing email first and then add your new email in the Account page.', false, true) }} + + + +
+
Email: {{ register_confirm_email }}
+
+ + Go back + + + {{ macros.csrf(getCSRFToken) }} +
+ {% else %} +
+

Log in or register

+ {# {{ macros.message('info', 'If we don\'t find your email address in our database, you will be able to register.', false, true) }}#} +
+ {{ macros.field(_locals, 'email', 'email', query.email or '', 'Your email address', "If we don't find your email address in our database, you will be able to register.", 'required') }} +
+ + + {{ macros.csrf(getCSRFToken) }} +
+ {% endif %} +
+
+{% endblock %}