2024-08-22 09:40:31 +00:00
|
|
|
import { Request, Response } from "express";
|
|
|
|
import { JWTHelper } from "../helpers/jwtHelper";
|
2024-08-26 11:47:08 +00:00
|
|
|
import { JWTToken } from "../type/jwtTypes";
|
2024-08-22 09:40:31 +00:00
|
|
|
import InternalException from "../exceptions/internalException";
|
|
|
|
import RefreshCommandHandler from "../command/refreshCommandHandler";
|
2024-08-25 08:09:57 +00:00
|
|
|
import { CreateRefreshCommand, DeleteRefreshCommand } from "../command/refreshCommand";
|
2024-08-22 09:40:31 +00:00
|
|
|
import UserService from "../service/userService";
|
|
|
|
import speakeasy from "speakeasy";
|
|
|
|
import UnauthorizedRequestException from "../exceptions/unauthorizedRequestException";
|
2024-08-23 12:42:47 +00:00
|
|
|
import RefreshService from "../service/refreshService";
|
2024-08-27 15:54:59 +00:00
|
|
|
import UserPermissionService from "../service/userPermissionService";
|
2024-08-26 11:47:08 +00:00
|
|
|
import PermissionHelper from "../helpers/permissionHelper";
|
2024-08-27 15:54:59 +00:00
|
|
|
import RolePermissionService from "../service/rolePermissionService";
|
2024-08-22 09:40:31 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @description Check authentication status by token
|
|
|
|
* @param req {Request} Express req object
|
|
|
|
* @param res {Response} Express res object
|
|
|
|
* @returns {Promise<*>}
|
|
|
|
*/
|
|
|
|
export async function login(req: Request, res: Response): Promise<any> {
|
|
|
|
let username = req.body.username;
|
|
|
|
let totp = req.body.totp;
|
|
|
|
|
2024-10-07 16:09:27 +00:00
|
|
|
let { id, secret, mail, firstname, lastname, isOwner } = await UserService.getByUsername(username);
|
2024-08-22 09:40:31 +00:00
|
|
|
|
|
|
|
let valid = speakeasy.totp.verify({
|
|
|
|
secret: secret,
|
|
|
|
encoding: "base32",
|
|
|
|
token: totp,
|
|
|
|
window: 2,
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!valid) {
|
|
|
|
throw new UnauthorizedRequestException("Token not valid or expired");
|
|
|
|
}
|
|
|
|
|
2024-08-27 15:54:59 +00:00
|
|
|
let userPermissions = await UserPermissionService.getByUser(id);
|
|
|
|
let userPermissionStrings = userPermissions.map((e) => e.permission);
|
|
|
|
let userRoles = await UserService.getAssignedRolesByUserId(id);
|
2024-09-01 12:55:05 +00:00
|
|
|
let rolePermissions = userRoles.length != 0 ? await RolePermissionService.getByRoles(userRoles.map((e) => e.id)) : [];
|
2024-08-27 15:54:59 +00:00
|
|
|
let rolePermissionStrings = rolePermissions.map((e) => e.permission);
|
|
|
|
let permissionObject = PermissionHelper.convertToObject([...userPermissionStrings, ...rolePermissionStrings]);
|
2024-08-26 11:47:08 +00:00
|
|
|
|
2024-08-22 09:40:31 +00:00
|
|
|
let jwtData: JWTToken = {
|
|
|
|
userId: id,
|
2024-08-26 11:47:08 +00:00
|
|
|
mail: mail,
|
2024-08-22 09:40:31 +00:00
|
|
|
username: username,
|
2024-08-26 11:47:08 +00:00
|
|
|
firstname: firstname,
|
|
|
|
lastname: lastname,
|
2024-10-07 16:09:27 +00:00
|
|
|
isOwner: isOwner,
|
2024-08-26 11:47:08 +00:00
|
|
|
permissions: permissionObject,
|
2024-08-22 09:40:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let accessToken: string;
|
|
|
|
let refreshToken: string;
|
|
|
|
|
|
|
|
JWTHelper.create(jwtData)
|
|
|
|
.then((result) => {
|
|
|
|
accessToken = result;
|
|
|
|
})
|
|
|
|
.catch((err) => {
|
|
|
|
console.log(err);
|
2024-09-06 08:08:19 +00:00
|
|
|
throw new InternalException("Failed accessToken creation", err);
|
2024-08-22 09:40:31 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
let refreshCommand: CreateRefreshCommand = {
|
|
|
|
userId: id,
|
|
|
|
};
|
|
|
|
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
accessToken,
|
|
|
|
refreshToken,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @description logout user by token (invalidate refresh token)
|
|
|
|
* @param req {Request} Express req object
|
|
|
|
* @param res {Response} Express res object
|
|
|
|
* @returns {Promise<*>}
|
|
|
|
*/
|
|
|
|
export async function logout(req: Request, res: Response): Promise<any> {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @description refresh expired token
|
|
|
|
* @param req {Request} Express req object
|
|
|
|
* @param res {Response} Express res object
|
|
|
|
* @returns {Promise<*>}
|
|
|
|
*/
|
|
|
|
export async function refresh(req: Request, res: Response): Promise<any> {
|
2024-08-25 08:09:57 +00:00
|
|
|
let token = req.body.accessToken;
|
|
|
|
let refresh = req.body.refreshToken;
|
2024-08-23 12:42:47 +00:00
|
|
|
|
|
|
|
const tokenUser = await JWTHelper.decode(token);
|
|
|
|
if (typeof tokenUser == "string" || !tokenUser) {
|
|
|
|
throw new InternalException("process failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
let tokenUserId = (tokenUser as JWTToken).userId;
|
|
|
|
|
|
|
|
let { user } = await RefreshService.getByToken(refresh);
|
|
|
|
|
|
|
|
if (tokenUserId != user.id) {
|
|
|
|
throw new UnauthorizedRequestException("user not identified with token and refresh");
|
|
|
|
}
|
|
|
|
|
2024-10-07 16:09:27 +00:00
|
|
|
let { id, username, mail, firstname, lastname, isOwner } = await UserService.getById(tokenUserId);
|
2024-08-26 11:47:08 +00:00
|
|
|
|
2024-08-27 15:54:59 +00:00
|
|
|
let permissions = await UserPermissionService.getByUser(id);
|
2024-08-26 11:47:08 +00:00
|
|
|
let permissionStrings = permissions.map((e) => e.permission);
|
|
|
|
let permissionObject = PermissionHelper.convertToObject(permissionStrings);
|
2024-08-23 12:42:47 +00:00
|
|
|
|
|
|
|
let jwtData: JWTToken = {
|
|
|
|
userId: id,
|
2024-08-26 11:47:08 +00:00
|
|
|
mail: mail,
|
2024-08-23 12:42:47 +00:00
|
|
|
username: username,
|
2024-08-26 11:47:08 +00:00
|
|
|
firstname: firstname,
|
|
|
|
lastname: lastname,
|
2024-10-07 16:09:27 +00:00
|
|
|
isOwner: isOwner,
|
2024-08-26 11:47:08 +00:00
|
|
|
permissions: permissionObject,
|
2024-08-23 12:42:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let accessToken: string;
|
|
|
|
let refreshToken: string;
|
|
|
|
|
|
|
|
JWTHelper.create(jwtData)
|
|
|
|
.then((result) => {
|
|
|
|
accessToken = result;
|
|
|
|
})
|
|
|
|
.catch((err) => {
|
2024-09-06 08:08:19 +00:00
|
|
|
throw new InternalException("Failed accessToken creation", err);
|
2024-08-23 12:42:47 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
let refreshCommand: CreateRefreshCommand = {
|
|
|
|
userId: id,
|
|
|
|
};
|
|
|
|
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
|
|
|
|
2024-08-25 08:09:57 +00:00
|
|
|
let removeToken: DeleteRefreshCommand = {
|
|
|
|
userId: id,
|
|
|
|
token: refresh,
|
|
|
|
};
|
|
|
|
await RefreshCommandHandler.deleteByToken(removeToken);
|
2024-08-23 12:42:47 +00:00
|
|
|
|
|
|
|
res.json({
|
|
|
|
accessToken,
|
|
|
|
refreshToken,
|
|
|
|
});
|
2024-08-22 09:40:31 +00:00
|
|
|
}
|