diff --git a/packages/platform/platform-cache/vitest.config.mts b/packages/platform/platform-cache/vitest.config.mts index 713a830f8d8..95bbef6af1b 100644 --- a/packages/platform/platform-cache/vitest.config.mts +++ b/packages/platform/platform-cache/vitest.config.mts @@ -11,11 +11,11 @@ export default defineConfig( ...presets.test.coverage, thresholds: { statements: 100, - branches: 98.92, + branches: 98.91, functions: 100, lines: 100 } } } } -); \ No newline at end of file +); diff --git a/packages/platform/platform-middlewares/src/decorators/authOptions.ts b/packages/platform/platform-middlewares/src/decorators/authOptions.ts index 6c61ffcddd7..851aee012a4 100644 --- a/packages/platform/platform-middlewares/src/decorators/authOptions.ts +++ b/packages/platform/platform-middlewares/src/decorators/authOptions.ts @@ -4,6 +4,7 @@ import { DecoratorParameters, decoratorTypeOf, DecoratorTypes, + Store, Type, UnsupportedDecoratorType } from "@tsed/core"; @@ -41,7 +42,12 @@ export function AuthOptions(guardAuth: Type, options: Record { + Store.fromMethod(args[0], property).merge(guardAuth, options, true); + }); + // methodsOf(args[0]).forEach(({propertyKey}) => { + // + // }); break; default: diff --git a/packages/platform/platform-middlewares/src/decorators/useAuth.ts b/packages/platform/platform-middlewares/src/decorators/useAuth.ts index bffa444aeb4..43dd40749b8 100644 --- a/packages/platform/platform-middlewares/src/decorators/useAuth.ts +++ b/packages/platform/platform-middlewares/src/decorators/useAuth.ts @@ -47,7 +47,16 @@ export function UseAuth(guardAuth: Type, options: Record = )(...args); case DecoratorTypes.CLASS: - decorateMethodsOf(args[0], UseAuth(guardAuth, options)); + decorateMethodsOf( + args[0], + StoreFn((store: Store) => { + if (!store.has(guardAuth)) { + return UseBefore(guardAuth); + } + }) + ); + + AuthOptions(guardAuth, options)(...args); break; default: diff --git a/packages/platform/platform-router/vitest.config.mts b/packages/platform/platform-router/vitest.config.mts index cc161ec7188..f1585ca25a5 100644 --- a/packages/platform/platform-router/vitest.config.mts +++ b/packages/platform/platform-router/vitest.config.mts @@ -11,11 +11,11 @@ export default defineConfig( ...presets.test.coverage, thresholds: { statements: 100, - branches: 97.47, + branches: 97.45, functions: 100, lines: 100 } } } } -); \ No newline at end of file +); diff --git a/packages/security/passport/src/decorators/__snapshots__/authorize.spec.ts.snap b/packages/security/passport/src/decorators/__snapshots__/authorize.spec.ts.snap new file mode 100644 index 00000000000..54346009924 --- /dev/null +++ b/packages/security/passport/src/decorators/__snapshots__/authorize.spec.ts.snap @@ -0,0 +1,53 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`@Authorize > should support inheritance 1`] = ` +{ + "paths": { + "/admin/allEntries": { + "get": { + "operationId": "abstractAdminControllerGetAllEntries", + "parameters": [], + "responses": { + "200": { + "description": "Success", + }, + }, + "tags": [ + "AdminController", + ], + }, + }, + }, + "tags": [ + { + "name": "AdminController", + }, + ], +} +`; + +exports[`@Authorize > should support inheritance 2`] = ` +{ + "paths": { + "/admin/bucket/allEntries": { + "get": { + "operationId": "abstractAdminControllerGetAllEntries", + "parameters": [], + "responses": { + "200": { + "description": "Success", + }, + }, + "tags": [ + "BucketAdminController", + ], + }, + }, + }, + "tags": [ + { + "name": "BucketAdminController", + }, + ], +} +`; diff --git a/packages/security/passport/src/decorators/authorize.spec.ts b/packages/security/passport/src/decorators/authorize.spec.ts index cbab06ef12d..790c3109653 100644 --- a/packages/security/passport/src/decorators/authorize.spec.ts +++ b/packages/security/passport/src/decorators/authorize.spec.ts @@ -1,7 +1,15 @@ import {Store} from "@tsed/core"; +import {Controller, inject} from "@tsed/di"; +import {Middleware, UseBefore} from "@tsed/platform-middlewares"; +import {Get, getSpec} from "@tsed/schema"; import {Authorize, PassportMiddleware} from "../index.js"; +@Middleware() +class AuthoriseBucket { + use() {} +} + describe("@Authorize", () => { it("should store data", () => { class Test { @@ -51,4 +59,38 @@ describe("@Authorize", () => { protocol: "local" }); }); + it("should support inheritance", async () => { + abstract class AbstractAdminController { + @Get("/allEntries") + getAllEntries(): Promise { + return Promise.resolve({}); + } + } + + @Authorize("loginAuthProvider") + @Controller("/admin") + class AdminController extends AbstractAdminController {} + + @Controller("/admin/bucket") + @UseBefore(AuthoriseBucket) + class BucketAdminController extends AbstractAdminController {} + + expect(getSpec(AdminController)).toMatchSnapshot(); + expect(getSpec(BucketAdminController)).toMatchSnapshot(); + expect(Reflect.getOwnPropertyDescriptor(AdminController.prototype, "getAllEntries")).toBeDefined(); + expect(Reflect.getOwnPropertyDescriptor(BucketAdminController.prototype, "getAllEntries")).not.toBeDefined(); + + const adminController = inject(AdminController); + + expect(await adminController.getAllEntries()).toEqual({}); + + expect(Store.fromMethod(BucketAdminController, "getAllEntries").get(PassportMiddleware)).toEqual(undefined); + expect(Store.fromMethod(AbstractAdminController, "getAllEntries").get(PassportMiddleware)).toEqual(undefined); + expect(Store.fromMethod(AdminController, "getAllEntries").get(PassportMiddleware)).toEqual({ + method: "authorize", + options: {}, + originalUrl: true, + protocol: "loginAuthProvider" + }); + }); });