Promote auth view to core
This commit is contained in:
parent
a0c385bbbe
commit
d6266e4396
34
src/auth/AuthController.ts
Normal file
34
src/auth/AuthController.ts
Normal file
@ -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<void> {
|
||||||
|
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<void>;
|
||||||
|
|
||||||
|
protected abstract async getCheckAuth(req: Request, res: Response, next: NextFunction): Promise<void>;
|
||||||
|
|
||||||
|
protected async postLogout(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||||
|
await req.authGuard.logout(req.session!);
|
||||||
|
req.flash('success', 'Successfully logged out.');
|
||||||
|
res.redirectBack('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,16 +1,16 @@
|
|||||||
import {Request, Response} from "express";
|
import {NextFunction, Request, Response} from "express";
|
||||||
import Controller from "../../Controller";
|
import Controller from "../../Controller";
|
||||||
import MagicLink from "../models/MagicLink";
|
import MagicLink from "../models/MagicLink";
|
||||||
import {REQUIRE_AUTH_MIDDLEWARE, REQUIRE_GUEST_MIDDLEWARE} from "../AuthComponent";
|
|
||||||
import {BadRequestError} from "../../HttpError";
|
import {BadRequestError} from "../../HttpError";
|
||||||
import UserEmail from "../models/UserEmail";
|
import UserEmail from "../models/UserEmail";
|
||||||
import MagicLinkController from "./MagicLinkController";
|
import MagicLinkController from "./MagicLinkController";
|
||||||
import {MailTemplate} from "../../Mail";
|
import {MailTemplate} from "../../Mail";
|
||||||
import {AuthError, PendingApprovalAuthError} from "../AuthGuard";
|
import {AuthError, PendingApprovalAuthError} from "../AuthGuard";
|
||||||
import geoip from "geoip-lite";
|
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<void> {
|
public static async checkAndAuth(req: Request, res: Response, magicLink: MagicLink): Promise<void> {
|
||||||
if (magicLink.getSessionID() !== req.sessionID!) throw new BadOwnerMagicLink();
|
if (magicLink.getSessionID() !== req.sessionID!) throw new BadOwnerMagicLink();
|
||||||
if (!await magicLink.isAuthorized()) throw new UnauthorizedMagicLink();
|
if (!await magicLink.isAuthorized()) throw new UnauthorizedMagicLink();
|
||||||
@ -49,33 +49,17 @@ export default abstract class MagicLinkAuthController extends Controller {
|
|||||||
this.magicLinkMailTemplate = magicLinkMailTemplate;
|
this.magicLinkMailTemplate = magicLinkMailTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async getAuth(request: Request, response: Response, next: NextFunction): Promise<void> {
|
||||||
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<void> {
|
|
||||||
const registerEmail = request.flash('register_confirm_email');
|
|
||||||
|
|
||||||
const link = await MagicLink.bySessionID(request.sessionID!, [this.loginMagicLinkActionType, this.registerMagicLinkActionType]);
|
const link = await MagicLink.bySessionID(request.sessionID!, [this.loginMagicLinkActionType, this.registerMagicLinkActionType]);
|
||||||
if (link && await link.isValid()) {
|
if (link && await link.isValid()) {
|
||||||
response.redirect(Controller.route('magic_link_lobby'));
|
response.redirect(Controller.route('magic_link_lobby'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.render('auth', {
|
await super.getAuth(request, response, next);
|
||||||
register_confirm_email: registerEmail.length > 0 ? registerEmail[0] : null,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async postAuth(req: Request, res: Response): Promise<void> {
|
protected async postAuth(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||||
const email = req.body.email;
|
const email = req.body.email;
|
||||||
if (!email) throw new BadRequestError('Email not specified.', 'Please try again.', req.originalUrl);
|
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
|
* Check whether a magic link is authorized, and authenticate if yes
|
||||||
*/
|
*/
|
||||||
protected async getCheckAuth(req: Request, res: Response): Promise<void> {
|
protected async getCheckAuth(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||||
const magicLink = await MagicLink.bySessionID(req.sessionID!, [this.loginMagicLinkActionType, this.registerMagicLinkActionType]);
|
const magicLink = await MagicLink.bySessionID(req.sessionID!, [this.loginMagicLinkActionType, this.registerMagicLinkActionType]);
|
||||||
|
|
||||||
if (!magicLink) {
|
if (!magicLink) {
|
||||||
@ -149,12 +133,6 @@ export default abstract class MagicLinkAuthController extends Controller {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getLogout(req: Request, res: Response): Promise<void> {
|
|
||||||
await req.authGuard.logout(req.session!);
|
|
||||||
req.flash('success', 'Successfully logged out.');
|
|
||||||
res.redirectBack('/');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BadOwnerMagicLink extends AuthError {
|
export class BadOwnerMagicLink extends AuthError {
|
||||||
|
42
views/auth/auth.njk
Normal file
42
views/auth/auth.njk
Normal file
@ -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 %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="panel">
|
||||||
|
{% if register_confirm_email %}
|
||||||
|
<form action="/auth" method="POST" id="register-form">
|
||||||
|
<h2>Register</h2>
|
||||||
|
{{ 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) }}
|
||||||
|
<input type="hidden" name="email" value="{{ register_confirm_email }}">
|
||||||
|
<input type="hidden" name="confirm_register" value="confirm">
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<div class="form-display">Email: {{ register_confirm_email }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="/auth" class="button transparent">Go back</a>
|
||||||
|
<button type="submit" class="primary">Register</button>
|
||||||
|
|
||||||
|
{{ macros.csrf(getCSRFToken) }}
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<form action="/auth" method="POST" id="login-form">
|
||||||
|
<h2>Log in or register</h2>
|
||||||
|
{# {{ macros.message('info', 'If we don\'t find your email address in our database, you will be able to register.', false, true) }}#}
|
||||||
|
<div class="input-field">
|
||||||
|
{{ 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') }}
|
||||||
|
</div>
|
||||||
|
<button type="submit">Authenticate</button>
|
||||||
|
|
||||||
|
{{ macros.csrf(getCSRFToken) }}
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user