182 lines
4.6 KiB
TypeScript
182 lines
4.6 KiB
TypeScript
// src/controllers/auth.ts
|
|
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
|
|
// All Rights Reserved
|
|
|
|
// import env from "../config/env.js";
|
|
import { NextFunction, Request, Response } from "express";
|
|
|
|
import { DtpController } from "../lib/controller.js";
|
|
|
|
import UserService from "../services/user.js";
|
|
import SessionService, { SessionType } from "../services/session.js";
|
|
|
|
export class AuthController extends DtpController {
|
|
get name(): string {
|
|
return "AuthController";
|
|
}
|
|
get slug(): string {
|
|
return "auth";
|
|
}
|
|
get route(): string {
|
|
return "/auth";
|
|
}
|
|
|
|
constructor() {
|
|
super();
|
|
}
|
|
|
|
async start(): Promise<void> {
|
|
this.router.post("/sign-up", this.postSignUp.bind(this));
|
|
this.router.post("/sign-in", this.postSignIn.bind(this));
|
|
this.router.post("/renew-token", this.postRenewToken.bind(this));
|
|
|
|
this.router.get("/welcome", this.getWelcomeView.bind(this));
|
|
this.router.get("/sign-up", this.getSignUpForm.bind(this));
|
|
this.router.get("/sign-in", this.getSignInForm.bind(this));
|
|
this.router.get("/sign-out", this.getSignOut.bind(this));
|
|
}
|
|
|
|
async postSignUp(
|
|
req: Request,
|
|
res: Response,
|
|
next: NextFunction
|
|
): Promise<void> {
|
|
try {
|
|
const user = await UserService.create(
|
|
req.body.email,
|
|
req.body.password,
|
|
req.body.displayName
|
|
);
|
|
|
|
req.session.user = {
|
|
_id: user._id,
|
|
email: user.email,
|
|
displayName: user.displayName,
|
|
flags: user.flags,
|
|
};
|
|
|
|
const token = await SessionService.createJsonWebToken(user);
|
|
req.session.token = token;
|
|
req.session.type = SessionType.WEB;
|
|
|
|
req.session.save((err: Error) => {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
res.status(201).json({
|
|
success: true,
|
|
user: {
|
|
_id: user._id.toString(),
|
|
email: user.email,
|
|
displayName: user.displayName,
|
|
flags: user.flags,
|
|
},
|
|
token,
|
|
});
|
|
});
|
|
} catch (error) {
|
|
this.log.error("failed to process new user sign-up", { error });
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async postSignIn(
|
|
req: Request,
|
|
res: Response,
|
|
next: NextFunction
|
|
): Promise<void> {
|
|
try {
|
|
const user = await UserService.authenticate(
|
|
req.body.email,
|
|
req.body.password
|
|
);
|
|
req.session.user = {
|
|
_id: user._id,
|
|
email: user.email,
|
|
displayName: user.displayName,
|
|
flags: user.flags,
|
|
};
|
|
|
|
const token = await SessionService.createJsonWebToken(user);
|
|
req.session.token = token;
|
|
req.session.type = SessionType.WEB;
|
|
|
|
req.session.save((err: Error) => {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
res.status(200).json({
|
|
success: true,
|
|
user: {
|
|
_id: user._id.toString(),
|
|
email: user.email,
|
|
displayName: user.displayName,
|
|
flags: user.flags,
|
|
},
|
|
token,
|
|
});
|
|
});
|
|
} catch (error) {
|
|
return next(error);
|
|
}
|
|
}
|
|
|
|
async postRenewToken(req: Request, res: Response): Promise<void> {
|
|
try {
|
|
const user = await SessionService.verifyJsonWebToken(req.body.token);
|
|
const token = await SessionService.createJsonWebToken(user);
|
|
req.session.token = token;
|
|
res.status(200).json({ success: true, token });
|
|
} catch (error) {
|
|
this.log.error("failed to process token renewal", { error });
|
|
res.status((error as Error).statusCode || 500).json({
|
|
success: false,
|
|
message: (error as Error).message,
|
|
});
|
|
}
|
|
}
|
|
|
|
async getWelcomeView(_req: Request, res: Response): Promise<void> {
|
|
res.status(200).json({
|
|
success: true,
|
|
message: "Welcome to DTP Web Application",
|
|
});
|
|
}
|
|
|
|
async getSignUpForm(_req: Request, res: Response): Promise<void> {
|
|
res.status(200).json({
|
|
success: true,
|
|
form: "sign-up",
|
|
});
|
|
}
|
|
async getSignInForm(_req: Request, res: Response): Promise<void> {
|
|
res.status(200).json({
|
|
success: true,
|
|
form: "sign-in",
|
|
});
|
|
}
|
|
|
|
async getSignOut(
|
|
req: Request,
|
|
res: Response,
|
|
next: NextFunction
|
|
): Promise<void> {
|
|
if (req.session.token) {
|
|
try {
|
|
await SessionService.revokeJsonWebToken(req.session.token);
|
|
} catch (error) {
|
|
this.log.error("failed to revoke JSON Web Token", { error });
|
|
}
|
|
}
|
|
req.session.destroy((err: Error) => {
|
|
if (err) {
|
|
this.log.error("failed to destroy user session", { error: err });
|
|
return next(err);
|
|
}
|
|
res.status(200).json({ success: true, message: "Signed out successfully" });
|
|
});
|
|
}
|
|
}
|
|
|
|
export default AuthController;
|