103 lines
4.5 KiB
TypeScript
103 lines
4.5 KiB
TypeScript
import Controller from "wms-core/Controller";
|
|
import {REQUIRE_AUTH_MIDDLEWARE, REQUIRE_GUEST_MIDDLEWARE} from "wms-core/auth/AuthComponent";
|
|
import {Request, Response} from "express";
|
|
import Validator from "wms-core/db/Validator";
|
|
import {EMAIL_REGEX} from "wms-core/db/Model";
|
|
import {PasswordAuthProof} from "../models/UserPassword";
|
|
import UserEmail from "wms-core/auth/models/UserEmail";
|
|
import Username, {USERNAME_REGEXP} from "../models/Username";
|
|
|
|
export default class AuthController extends Controller {
|
|
routes(): void {
|
|
this.get('/login', this.getLogin, 'login', REQUIRE_GUEST_MIDDLEWARE);
|
|
this.post('/login', this.postLogin, 'login', REQUIRE_GUEST_MIDDLEWARE);
|
|
this.get('/register', this.getRegister, 'register', REQUIRE_GUEST_MIDDLEWARE);
|
|
this.post('/register', this.postRegister, 'register', REQUIRE_GUEST_MIDDLEWARE);
|
|
this.get('/logout', this.getLogout, 'logout', REQUIRE_AUTH_MIDDLEWARE);
|
|
}
|
|
|
|
private async getLogin(req: Request, res: Response): Promise<void> {
|
|
res.render('login');
|
|
}
|
|
|
|
private async postLogin(req: Request, res: Response): Promise<void> {
|
|
await this.validate({
|
|
email: new Validator().defined().regexp(EMAIL_REGEX),
|
|
password: new Validator().acceptUndefined(),
|
|
}, req.body);
|
|
|
|
const passwordAuthProof = new PasswordAuthProof(req.body.email);
|
|
const user = await passwordAuthProof.getUser();
|
|
if (!user) {
|
|
req.flash('error', 'Unknown email address');
|
|
res.redirect(Controller.route('login'));
|
|
return;
|
|
}
|
|
|
|
await passwordAuthProof.authorize(req.body.password, req.session);
|
|
await req.authGuard.authenticateOrRegister(req.session!, passwordAuthProof);
|
|
|
|
req.flash('success', `Welcome, ${user.name}.`);
|
|
res.redirect(Controller.route('home'));
|
|
}
|
|
|
|
private async getRegister(req: Request, res: Response): Promise<void> {
|
|
res.render('register');
|
|
}
|
|
|
|
private async postRegister(req: Request, res: Response): Promise<void> {
|
|
const validationMap: any = {
|
|
username: new Validator().defined().between(3, 64).regexp(USERNAME_REGEXP).unique(Username),
|
|
password: new Validator().defined().minLength(8),
|
|
password_confirmation: new Validator().defined().sameAs('password', req.body.password),
|
|
terms: new Validator().defined(),
|
|
};
|
|
|
|
let email: string;
|
|
if (req.body.create_email) {
|
|
validationMap['domain'] = new Validator().defined().regexp(/^(toot\.party)$/);
|
|
validationMap['recovery_email'] = new Validator().acceptUndefined(true).regexp(EMAIL_REGEX).unique(UserEmail, 'email');
|
|
email = req.body.email = req.body.username + '@' + req.body.domain;
|
|
validationMap['email'] = new Validator().defined().regexp(EMAIL_REGEX).unique(UserEmail, 'email');
|
|
} else {
|
|
validationMap['recovery_email'] = new Validator().defined().regexp(EMAIL_REGEX).unique(UserEmail, 'email');
|
|
email = req.body.recovery_email;
|
|
}
|
|
await this.validate(validationMap, req.body);
|
|
|
|
const passwordAuthProof = new PasswordAuthProof(email, false);
|
|
const userPassword = await passwordAuthProof.register(req.body.password);
|
|
await passwordAuthProof.authorize(req.body.password_confirmation, req.session);
|
|
await req.authGuard.authenticateOrRegister(req.session!, passwordAuthProof, async (connection, userID) => {
|
|
const callbacks: (() => Promise<void>)[] = [];
|
|
|
|
// Password
|
|
await userPassword.setUser(userID);
|
|
await userPassword.save(connection, c => callbacks.push(c));
|
|
|
|
// Username
|
|
await new Username({user_id: userID, username: req.body.username}).save(connection, c => callbacks.push(c));
|
|
|
|
// Email
|
|
if (req.body.create_email && req.body.recovery_email) {
|
|
await new UserEmail({
|
|
user_id: userID,
|
|
email: req.body.recovery_email,
|
|
main: false,
|
|
}).save(connection, c => callbacks.push(c));
|
|
}
|
|
|
|
return callbacks;
|
|
});
|
|
|
|
const user = (await passwordAuthProof.getUser())!;
|
|
|
|
req.flash('success', `Your account was successfully created! Welcome, ${user.name}.`);
|
|
res.redirect(Controller.route('home'));
|
|
}
|
|
|
|
private async getLogout(req: Request, res: Response): Promise<void> {
|
|
await req.authGuard.logout(req.session!);
|
|
res.redirect(Controller.route('home'));
|
|
}
|
|
} |