gadget/gadget-code/src/controllers/auth.ts
2026-04-28 09:20:37 -04:00

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;