diff --git a/Services/server/src/app.ts b/Services/server/src/app.ts index d0d7c7b..6d1030c 100644 --- a/Services/server/src/app.ts +++ b/Services/server/src/app.ts @@ -35,4 +35,4 @@ app.listen(PORT, "0.0.0.0", () => console.log(`[APP] Application is running on http://localhost:${PORT}`), ); -rabbitmq.init(amqHandler).catch((e) => console.error(e)); +// rabbitmq.init(amqHandler).catch((e) => console.error(e)); diff --git a/Services/server/src/controllers/cabinetController.ts b/Services/server/src/controllers/cabinetController.ts index 0f22ebb..463cb43 100644 --- a/Services/server/src/controllers/cabinetController.ts +++ b/Services/server/src/controllers/cabinetController.ts @@ -64,7 +64,7 @@ export class CabinetController extends Controller { @Post("/") @Tags("ตู้เอกสาร") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดกับระบบจัดการไฟล์") @SuccessResponse(HttpStatusCode.CREATED, "สำเร็จ") public async createCabinet( @@ -94,7 +94,7 @@ export class CabinetController extends Controller { */ @Put("/{cabinetName}") @Tags("ตู้เอกสาร") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดไม่สามารถย้ายไฟล์ได้") @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async editCabinet( @@ -163,7 +163,7 @@ export class CabinetController extends Controller { */ @Delete("/{cabinetName}") @Tags("ตู้เอกสาร") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาด ไม่สามารถลบไฟล์ได้") @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async deleteCabinet(@Path() cabinetName: string) { diff --git a/Services/server/src/controllers/drawerController.ts b/Services/server/src/controllers/drawerController.ts index 804e942..9d3a505 100644 --- a/Services/server/src/controllers/drawerController.ts +++ b/Services/server/src/controllers/drawerController.ts @@ -71,7 +71,7 @@ export class DrawerController extends Controller { */ @Post("/") @Tags("ลิ้นชัก") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.NOT_FOUND, "ไม่พบลิ้นชัก") @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดกับระบบจัดการไฟล์") @SuccessResponse(HttpStatusCode.CREATED, "สำเร็จ") @@ -110,7 +110,7 @@ export class DrawerController extends Controller { */ @Put("/{drawerName}") @Tags("ลิ้นชัก") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดไม่สามารถย้ายไฟล์ได้") @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async editDrawer( @@ -181,7 +181,7 @@ export class DrawerController extends Controller { */ @Delete("/{drawerName}") @Tags("ลิ้นชัก") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async deleteDrawer(@Path() cabinetName: string, @Path() drawerName: string) { await new Promise((resolve, reject) => { diff --git a/Services/server/src/controllers/fileController.ts b/Services/server/src/controllers/fileController.ts index 5d7c6d9..e39752b 100644 --- a/Services/server/src/controllers/fileController.ts +++ b/Services/server/src/controllers/fileController.ts @@ -93,7 +93,7 @@ export class FileController extends Controller { */ @Post("/") @Tags("ไฟล์") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response( HttpStatusCode.NOT_FOUND, "ตำแหน่งที่ระบุไม่พบ กรุณาเตรียมตำแหน่งที่ต้องการก่อนดำเนินการ", @@ -180,7 +180,7 @@ export class FileController extends Controller { const metadata: Partial = { pathname, path: basePath, - fileName: replaceIllegalChars( body.file ), + fileName: replaceIllegalChars(body.file), fileSize: 0, fileType: "", title: body.title ?? "", @@ -218,7 +218,7 @@ export class FileController extends Controller { */ @Patch("/{fileName}") @Tags("ไฟล์") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.NOT_FOUND, "ไม่พบตำแหน่งที่ต้องการสร้างแฟ้ม") @Response(HttpStatusCode.NO_CONTENT, "สำเร็จ") @SuccessResponse(HttpStatusCode.OK, "สำเร็จ") @@ -345,7 +345,7 @@ export class FileController extends Controller { */ @Delete("/{fileName}") @Tags("ไฟล์") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @SuccessResponse(HttpStatusCode.OK, "สำเร็จ") public async deleteFile( @Path() cabinetName: string, diff --git a/Services/server/src/controllers/folderController.ts b/Services/server/src/controllers/folderController.ts index 553661d..9a2e663 100644 --- a/Services/server/src/controllers/folderController.ts +++ b/Services/server/src/controllers/folderController.ts @@ -75,7 +75,7 @@ export class FolderController extends Controller { */ @Post("/") @Tags("แฟ้ม") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.NOT_FOUND, "ไม่พบตำแหน่งที่ต้องการสร้างแฟ้ม") @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดกับระบบจัดการไฟล์") @SuccessResponse(HttpStatusCode.CREATED, "สำเร็จ") @@ -116,7 +116,7 @@ export class FolderController extends Controller { */ @Put("/{folderName}") @Tags("แฟ้ม") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดไม่สามารถย้ายไฟล์ได้") @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async editFolder( @@ -189,7 +189,7 @@ export class FolderController extends Controller { */ @Delete("/{folderName}") @Tags("แฟ้ม") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async deleteFolder( @Path() cabinetName: string, diff --git a/Services/server/src/controllers/subFolderController.ts b/Services/server/src/controllers/subFolderController.ts index 08dab6d..9199a30 100644 --- a/Services/server/src/controllers/subFolderController.ts +++ b/Services/server/src/controllers/subFolderController.ts @@ -79,7 +79,7 @@ export class SubFolderController extends Controller { */ @Post("/") @Tags("แฟ้มย่อย") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.NOT_FOUND, "ไม่พบของแฟ้ม") @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดกับระบบจัดการไฟล์") @SuccessResponse(HttpStatusCode.CREATED, "สำเร็จ") @@ -116,7 +116,7 @@ export class SubFolderController extends Controller { */ @Put("/{subFolderName}") @Tags("แฟ้มย่อย") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาดไม่สามารถย้ายไฟล์ได้") @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async editFolder( @@ -193,7 +193,7 @@ export class SubFolderController extends Controller { */ @Delete("/{subFolderName}") @Tags("แฟ้มย่อย") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ") public async deleteFolder( @Path() cabinetName: string, diff --git a/Services/server/src/controllers/subFolderFileController.ts b/Services/server/src/controllers/subFolderFileController.ts index 2bdc672..7729314 100644 --- a/Services/server/src/controllers/subFolderFileController.ts +++ b/Services/server/src/controllers/subFolderFileController.ts @@ -98,7 +98,7 @@ export class SubFolderFileController extends Controller { */ @Post("/") @Tags("ไฟล์") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response( HttpStatusCode.NOT_FOUND, "ตำแหน่งที่ระบุไม่พบ กรุณาเตรียมตำแหน่งที่ต้องการก่อนดำเนินการ", @@ -225,7 +225,7 @@ export class SubFolderFileController extends Controller { */ @Patch("/{fileName}") @Tags("ไฟล์") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @Response(HttpStatusCode.NOT_FOUND, "ไม่พบตำแหน่งที่ต้องการสร้างแฟ้ม") @SuccessResponse(HttpStatusCode.OK, "สำเร็จ") public async updateFile( @@ -352,7 +352,7 @@ export class SubFolderFileController extends Controller { */ @Delete("/{fileName}") @Tags("ไฟล์") - @Security("bearerAuth", ["admin"]) + @Security("bearerAuth", ["admin", "management-role"]) @SuccessResponse(HttpStatusCode.OK, "สำเร็จ") public async deleteFile( @Path() cabinetName: string, diff --git a/Services/server/src/routes.ts b/Services/server/src/routes.ts index 9fa706a..a056828 100644 --- a/Services/server/src/routes.ts +++ b/Services/server/src/routes.ts @@ -101,7 +101,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/cabinet', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(CabinetController)), ...(fetchMiddlewares(CabinetController.prototype.createCabinet)), @@ -128,7 +128,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.put('/cabinet/:cabinetName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(CabinetController)), ...(fetchMiddlewares(CabinetController.prototype.editCabinet)), @@ -155,7 +155,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.delete('/cabinet/:cabinetName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(CabinetController)), ...(fetchMiddlewares(CabinetController.prototype.deleteCabinet)), @@ -207,7 +207,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/cabinet/:cabinetName/drawer', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(DrawerController)), ...(fetchMiddlewares(DrawerController.prototype.createDrawer)), @@ -235,7 +235,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.put('/cabinet/:cabinetName/drawer/:drawerName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(DrawerController)), ...(fetchMiddlewares(DrawerController.prototype.editDrawer)), @@ -263,7 +263,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.delete('/cabinet/:cabinetName/drawer/:drawerName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(DrawerController)), ...(fetchMiddlewares(DrawerController.prototype.deleteDrawer)), @@ -318,7 +318,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/file', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(FileController)), ...(fetchMiddlewares(FileController.prototype.uploadFile)), @@ -348,7 +348,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.patch('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/file/:fileName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(FileController)), ...(fetchMiddlewares(FileController.prototype.updateFile)), @@ -379,7 +379,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.delete('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/file/:fileName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(FileController)), ...(fetchMiddlewares(FileController.prototype.deleteFile)), @@ -464,7 +464,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/cabinet/:cabinetName/drawer/:drawerName/folder', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(FolderController)), ...(fetchMiddlewares(FolderController.prototype.createFolder)), @@ -493,7 +493,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.put('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(FolderController)), ...(fetchMiddlewares(FolderController.prototype.editFolder)), @@ -522,7 +522,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.delete('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(FolderController)), ...(fetchMiddlewares(FolderController.prototype.deleteFolder)), @@ -604,7 +604,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/subfolder', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(SubFolderController)), ...(fetchMiddlewares(SubFolderController.prototype.createFolder)), @@ -634,7 +634,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.put('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/subfolder/:subFolderName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(SubFolderController)), ...(fetchMiddlewares(SubFolderController.prototype.editFolder)), @@ -664,7 +664,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.delete('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/subfolder/:subFolderName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(SubFolderController)), ...(fetchMiddlewares(SubFolderController.prototype.deleteFolder)), @@ -722,7 +722,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/subfolder/:subFolderName/file', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(SubFolderFileController)), ...(fetchMiddlewares(SubFolderFileController.prototype.uploadFile)), @@ -753,7 +753,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.patch('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/subfolder/:subFolderName/file/:fileName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(SubFolderFileController)), ...(fetchMiddlewares(SubFolderFileController.prototype.updateFile)), @@ -785,7 +785,7 @@ export function RegisterRoutes(app: Router) { }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.delete('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/subfolder/:subFolderName/file/:fileName', - authenticateMiddleware([{"bearerAuth":["admin"]}]), + authenticateMiddleware([{"bearerAuth":["admin","management-role"]}]), ...(fetchMiddlewares(SubFolderFileController)), ...(fetchMiddlewares(SubFolderFileController.prototype.deleteFile)), diff --git a/Services/server/src/swagger.json b/Services/server/src/swagger.json index da8bf1b..37ab26f 100644 --- a/Services/server/src/swagger.json +++ b/Services/server/src/swagger.json @@ -261,7 +261,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -304,7 +305,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -355,7 +357,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -450,7 +453,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -503,7 +507,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -560,7 +565,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -783,7 +789,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -906,7 +913,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1007,7 +1015,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1286,7 +1295,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1348,7 +1358,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1414,7 +1425,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1584,7 +1596,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1654,7 +1667,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1729,7 +1743,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -1979,7 +1994,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -2108,7 +2124,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], @@ -2218,7 +2235,8 @@ "security": [ { "bearerAuth": [ - "admin" + "admin", + "management-role" ] } ], diff --git a/Services/server/src/utils/auth.ts b/Services/server/src/utils/auth.ts index 2b601fa..574db66 100644 --- a/Services/server/src/utils/auth.ts +++ b/Services/server/src/utils/auth.ts @@ -1,12 +1,19 @@ import * as express from "express"; -import { createVerifier } from "fast-jwt"; +import { createDecoder, createVerifier } from "fast-jwt"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; +import { JwtPayload } from "jsonwebtoken"; -if (!process.env.PUBLIC_KEY && !process.env.REALM_URL) { +if (!(process.env.PUBLIC_KEY && process.env.REALM_URL)) { throw new Error("Require public key or realm url."); } +if (process.env.PUBLIC_KEY && process.env.REALM_URL && !process.env.PREFERRED_AUTH) { + throw new Error("Preferred auth type must be specified if public key and realm url is provided."); +} +if (!process.env.MANAGEMENT_ROLE) { + throw new Error("Management role env is required."); +} const jwtVerify = createVerifier({ key: async () => { @@ -14,6 +21,8 @@ const jwtVerify = createVerifier({ }, }); +const jwtDecode = createDecoder(); + export async function expressAuthentication( request: express.Request, securityName: string, @@ -29,19 +38,47 @@ export async function expressAuthentication( if (!token) throw new HttpError(HttpStatusCode.UNAUTHORIZED, "No token provided."); - const payload = await jwtVerify(token).catch((_) => null); + let payload: JwtPayload = {}; - if (!payload) { - throw new HttpError(HttpStatusCode.UNAUTHORIZED, "Invalid token provided."); + switch (process.env.PREFERRED_AUTH) { + case "online": + payload = await verifyOnline(token); + break; + case "offline": + payload = await verifyOffline(token); + break; + default: + if (process.env.REALM_URL) payload = await verifyOnline(token); + if (process.env.PUBLIC_KEY) payload = await verifyOffline(token); + break; } if ( scopes && scopes.length > 0 && - scopes.some((v) => !payload.resource_access[payload.azp].roles.includes(v)) + scopes + .map((v) => (v === "management-role" ? process.env.MANAGEMENT_ROLE : v)) + .every((v) => !payload.resource_access[payload.azp].roles.includes(v)) ) { throw new HttpError(HttpStatusCode.FORBIDDEN, "You are not allowed to perform this action."); } return payload; } + +async function verifyOffline(token: string) { + const payload = await jwtVerify(token).catch((_) => null); + if (!payload) throw new HttpError(HttpStatusCode.UNAUTHORIZED, "Invalid token provided."); + return payload; +} + +async function verifyOnline(token: string) { + const res = await fetch(`${process.env.REALM_URL}/protocol/openid-connect/userinfo`, { + headers: { authorization: `Bearer ${token}` }, + }).catch((e) => console.error(e)); + + if (!res) throw new Error("Cannot connect to auth service."); + if (!res.ok) throw new HttpError(HttpStatusCode.UNAUTHORIZED, "Invalid token provided."); + + return await jwtDecode(token); +}