mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-10-31 02:27:11 -04:00 
			
		
		
		
	Check for permissions on each routes
This commit is contained in:
		
							parent
							
								
									8110f7de66
								
							
						
					
					
						commit
						49f700ca6e
					
				| @ -1,6 +1,6 @@ | ||||
| import Elysia, { getSchemaValidator, t } from "elysia"; | ||||
| import { TypeCompiler } from "@sinclair/typebox/compiler"; | ||||
| import Elysia, { t } from "elysia"; | ||||
| import { createRemoteJWKSet, jwtVerify } from "jose"; | ||||
| import { KError } from "./models/error"; | ||||
| 
 | ||||
| const jwtSecret = process.env.JWT_SECRET | ||||
| 	? new TextEncoder().encode(process.env.JWT_SECRET) | ||||
| @ -16,33 +16,40 @@ const Jwt = t.Object({ | ||||
| 	sub: t.String({ description: "User id" }), | ||||
| 	username: t.String(), | ||||
| 	sid: t.String({ description: "Session id" }), | ||||
| 	permissions: t.Array(t.String()), | ||||
| }); | ||||
| const validator = getSchemaValidator(Jwt); | ||||
| const validator = TypeCompiler.Compile(Jwt); | ||||
| 
 | ||||
| export const auth = new Elysia({ name: "auth" }) | ||||
| 	.guard({ | ||||
| 		// Those are not applied for now. See https://github.com/elysiajs/elysia/issues/1139
 | ||||
| 		detail: { | ||||
| 			security: [{ bearer: ["read"] }, { api: ["read"] }], | ||||
| 		}, | ||||
| 		response: { | ||||
| 			401: { ...KError, description: "" }, | ||||
| 			403: { ...KError, description: "" }, | ||||
| 		}, | ||||
| 	}) | ||||
| 	.macro({ | ||||
| 		permissions(perms: string[]) { | ||||
| 			return { | ||||
| 				resolve: async ({ headers: { authorization }, error }) => { | ||||
| 					console.log(process.env.JWT_ISSUER); | ||||
| 					const bearer = authorization?.slice(7); | ||||
| 					if (!bearer) return { jwt: false }; | ||||
| 					if (!bearer) { | ||||
| 						return error(500, { | ||||
| 							status: 500, | ||||
| 							message: "No jwt, auth server configuration error.", | ||||
| 						}); | ||||
| 					} | ||||
| 
 | ||||
| 					// @ts-expect-error ts can't understand that there's two overload idk why
 | ||||
| 					const { payload } = await jwtVerify(bearer, jwtSecret ?? jwks, { | ||||
| 						issuer: process.env.JWT_ISSUER, | ||||
| 					}); | ||||
| 					// TODO: use perms
 | ||||
| 					return { jwt: validator.Decode<typeof Jwt>(payload) }; | ||||
| 					const jwt = validator.Decode(payload); | ||||
| 
 | ||||
| 					for (const perm of perms) { | ||||
| 						if (!jwt.permissions.includes(perm)) { | ||||
| 							return error(403, { | ||||
| 								status: 403, | ||||
| 								message: `Missing permission: '${perm}'.`, | ||||
| 								details: { current: jwt.permissions, required: perms }, | ||||
| 							}); | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					return { jwt }; | ||||
| 				}, | ||||
| 			}; | ||||
| 		}, | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import { Elysia, t } from "elysia"; | ||||
| import { auth } from "./auth"; | ||||
| import { entriesH } from "./controllers/entries"; | ||||
| import { imagesH } from "./controllers/images"; | ||||
| import { seasonsH } from "./controllers/seasons"; | ||||
| @ -10,7 +11,7 @@ import { showsH } from "./controllers/shows/shows"; | ||||
| import { staffH } from "./controllers/staff"; | ||||
| import { studiosH } from "./controllers/studios"; | ||||
| import { videosH } from "./controllers/videos"; | ||||
| import type { KError } from "./models/error"; | ||||
| import { KError } from "./models/error"; | ||||
| 
 | ||||
| export const base = new Elysia({ name: "base" }) | ||||
| 	.onError(({ code, error }) => { | ||||
| @ -53,6 +54,21 @@ export const base = new Elysia({ name: "base" }) | ||||
| export const prefix = process.env.KYOO_PREFIX ?? ""; | ||||
| export const app = new Elysia({ prefix }) | ||||
| 	.use(base) | ||||
| 	.use(auth) | ||||
| 	.guard( | ||||
| 		{ | ||||
| 			// Those are not applied for now. See https://github.com/elysiajs/elysia/issues/1139
 | ||||
| 			detail: { | ||||
| 				security: [{ bearer: ["core.read"] }, { api: ["core.read"] }], | ||||
| 			}, | ||||
| 			response: { | ||||
| 				401: { ...KError, description: "" }, | ||||
| 				403: { ...KError, description: "" }, | ||||
| 			}, | ||||
| 			perms: ["core.read"], | ||||
| 		}, | ||||
| 		(app) => | ||||
| 			app | ||||
| 				.use(showsH) | ||||
| 				.use(movies) | ||||
| 				.use(series) | ||||
| @ -61,6 +77,18 @@ export const app = new Elysia({ prefix }) | ||||
| 				.use(seasonsH) | ||||
| 				.use(studiosH) | ||||
| 				.use(staffH) | ||||
| 	.use(videosH) | ||||
| 	.use(imagesH) | ||||
| 	.use(seed); | ||||
| 				.use(imagesH), | ||||
| 	) | ||||
| 	.guard( | ||||
| 		{ | ||||
| 			detail: { | ||||
| 				security: [{ bearer: ["core.write"] }, { api: ["core.write"] }], | ||||
| 			}, | ||||
| 			response: { | ||||
| 				401: { ...KError, description: "" }, | ||||
| 				403: { ...KError, description: "" }, | ||||
| 			}, | ||||
| 			perms: ["core.read"], | ||||
| 		}, | ||||
| 		(app) => app.use(videosH).use(seed), | ||||
| 	); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user