diff --git a/packages/security/oidc-provider/src/services/OidcPolicy.spec.ts b/packages/security/oidc-provider/src/services/OidcPolicy.spec.ts index 027ef46b602..afb85d24807 100644 --- a/packages/security/oidc-provider/src/services/OidcPolicy.spec.ts +++ b/packages/security/oidc-provider/src/services/OidcPolicy.spec.ts @@ -1,5 +1,6 @@ import {PlatformTest} from "@tsed/common"; import {Env} from "@tsed/core"; +import {ConsentInteraction} from "../../test/app/interactions/ConsentInteraction"; import {Interaction} from "../decorators/interaction"; import {OidcInteractions} from "./OidcInteractions"; import {OidcPolicy} from "./OidcPolicy"; @@ -15,7 +16,6 @@ describe("OidcPolicy", () => { }) ); afterEach(() => PlatformTest.reset()); - describe("createPrompt()", () => { it("should bind options to prompt instance", async () => { const oidcProvider = PlatformTest.get(OidcPolicy); @@ -53,78 +53,103 @@ describe("OidcPolicy", () => { }); }); describe("getPolicy()", () => { - @Interaction({ - name: "test" - }) - class TestInteraction {} - - @Interaction({ - name: "test2" - }) - class Test2Interaction {} - - @Interaction({ - name: "login" - }) - class LoginInteraction {} - - @Interaction({ - name: "consent" - }) - class ConsentInteraction {} - - @Interaction({ - name: "test3", - priority: 0 - }) - class Test3Interaction {} - - it("should load policy (without priority)", async () => { - const oidcInteractions = { - getInteractions: jest - .fn() - .mockReturnValue([ - PlatformTest.injector.getProvider(Test2Interaction), - PlatformTest.injector.getProvider(LoginInteraction), - PlatformTest.injector.getProvider(ConsentInteraction), - PlatformTest.injector.getProvider(TestInteraction) - ]) - }; - - const oidcProvider = await PlatformTest.invoke(OidcPolicy, [ - { - token: OidcInteractions, - use: oidcInteractions - } - ]); - - const policy = oidcProvider.getPolicy(); - - expect(policy.map(({name}) => name)).toEqual(["test2", "login", "consent", "test"]); + describe('when there is interactions with "priority" property', () => { + @Interaction({ + name: "test" + }) + class TestInteraction {} + + @Interaction({ + name: "test2" + }) + class Test2Interaction {} + + @Interaction({ + name: "login" + }) + class LoginInteraction {} + + @Interaction({ + name: "consent" + }) + class ConsentInteraction {} + + @Interaction({ + name: "test3", + priority: 0 + }) + class Test3Interaction {} + + it("should load policy (without priority)", async () => { + const oidcInteractions = { + getInteractions: jest + .fn() + .mockReturnValue([ + PlatformTest.injector.getProvider(Test2Interaction), + PlatformTest.injector.getProvider(LoginInteraction), + PlatformTest.injector.getProvider(ConsentInteraction), + PlatformTest.injector.getProvider(TestInteraction) + ]) + }; + + const oidcProvider = await PlatformTest.invoke(OidcPolicy, [ + { + token: OidcInteractions, + use: oidcInteractions + } + ]); + + const policy = oidcProvider.getPolicy(); + + expect(policy.map(({name}) => name)).toEqual(["test2", "login", "consent", "test"]); + }); + it("should load policy (with priority)", async () => { + const oidcInteractions = { + getInteractions: jest + .fn() + .mockReturnValue([ + PlatformTest.injector.getProvider(Test2Interaction), + PlatformTest.injector.getProvider(LoginInteraction), + PlatformTest.injector.getProvider(ConsentInteraction), + PlatformTest.injector.getProvider(TestInteraction), + PlatformTest.injector.getProvider(Test3Interaction) + ]) + }; + + const oidcProvider = await PlatformTest.invoke(OidcPolicy, [ + { + token: OidcInteractions, + use: oidcInteractions + } + ]); + + const policy = oidcProvider.getPolicy(); + + expect(policy.map(({name}) => name)).toEqual(["test3", "login", "consent", "test2", "test"]); + }); }); - it("should load policy (with priority)", async () => { - const oidcInteractions = { - getInteractions: jest - .fn() - .mockReturnValue([ - PlatformTest.injector.getProvider(Test2Interaction), - PlatformTest.injector.getProvider(LoginInteraction), - PlatformTest.injector.getProvider(ConsentInteraction), - PlatformTest.injector.getProvider(TestInteraction), - PlatformTest.injector.getProvider(Test3Interaction) - ]) - }; - - const oidcProvider = await PlatformTest.invoke(OidcPolicy, [ - { - token: OidcInteractions, - use: oidcInteractions - } - ]); - - const policy = oidcProvider.getPolicy(); - - expect(policy.map(({name}) => name)).toEqual(["test3", "login", "consent", "test2", "test"]); + describe("when there is no interactions without usePriority", () => { + it("should load policy", async () => { + const oidcInteractions = { + getInteractions: jest.fn().mockReturnValue([]) + }; + + const oidcPolicy = await PlatformTest.invoke(OidcPolicy, [ + { + token: OidcInteractions, + use: oidcInteractions + } + ]); + + jest.spyOn(oidcPolicy as any, "getInteractions").mockReturnValue({ + usePriority: false, + interactions: new Map([["login", {name: "login", instance: {}} as any]]) + }); + + const policy = oidcPolicy.getPolicy(); + + expect(policy.map(({name}) => name)).toEqual(["login", "consent"]); + }); }); }); }); diff --git a/packages/security/oidc-provider/src/services/OidcPolicy.ts b/packages/security/oidc-provider/src/services/OidcPolicy.ts index 34e82ba28e1..ecaaee66a73 100644 --- a/packages/security/oidc-provider/src/services/OidcPolicy.ts +++ b/packages/security/oidc-provider/src/services/OidcPolicy.ts @@ -36,7 +36,12 @@ export class OidcPolicy { // reordering interactions by interactions index if (!usePriority) { - policy = policy.sort((a, b) => (interactions.get(a.name)!.order < interactions.get(b.name)!.order ? -1 : 1)); + policy = policy.sort((a, b) => { + const o1 = interactions.get(a.name)?.order || 0; + const o2 = interactions.get(b.name)?.order || 0; + + return o1 < o2 ? -1 : 1; + }); } } @@ -55,23 +60,35 @@ export class OidcPolicy { const interactions = this.oidcInteractions.getInteractions(); - const map = interactions.reduce((map, provider, index) => { - const instance = this.injector.get(provider.token)!; + const map = interactions.reduce( + (map, provider, index) => { + const instance = this.injector.get(provider.token)!; - const options = provider.store.get("interactionOptions"); + const options = provider.store.get("interactionOptions"); - if (options.priority !== undefined) { - usePriority = true; - } + if (options.priority !== undefined) { + usePriority = true; + } - return map.set(options.name, { - order: index, - name: options.name, - provider, - instance, - options - }); - }, new Map()); + return map.set(options.name, { + order: index, + name: options.name, + provider, + instance, + options + }); + }, + new Map< + string, + { + order: number; + provider: Provider; + instance: any; + options: OidcInteractionOptions; + name: string; + } + >() + ); return { interactions: map,