@tsed/cli-plugin-oidc-provider 3.23.0 → 3.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,18 +17,22 @@ let OidcProviderInitHook = class OidcProviderInitHook {
17
17
  task: async () => this.rootRenderer.renderAll([
18
18
  "/src/config/oidc/index.ts.hbs",
19
19
  "/src/controllers/oidc/InteractionsController.ts",
20
+ ctx.jest && "/src/controllers/oidc/InteractionsController.spec.ts",
20
21
  "/src/interactions/ConsentInteraction.ts",
22
+ ctx.jest && "/src/interactions/ConsentInteraction.spec.ts",
21
23
  "/src/interactions/CustomInteraction.ts",
22
24
  "/src/interactions/LoginInteraction.ts",
25
+ ctx.jest && "/src/interactions/LoginInteraction.spec.ts",
26
+ ctx.jest && "/src/interactions/__mock__/oidcContext.fixture.ts",
23
27
  "/src/models/Account.ts",
24
28
  "/src/services/Accounts.ts",
25
- "/views/forms/interaction-form.ejs",
29
+ "/views/forms/consent-form.ejs",
26
30
  "/views/forms/login-form.ejs",
27
31
  "/views/forms/select-account-form.ejs",
28
32
  "/views/partials/footer.ejs",
29
33
  "/views/partials/header.ejs",
30
34
  "/views/partials/login-help.ejs",
31
- "/views/interaction.ejs",
35
+ "/views/consent.ejs",
32
36
  "/views/login.ejs",
33
37
  "/views/repost.ejs",
34
38
  "/views/select_account.ejs"
@@ -1 +1 @@
1
- {"version":3,"file":"OidcProviderInitHook.js","sourceRoot":"","sources":["../../../src/hooks/OidcProviderInitHook.ts"],"names":[],"mappings":";;;;AACA,6CAAiI;AACjI,iCAAoC;AACpC,sDAAkD;AAGlD,IAAa,oBAAoB,GAAjC,MAAa,oBAAoB;IAErB,WAAW,CAAqB;IAGhC,YAAY,CAAsB;IAGlC,WAAW,CAAqB;IAGhC,oBAAoB,CAAuB;IAGrD,MAAM,CAAC,GAAmB;QACxB,OAAO;YACL;gBACE,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,IAAI,CAAC,YAAY,CAAC,SAAS,CACzB;oBACE,+BAA+B;oBAC/B,iDAAiD;oBACjD,yCAAyC;oBACzC,wCAAwC;oBACxC,uCAAuC;oBACvC,wBAAwB;oBACxB,2BAA2B;oBAC3B,mCAAmC;oBACnC,6BAA6B;oBAC7B,sCAAsC;oBACtC,4BAA4B;oBAC5B,4BAA4B;oBAC5B,gCAAgC;oBAChC,wBAAwB;oBACxB,kBAAkB;oBAClB,mBAAmB;oBACnB,2BAA2B;iBAC5B,EACD,GAAG,EACH;oBACE,WAAW,EAAE,GAAG,0BAAY,OAAO;iBACpC,CACF;aACJ;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AA7CC;IADC,IAAA,iBAAM,GAAE;sCACc,6BAAkB;yDAAC;AAG1C;IADC,IAAA,iBAAM,GAAE;sCACe,8BAAmB;0DAAC;AAG5C;IADC,IAAA,iBAAM,GAAE;sCACc,6BAAkB;yDAAC;AAG1C;IADC,IAAA,iBAAM,GAAE;sCACuB,+BAAoB;kEAAC;AAGrD;IADC,IAAA,iBAAM,EAAC,MAAM,CAAC;;;;kDAiCd;AA9CU,oBAAoB;IADhC,IAAA,eAAU,GAAE;GACA,oBAAoB,CA+ChC;AA/CY,oDAAoB","sourcesContent":["import {InitCmdContext} from \"@tsed/cli\";\nimport {CliDockerComposeYaml, Inject, OnExec, ProjectPackageJson, RootRendererService, SrcRendererService} from \"@tsed/cli-core\";\nimport {Injectable} from \"@tsed/di\";\nimport {TEMPLATE_DIR} from \"../utils/templateDir\";\n\n@Injectable()\nexport class OidcProviderInitHook {\n @Inject()\n protected packageJson: ProjectPackageJson;\n\n @Inject()\n protected rootRenderer: RootRendererService;\n\n @Inject()\n protected srcRenderer: SrcRendererService;\n\n @Inject()\n protected cliDockerComposeYaml: CliDockerComposeYaml;\n\n @OnExec(\"init\")\n onExec(ctx: InitCmdContext) {\n return [\n {\n title: \"Generate files\",\n task: async () =>\n this.rootRenderer.renderAll(\n [\n \"/src/config/oidc/index.ts.hbs\",\n \"/src/controllers/oidc/InteractionsController.ts\",\n \"/src/interactions/ConsentInteraction.ts\",\n \"/src/interactions/CustomInteraction.ts\",\n \"/src/interactions/LoginInteraction.ts\",\n \"/src/models/Account.ts\",\n \"/src/services/Accounts.ts\",\n \"/views/forms/interaction-form.ejs\",\n \"/views/forms/login-form.ejs\",\n \"/views/forms/select-account-form.ejs\",\n \"/views/partials/footer.ejs\",\n \"/views/partials/header.ejs\",\n \"/views/partials/login-help.ejs\",\n \"/views/interaction.ejs\",\n \"/views/login.ejs\",\n \"/views/repost.ejs\",\n \"/views/select_account.ejs\"\n ],\n ctx,\n {\n templateDir: `${TEMPLATE_DIR}/init`\n }\n )\n }\n ];\n }\n}\n"]}
1
+ {"version":3,"file":"OidcProviderInitHook.js","sourceRoot":"","sources":["../../../src/hooks/OidcProviderInitHook.ts"],"names":[],"mappings":";;;;AACA,6CAAiI;AACjI,iCAAoC;AACpC,sDAAkD;AAGlD,IAAa,oBAAoB,GAAjC,MAAa,oBAAoB;IAErB,WAAW,CAAqB;IAGhC,YAAY,CAAsB;IAGlC,WAAW,CAAqB;IAGhC,oBAAoB,CAAuB;IAGrD,MAAM,CAAC,GAAmB;QACxB,OAAO;YACL;gBACE,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,IAAI,CAAC,YAAY,CAAC,SAAS,CACzB;oBACE,+BAA+B;oBAC/B,iDAAiD;oBACjD,GAAG,CAAC,IAAI,IAAI,sDAAsD;oBAClE,yCAAyC;oBACzC,GAAG,CAAC,IAAI,IAAI,8CAA8C;oBAC1D,wCAAwC;oBACxC,uCAAuC;oBACvC,GAAG,CAAC,IAAI,IAAI,4CAA4C;oBACxD,GAAG,CAAC,IAAI,IAAI,mDAAmD;oBAC/D,wBAAwB;oBACxB,2BAA2B;oBAC3B,+BAA+B;oBAC/B,6BAA6B;oBAC7B,sCAAsC;oBACtC,4BAA4B;oBAC5B,4BAA4B;oBAC5B,gCAAgC;oBAChC,oBAAoB;oBACpB,kBAAkB;oBAClB,mBAAmB;oBACnB,2BAA2B;iBAC5B,EACD,GAAG,EACH;oBACE,WAAW,EAAE,GAAG,0BAAY,OAAO;iBACpC,CACF;aACJ;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAjDC;IADC,IAAA,iBAAM,GAAE;sCACc,6BAAkB;yDAAC;AAG1C;IADC,IAAA,iBAAM,GAAE;sCACe,8BAAmB;0DAAC;AAG5C;IADC,IAAA,iBAAM,GAAE;sCACc,6BAAkB;yDAAC;AAG1C;IADC,IAAA,iBAAM,GAAE;sCACuB,+BAAoB;kEAAC;AAGrD;IADC,IAAA,iBAAM,EAAC,MAAM,CAAC;;;;kDAqCd;AAlDU,oBAAoB;IADhC,IAAA,eAAU,GAAE;GACA,oBAAoB,CAmDhC;AAnDY,oDAAoB","sourcesContent":["import {InitCmdContext} from \"@tsed/cli\";\nimport {CliDockerComposeYaml, Inject, OnExec, ProjectPackageJson, RootRendererService, SrcRendererService} from \"@tsed/cli-core\";\nimport {Injectable} from \"@tsed/di\";\nimport {TEMPLATE_DIR} from \"../utils/templateDir\";\n\n@Injectable()\nexport class OidcProviderInitHook {\n @Inject()\n protected packageJson: ProjectPackageJson;\n\n @Inject()\n protected rootRenderer: RootRendererService;\n\n @Inject()\n protected srcRenderer: SrcRendererService;\n\n @Inject()\n protected cliDockerComposeYaml: CliDockerComposeYaml;\n\n @OnExec(\"init\")\n onExec(ctx: InitCmdContext) {\n return [\n {\n title: \"Generate files\",\n task: async () =>\n this.rootRenderer.renderAll(\n [\n \"/src/config/oidc/index.ts.hbs\",\n \"/src/controllers/oidc/InteractionsController.ts\",\n ctx.jest && \"/src/controllers/oidc/InteractionsController.spec.ts\",\n \"/src/interactions/ConsentInteraction.ts\",\n ctx.jest && \"/src/interactions/ConsentInteraction.spec.ts\",\n \"/src/interactions/CustomInteraction.ts\",\n \"/src/interactions/LoginInteraction.ts\",\n ctx.jest && \"/src/interactions/LoginInteraction.spec.ts\",\n ctx.jest && \"/src/interactions/__mock__/oidcContext.fixture.ts\",\n \"/src/models/Account.ts\",\n \"/src/services/Accounts.ts\",\n \"/views/forms/consent-form.ejs\",\n \"/views/forms/login-form.ejs\",\n \"/views/forms/select-account-form.ejs\",\n \"/views/partials/footer.ejs\",\n \"/views/partials/header.ejs\",\n \"/views/partials/login-help.ejs\",\n \"/views/consent.ejs\",\n \"/views/login.ejs\",\n \"/views/repost.ejs\",\n \"/views/select_account.ejs\"\n ],\n ctx,\n {\n templateDir: `${TEMPLATE_DIR}/init`\n }\n )\n }\n ];\n }\n}\n"]}
@@ -14,18 +14,22 @@ let OidcProviderInitHook = class OidcProviderInitHook {
14
14
  task: async () => this.rootRenderer.renderAll([
15
15
  "/src/config/oidc/index.ts.hbs",
16
16
  "/src/controllers/oidc/InteractionsController.ts",
17
+ ctx.jest && "/src/controllers/oidc/InteractionsController.spec.ts",
17
18
  "/src/interactions/ConsentInteraction.ts",
19
+ ctx.jest && "/src/interactions/ConsentInteraction.spec.ts",
18
20
  "/src/interactions/CustomInteraction.ts",
19
21
  "/src/interactions/LoginInteraction.ts",
22
+ ctx.jest && "/src/interactions/LoginInteraction.spec.ts",
23
+ ctx.jest && "/src/interactions/__mock__/oidcContext.fixture.ts",
20
24
  "/src/models/Account.ts",
21
25
  "/src/services/Accounts.ts",
22
- "/views/forms/interaction-form.ejs",
26
+ "/views/forms/consent-form.ejs",
23
27
  "/views/forms/login-form.ejs",
24
28
  "/views/forms/select-account-form.ejs",
25
29
  "/views/partials/footer.ejs",
26
30
  "/views/partials/header.ejs",
27
31
  "/views/partials/login-help.ejs",
28
- "/views/interaction.ejs",
32
+ "/views/consent.ejs",
29
33
  "/views/login.ejs",
30
34
  "/views/repost.ejs",
31
35
  "/views/select_account.ejs"
@@ -1 +1 @@
1
- {"version":3,"file":"OidcProviderInitHook.js","sourceRoot":"","sources":["../../../src/hooks/OidcProviderInitHook.ts"],"names":[],"mappings":";AACA,OAAO,EAAC,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AACjI,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACpC,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAGlD,IAAa,oBAAoB,GAAjC,MAAa,oBAAoB;IAErB,WAAW,CAAqB;IAGhC,YAAY,CAAsB;IAGlC,WAAW,CAAqB;IAGhC,oBAAoB,CAAuB;IAGrD,MAAM,CAAC,GAAmB;QACxB,OAAO;YACL;gBACE,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,IAAI,CAAC,YAAY,CAAC,SAAS,CACzB;oBACE,+BAA+B;oBAC/B,iDAAiD;oBACjD,yCAAyC;oBACzC,wCAAwC;oBACxC,uCAAuC;oBACvC,wBAAwB;oBACxB,2BAA2B;oBAC3B,mCAAmC;oBACnC,6BAA6B;oBAC7B,sCAAsC;oBACtC,4BAA4B;oBAC5B,4BAA4B;oBAC5B,gCAAgC;oBAChC,wBAAwB;oBACxB,kBAAkB;oBAClB,mBAAmB;oBACnB,2BAA2B;iBAC5B,EACD,GAAG,EACH;oBACE,WAAW,EAAE,GAAG,YAAY,OAAO;iBACpC,CACF;aACJ;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AA7CC;IADC,MAAM,EAAE;8BACc,kBAAkB;yDAAC;AAG1C;IADC,MAAM,EAAE;8BACe,mBAAmB;0DAAC;AAG5C;IADC,MAAM,EAAE;8BACc,kBAAkB;yDAAC;AAG1C;IADC,MAAM,EAAE;8BACuB,oBAAoB;kEAAC;AAGrD;IADC,MAAM,CAAC,MAAM,CAAC;;;;kDAiCd;AA9CU,oBAAoB;IADhC,UAAU,EAAE;GACA,oBAAoB,CA+ChC;SA/CY,oBAAoB","sourcesContent":["import {InitCmdContext} from \"@tsed/cli\";\nimport {CliDockerComposeYaml, Inject, OnExec, ProjectPackageJson, RootRendererService, SrcRendererService} from \"@tsed/cli-core\";\nimport {Injectable} from \"@tsed/di\";\nimport {TEMPLATE_DIR} from \"../utils/templateDir\";\n\n@Injectable()\nexport class OidcProviderInitHook {\n @Inject()\n protected packageJson: ProjectPackageJson;\n\n @Inject()\n protected rootRenderer: RootRendererService;\n\n @Inject()\n protected srcRenderer: SrcRendererService;\n\n @Inject()\n protected cliDockerComposeYaml: CliDockerComposeYaml;\n\n @OnExec(\"init\")\n onExec(ctx: InitCmdContext) {\n return [\n {\n title: \"Generate files\",\n task: async () =>\n this.rootRenderer.renderAll(\n [\n \"/src/config/oidc/index.ts.hbs\",\n \"/src/controllers/oidc/InteractionsController.ts\",\n \"/src/interactions/ConsentInteraction.ts\",\n \"/src/interactions/CustomInteraction.ts\",\n \"/src/interactions/LoginInteraction.ts\",\n \"/src/models/Account.ts\",\n \"/src/services/Accounts.ts\",\n \"/views/forms/interaction-form.ejs\",\n \"/views/forms/login-form.ejs\",\n \"/views/forms/select-account-form.ejs\",\n \"/views/partials/footer.ejs\",\n \"/views/partials/header.ejs\",\n \"/views/partials/login-help.ejs\",\n \"/views/interaction.ejs\",\n \"/views/login.ejs\",\n \"/views/repost.ejs\",\n \"/views/select_account.ejs\"\n ],\n ctx,\n {\n templateDir: `${TEMPLATE_DIR}/init`\n }\n )\n }\n ];\n }\n}\n"]}
1
+ {"version":3,"file":"OidcProviderInitHook.js","sourceRoot":"","sources":["../../../src/hooks/OidcProviderInitHook.ts"],"names":[],"mappings":";AACA,OAAO,EAAC,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AACjI,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACpC,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAGlD,IAAa,oBAAoB,GAAjC,MAAa,oBAAoB;IAErB,WAAW,CAAqB;IAGhC,YAAY,CAAsB;IAGlC,WAAW,CAAqB;IAGhC,oBAAoB,CAAuB;IAGrD,MAAM,CAAC,GAAmB;QACxB,OAAO;YACL;gBACE,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,IAAI,CAAC,YAAY,CAAC,SAAS,CACzB;oBACE,+BAA+B;oBAC/B,iDAAiD;oBACjD,GAAG,CAAC,IAAI,IAAI,sDAAsD;oBAClE,yCAAyC;oBACzC,GAAG,CAAC,IAAI,IAAI,8CAA8C;oBAC1D,wCAAwC;oBACxC,uCAAuC;oBACvC,GAAG,CAAC,IAAI,IAAI,4CAA4C;oBACxD,GAAG,CAAC,IAAI,IAAI,mDAAmD;oBAC/D,wBAAwB;oBACxB,2BAA2B;oBAC3B,+BAA+B;oBAC/B,6BAA6B;oBAC7B,sCAAsC;oBACtC,4BAA4B;oBAC5B,4BAA4B;oBAC5B,gCAAgC;oBAChC,oBAAoB;oBACpB,kBAAkB;oBAClB,mBAAmB;oBACnB,2BAA2B;iBAC5B,EACD,GAAG,EACH;oBACE,WAAW,EAAE,GAAG,YAAY,OAAO;iBACpC,CACF;aACJ;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAjDC;IADC,MAAM,EAAE;8BACc,kBAAkB;yDAAC;AAG1C;IADC,MAAM,EAAE;8BACe,mBAAmB;0DAAC;AAG5C;IADC,MAAM,EAAE;8BACc,kBAAkB;yDAAC;AAG1C;IADC,MAAM,EAAE;8BACuB,oBAAoB;kEAAC;AAGrD;IADC,MAAM,CAAC,MAAM,CAAC;;;;kDAqCd;AAlDU,oBAAoB;IADhC,UAAU,EAAE;GACA,oBAAoB,CAmDhC;SAnDY,oBAAoB","sourcesContent":["import {InitCmdContext} from \"@tsed/cli\";\nimport {CliDockerComposeYaml, Inject, OnExec, ProjectPackageJson, RootRendererService, SrcRendererService} from \"@tsed/cli-core\";\nimport {Injectable} from \"@tsed/di\";\nimport {TEMPLATE_DIR} from \"../utils/templateDir\";\n\n@Injectable()\nexport class OidcProviderInitHook {\n @Inject()\n protected packageJson: ProjectPackageJson;\n\n @Inject()\n protected rootRenderer: RootRendererService;\n\n @Inject()\n protected srcRenderer: SrcRendererService;\n\n @Inject()\n protected cliDockerComposeYaml: CliDockerComposeYaml;\n\n @OnExec(\"init\")\n onExec(ctx: InitCmdContext) {\n return [\n {\n title: \"Generate files\",\n task: async () =>\n this.rootRenderer.renderAll(\n [\n \"/src/config/oidc/index.ts.hbs\",\n \"/src/controllers/oidc/InteractionsController.ts\",\n ctx.jest && \"/src/controllers/oidc/InteractionsController.spec.ts\",\n \"/src/interactions/ConsentInteraction.ts\",\n ctx.jest && \"/src/interactions/ConsentInteraction.spec.ts\",\n \"/src/interactions/CustomInteraction.ts\",\n \"/src/interactions/LoginInteraction.ts\",\n ctx.jest && \"/src/interactions/LoginInteraction.spec.ts\",\n ctx.jest && \"/src/interactions/__mock__/oidcContext.fixture.ts\",\n \"/src/models/Account.ts\",\n \"/src/services/Accounts.ts\",\n \"/views/forms/consent-form.ejs\",\n \"/views/forms/login-form.ejs\",\n \"/views/forms/select-account-form.ejs\",\n \"/views/partials/footer.ejs\",\n \"/views/partials/header.ejs\",\n \"/views/partials/login-help.ejs\",\n \"/views/consent.ejs\",\n \"/views/login.ejs\",\n \"/views/repost.ejs\",\n \"/views/select_account.ejs\"\n ],\n ctx,\n {\n templateDir: `${TEMPLATE_DIR}/init`\n }\n )\n }\n ];\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsed/cli-plugin-oidc-provider",
3
- "version": "3.23.0",
3
+ "version": "3.24.0",
4
4
  "description": "Ts.ED CLI plugin. Add OIDC Provider",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/cjs/index.js",
@@ -25,12 +25,12 @@
25
25
  "tslib": "2.3.1"
26
26
  },
27
27
  "devDependencies": {
28
- "@tsed/cli": "3.23.0",
29
- "@tsed/cli-core": "3.23.0"
28
+ "@tsed/cli": "3.24.0",
29
+ "@tsed/cli-core": "3.24.0"
30
30
  },
31
31
  "peerDependencies": {
32
- "@tsed/cli": "^3.23.0",
33
- "@tsed/cli-core": "^3.23.0"
32
+ "@tsed/cli": "^3.24.0",
33
+ "@tsed/cli-core": "^3.24.0"
34
34
  },
35
35
  "repository": "https://github.com/tsedio/tsed-cli",
36
36
  "bugs": {
@@ -0,0 +1,20 @@
1
+ import { PlatformTest } from "@tsed/common";
2
+
3
+ import { getOidcContextFixture } from "../../interactions/__mock__/oidcContext.fixture";
4
+ import { InteractionsController } from "./InteractionsController";
5
+
6
+ describe("InteractionsController", () => {
7
+ beforeEach(() => PlatformTest.create());
8
+ afterEach(() => PlatformTest.reset());
9
+
10
+ describe("promptInteraction()", () => {
11
+ it("should run the asked prompt interaction", async () => {
12
+ const oidcContext = getOidcContextFixture();
13
+ const controller = await PlatformTest.invoke<InteractionsController>(InteractionsController);
14
+
15
+ await controller.promptInteraction(oidcContext);
16
+
17
+ expect(oidcContext.runInteraction).toHaveBeenCalledWith();
18
+ });
19
+ });
20
+ });
@@ -1,14 +1,12 @@
1
1
  import {Get} from "@tsed/common";
2
2
  import {Interactions, OidcCtx} from "@tsed/oidc-provider";
3
3
  import {Name} from "@tsed/schema";
4
- import {ConsentInteraction} from "../../interactions/ConsentInteraction";
5
- import {CustomInteraction} from "../../interactions/CustomInteraction";
6
- import {LoginInteraction} from "../../interactions/LoginInteraction";
4
+ import * as interactions from "../../interactions/index";
7
5
 
8
6
  @Name("Oidc")
9
7
  @Interactions({
10
8
  path: "/interaction/:uid",
11
- children: [LoginInteraction, ConsentInteraction, CustomInteraction]
9
+ children: Object.values(interactions)
12
10
  })
13
11
  export class InteractionsController {
14
12
  @Get("/")
@@ -0,0 +1,71 @@
1
+ import { PlatformTest } from "@tsed/common";
2
+
3
+ import { getOidcContextFixture } from "./__mock__/oidcContext.fixture";
4
+ import { ConsentInteraction } from "./ConsentInteraction";
5
+
6
+ async function createInteractionFixture() {
7
+ const interaction = await PlatformTest.invoke<ConsentInteraction>(ConsentInteraction, []);
8
+
9
+ return { interaction };
10
+ }
11
+
12
+ describe("ConsentInteraction", () => {
13
+ beforeEach(() => PlatformTest.create());
14
+ afterEach(() => PlatformTest.reset());
15
+
16
+ describe("$prompt()", () => {
17
+ it("should return consent context", async () => {
18
+ const { interaction } = await createInteractionFixture();
19
+ const oidcContext = getOidcContextFixture();
20
+
21
+ const result = await interaction.$prompt(oidcContext);
22
+
23
+ expect(result).toEqual({
24
+ client: {
25
+ client_id: "client_id"
26
+ },
27
+ flash: false,
28
+ details: {},
29
+ params: {
30
+ client_id: "client_id"
31
+ },
32
+ title: "Authorize",
33
+ uid: "uid"
34
+ });
35
+ });
36
+ });
37
+ describe("confirm()", () => {
38
+ it("should control all consentement", async () => {
39
+ const { interaction } = await createInteractionFixture();
40
+ const oidcContext = getOidcContextFixture();
41
+ oidcContext.prompt.name = "consent";
42
+
43
+ const grant = {
44
+ save: jest.fn().mockResolvedValue("grantId"),
45
+ addOIDCScope: jest.fn(),
46
+ addOIDCClaims: jest.fn(),
47
+ addResourceScope: jest.fn()
48
+ };
49
+
50
+ oidcContext.getGrant.mockResolvedValue(grant);
51
+ oidcContext.prompt.details = {
52
+ missingOIDCScope: ["scope1", "scope2"],
53
+ missingOIDClaims: ["claims"],
54
+ missingResourceScopes: {
55
+ indicator: ["scopes"]
56
+ }
57
+ };
58
+
59
+ const result = await interaction.confirm(oidcContext);
60
+
61
+ expect(result).toEqual(undefined);
62
+
63
+ expect(oidcContext.getGrant).toHaveBeenCalledWith();
64
+ expect(grant.addOIDCScope).toHaveBeenCalledWith("scope1 scope2");
65
+ expect(grant.addOIDCClaims).toHaveBeenCalledWith(["claims"]);
66
+ expect(grant.addResourceScope).toHaveBeenCalledWith("indicator", "scopes");
67
+ expect(grant.save).toHaveBeenCalledWith();
68
+ expect(oidcContext.interactionFinished).toHaveBeenCalledWith({ consent: { grantId: "grantId" } }, { mergeWithLastSubmission: true });
69
+ });
70
+ });
71
+ });
@@ -1,6 +1,5 @@
1
1
  import {Inject, Post, View} from "@tsed/common";
2
- import {BadRequest} from "@tsed/exceptions";
3
- import {Interaction, OidcCtx, OidcProvider, OidcSession, Params, Prompt, Uid} from "@tsed/oidc-provider";
2
+ import {Interaction, OidcCtx, OidcProvider} from "@tsed/oidc-provider";
4
3
  import {Name} from "@tsed/schema";
5
4
 
6
5
  @Interaction({
@@ -11,47 +10,35 @@ export class ConsentInteraction {
11
10
  @Inject()
12
11
  oidc: OidcProvider;
13
12
 
14
- @View("interaction")
15
- async $prompt(
16
- @OidcCtx() oidcCtx: OidcCtx,
17
- @Prompt() prompt: Prompt,
18
- @OidcSession() session: OidcSession,
19
- @Params() params: Params,
20
- @Uid() uid: Uid
21
- ): Promise<any> {
22
- const client = await oidcCtx.findClient();
23
-
24
- return {
25
- client,
26
- uid,
27
- details: prompt.details,
28
- params,
13
+ @View("consent")
14
+ async $prompt(@OidcCtx() oidcCtx: OidcCtx): Promise<any> {
15
+ const account = await oidcCtx.findAccount();
16
+ return oidcCtx.interactionPrompt({
29
17
  title: "Authorize",
30
- ...oidcCtx.debug()
31
- };
18
+ account,
19
+ flash: false
20
+ });
32
21
  }
33
22
 
34
23
  @Post("/confirm")
35
- async confirm(@OidcCtx() oidcCtx: OidcCtx, @Prompt() prompt: Prompt) {
36
- if (prompt.name !== "consent") {
37
- throw new BadRequest("Bad interaction name");
38
- }
24
+ async confirm(@OidcCtx() oidcCtx: OidcCtx) {
25
+ oidcCtx.checkInteractionName("content");
39
26
 
40
27
  const grant = await oidcCtx.getGrant();
41
- const details = prompt.details as {
28
+ const details = oidcCtx.prompt.details as {
42
29
  missingOIDCScope: string[];
43
30
  missingResourceScopes: Record<string, string[]>;
44
31
  missingOIDClaims: string[];
45
32
  };
46
33
 
47
- const {missingOIDCScope, missingOIDClaims, missingResourceScopes} = details;
34
+ const { missingOIDCScope, missingOIDClaims, missingResourceScopes } = details;
48
35
 
49
36
  if (missingOIDCScope) {
50
37
  grant.addOIDCScope(missingOIDCScope.join(" "));
51
38
  // use grant.rejectOIDCScope to reject a subset or the whole thing
52
39
  }
53
40
  if (missingOIDClaims) {
54
- grant.addOIDCClaims(missingOIDCScope);
41
+ grant.addOIDCClaims(missingOIDClaims);
55
42
  // use grant.rejectOIDCClaims to reject a subset or the whole thing
56
43
  }
57
44
 
@@ -64,7 +51,6 @@ export class ConsentInteraction {
64
51
  }
65
52
 
66
53
  const grantId = await grant.save();
67
-
68
54
  const consent: any = {};
69
55
 
70
56
  if (!oidcCtx.grantId) {
@@ -0,0 +1,126 @@
1
+ import { PlatformTest } from "@tsed/common";
2
+ import { catchAsyncError } from "@tsed/core";
3
+ import { BadRequest } from "@tsed/exceptions";
4
+
5
+ import { Accounts } from "../services/Accounts";
6
+ import { getOidcContextFixture } from "./__mock__/oidcContext.fixture";
7
+ import { LoginInteraction } from "./LoginInteraction";
8
+
9
+ async function createInteractionFixture() {
10
+ const accounts = {
11
+ authenticate: jest.fn()
12
+ };
13
+
14
+ const interaction = await PlatformTest.invoke<LoginInteraction>(LoginInteraction, [
15
+ {
16
+ token: Accounts,
17
+ use: accounts
18
+ }
19
+ ]);
20
+
21
+ return { interaction, accounts };
22
+ }
23
+
24
+ describe("LoginInteraction", () => {
25
+ beforeEach(() => {
26
+ jest.resetAllMocks();
27
+ return PlatformTest.create();
28
+ });
29
+ afterEach(() => PlatformTest.reset());
30
+
31
+ describe("$prompt()", () => {
32
+ it("should return the prompt login context", async () => {
33
+ const { interaction } = await createInteractionFixture();
34
+ const oidcContext = getOidcContextFixture();
35
+
36
+ const result = await interaction.$prompt(oidcContext);
37
+
38
+ expect(oidcContext.checkClientId).toHaveBeenCalledWith();
39
+
40
+ expect(result).toEqual({
41
+ client: {
42
+ client_id: "client_id"
43
+ },
44
+ details: {},
45
+ flash: false,
46
+ params: {
47
+ client_id: "client_id"
48
+ },
49
+ title: "Sign-in",
50
+ uid: "uid"
51
+ });
52
+ });
53
+ it("should throw error when the Client is unauthorized", async () => {
54
+ const { interaction } = await createInteractionFixture();
55
+ const oidcContext = getOidcContextFixture();
56
+
57
+ (oidcContext.checkClientId as jest.Mock).mockRejectedValue(new Error("Unknown given client_id: client_id"));
58
+
59
+ const result = await catchAsyncError(() => interaction.$prompt(oidcContext));
60
+
61
+ expect(oidcContext.checkClientId).toHaveBeenCalledWith();
62
+ expect(result?.message).toEqual("Unknown given client_id: client_id");
63
+ });
64
+ });
65
+ describe("submit()", () => {
66
+ it("should find account", async () => {
67
+ const { interaction, accounts } = await createInteractionFixture();
68
+ const oidcContext = getOidcContextFixture();
69
+
70
+ const payload = { email: "email@email.com", password: "pwd" };
71
+
72
+ accounts.authenticate.mockResolvedValue({
73
+ accountId: "id"
74
+ });
75
+
76
+ const result = await interaction.submit(payload, oidcContext);
77
+
78
+ expect(result).toEqual(undefined);
79
+ expect(oidcContext.checkInteractionName).toHaveBeenCalledWith("login");
80
+ expect(oidcContext.interactionFinished).toHaveBeenCalledWith({ login: { accountId: "id" } });
81
+ });
82
+ it("should return to the login page and return the right context page", async () => {
83
+ const { interaction, accounts } = await createInteractionFixture();
84
+ const oidcContext = getOidcContextFixture();
85
+
86
+ const payload = { email: "email@email.com", password: "pwd" };
87
+
88
+ accounts.authenticate.mockResolvedValue(null);
89
+
90
+ const result = await interaction.submit(payload, oidcContext);
91
+
92
+ expect(result).toEqual({
93
+ client: {
94
+ client_id: "client_id"
95
+ },
96
+ details: {},
97
+ flash: "Invalid email or password.",
98
+ params: {
99
+ client_id: "client_id",
100
+ login_hint: "email@email.com"
101
+ },
102
+ title: "Sign-in",
103
+ uid: "uid"
104
+ });
105
+ expect(oidcContext.checkInteractionName).toHaveBeenCalledWith("login");
106
+ expect(oidcContext.interactionFinished).not.toHaveBeenCalled();
107
+ });
108
+ it("should fail if the prompt name is incorrect", async () => {
109
+ const { interaction } = await createInteractionFixture();
110
+ const oidcContext = getOidcContextFixture();
111
+ oidcContext.prompt.name = "unknown";
112
+
113
+ oidcContext.checkInteractionName.mockImplementation(() => {
114
+ throw new BadRequest("Bad interaction name");
115
+ });
116
+
117
+ const payload = { email: "email@email.com", password: "pwd" };
118
+
119
+ const error = await catchAsyncError<any>(() => interaction.submit(payload, oidcContext));
120
+
121
+ expect(oidcContext.checkInteractionName).toHaveBeenCalledWith("login");
122
+ expect(error?.message).toEqual("Bad interaction name");
123
+ expect(error?.status).toEqual(400);
124
+ });
125
+ });
126
+ });
@@ -1,8 +1,7 @@
1
1
  import {BodyParams, Inject, Post, View} from "@tsed/common";
2
2
  import {Env} from "@tsed/core";
3
3
  import {Constant} from "@tsed/di";
4
- import {BadRequest, Unauthorized} from "@tsed/exceptions";
5
- import {Interaction, OidcCtx, OidcSession, Params, Prompt, Uid} from "@tsed/oidc-provider";
4
+ import {Interaction, OidcCtx} from "@tsed/oidc-provider";
6
5
  import {Name} from "@tsed/schema";
7
6
  import {Accounts} from "../services/Accounts";
8
7
 
@@ -21,60 +20,34 @@ export class LoginInteraction {
21
20
 
22
21
  @View("login")
23
22
  async $prompt(
24
- @OidcCtx() oidcCtx: OidcCtx,
25
- @Prompt() prompt: Prompt,
26
- @OidcSession() session: OidcSession,
27
- @Params() params: Params,
28
- @Uid() uid: Uid
23
+ @OidcCtx() oidcCtx: OidcCtx
29
24
  ): Promise<any> {
30
- const client = await oidcCtx.findClient();
31
-
32
- if (!client) {
33
- throw new Unauthorized(`Unknown client_id ${params.client_id}`);
34
- }
25
+ await oidcCtx.checkClientId();
35
26
 
36
- return {
37
- client,
38
- uid,
39
- details: prompt.details,
40
- params,
27
+ return oidcCtx.interactionPrompt({
41
28
  title: "Sign-in",
42
- flash: false,
43
- ...oidcCtx.debug()
44
- };
29
+ flash: false
30
+ });
45
31
  }
46
32
 
47
33
  @Post("/login")
48
34
  @View("login")
49
35
  async submit(
50
36
  @BodyParams() payload: any,
51
- @Params() params: Params,
52
- @Uid() uid: Uid,
53
- @OidcSession() session: OidcSession,
54
- @Prompt() prompt: Prompt,
55
37
  @OidcCtx() oidcCtx: OidcCtx
56
38
  ) {
57
- if (prompt.name !== "login") {
58
- throw new BadRequest("Bad interaction name");
59
- }
60
-
61
- const client = await oidcCtx.findClient();
39
+ oidcCtx.checkInteractionName("login");
62
40
 
63
- const account = await this.accounts.authenticate(payload.email);
41
+ const account = await this.accounts.authenticate(payload.email, payload.password);
64
42
 
65
43
  if (!account) {
66
- return {
67
- client,
68
- uid,
69
- details: prompt.details,
44
+ return oidcCtx.interactionPrompt({
70
45
  params: {
71
- ...params,
72
46
  login_hint: payload.email
73
47
  },
74
48
  title: "Sign-in",
75
- flash: "Invalid email or password.",
76
- ...oidcCtx.debug()
77
- };
49
+ flash: "Invalid email or password."
50
+ });
78
51
  }
79
52
 
80
53
  return oidcCtx.interactionFinished({
@@ -0,0 +1,57 @@
1
+ import { OidcInteractionContext } from "@tsed/oidc-provider";
2
+ import { PromptDetail } from "oidc-provider";
3
+
4
+ export function getPromptDetailFixture(opts: Partial<PromptDetail> = {}): PromptDetail {
5
+ return {
6
+ details: {},
7
+ name: "login",
8
+ reasons: [],
9
+ ...opts
10
+ };
11
+ }
12
+
13
+ export function getOidcContextFixture(opts: Partial<OidcInteractionContext> = {}) {
14
+ const p = {
15
+ context: undefined,
16
+ env: undefined,
17
+ oidcInteractions: undefined,
18
+ oidcProvider: undefined,
19
+ raw: undefined,
20
+ debug: jest.fn(),
21
+ findAccount: jest.fn(),
22
+ findClient: jest.fn(),
23
+ getGrant: jest.fn(),
24
+ grantId: undefined,
25
+ checkInteractionName: jest.fn(),
26
+ checkClientId: jest.fn(),
27
+ interactionDetails: jest.fn().mockResolvedValue({}),
28
+ interactionFinished: jest.fn().mockResolvedValue(undefined),
29
+ interactionResult: jest.fn().mockResolvedValue(""),
30
+ interactionPrompt: jest.fn().mockImplementation((obj) => {
31
+ return {
32
+ client: {
33
+ client_id: "client_id"
34
+ },
35
+ ...obj,
36
+ details: p.prompt.details,
37
+ uid: p.uid,
38
+ params: {
39
+ ...p.params,
40
+ ...(obj.params || {})
41
+ }
42
+ };
43
+ }),
44
+ render: jest.fn(),
45
+ runInteraction: jest.fn(),
46
+ save: jest.fn(),
47
+ session: {},
48
+ params: {
49
+ client_id: "client_id"
50
+ },
51
+ uid: "uid",
52
+ ...opts,
53
+ prompt: getPromptDetailFixture(opts.prompt)
54
+ } as any;
55
+
56
+ return p;
57
+ }
@@ -4,7 +4,7 @@
4
4
  <div class="login-card">
5
5
  <h1><%= title %></h1>
6
6
 
7
- <%- include('forms/interaction-form.ejs') %>
7
+ <%- include('forms/consent-form.ejs') %>
8
8
 
9
9
  <%- include('partials/login-help.ejs') %>
10
10
  </div>
@@ -12,4 +12,4 @@
12
12
  <% include('partials/footer.ejs') %>
13
13
 
14
14
  </body>
15
- </html>
15
+ </html>