@acorex-platform/extension-sso-client 0.0.21

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.
@@ -0,0 +1,40 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, Component } from '@angular/core';
3
+
4
+ //#region ---- Azure AD logo (owned by SSO extension) ----
5
+ class AXESSOAzureAdLogoComponent {
6
+ constructor() {
7
+ this.appearance = input('colored', /* @ts-ignore */
8
+ ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
9
+ this.size = input(20, /* @ts-ignore */
10
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
11
+ }
12
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOAzureAdLogoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
13
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXESSOAzureAdLogoComponent, isStandalone: true, selector: "axe-sso-azure-ad-logo", inputs: { appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "inline-flex items-center justify-center" }, ngImport: i0, template: `
14
+ <svg [attr.width]="size()" [attr.height]="size()" viewBox="0 0 23 23" aria-hidden="true">
15
+ <path fill="#F35325" d="M1 1h10v10H1z" />
16
+ <path fill="#81BC06" d="M12 1h10v10H12z" />
17
+ <path fill="#05A6F0" d="M1 12h10v10H1z" />
18
+ <path fill="#FFBA08" d="M12 12h10v10H12z" />
19
+ </svg>
20
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.Eager }); }
21
+ }
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOAzureAdLogoComponent, decorators: [{
23
+ type: Component,
24
+ args: [{
25
+ selector: 'axe-sso-azure-ad-logo',
26
+ host: { class: 'inline-flex items-center justify-center' },
27
+ changeDetection: ChangeDetectionStrategy.Eager,
28
+ template: `
29
+ <svg [attr.width]="size()" [attr.height]="size()" viewBox="0 0 23 23" aria-hidden="true">
30
+ <path fill="#F35325" d="M1 1h10v10H1z" />
31
+ <path fill="#81BC06" d="M12 1h10v10H12z" />
32
+ <path fill="#05A6F0" d="M1 12h10v10H1z" />
33
+ <path fill="#FFBA08" d="M12 12h10v10H12z" />
34
+ </svg>
35
+ `,
36
+ }]
37
+ }], propDecorators: { appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
38
+
39
+ export { AXESSOAzureAdLogoComponent };
40
+ //# sourceMappingURL=acorex-platform-extension-sso-client-azure-ad-logo.component-Bt55e572.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-extension-sso-client-azure-ad-logo.component-Bt55e572.mjs","sources":["../../../../libs/extensions/sso/client/src/lib/brand/azure-ad-logo.component.ts"],"sourcesContent":["import type { AXPLogoAppearance } from '@acorex-platform/framework-client/core';\nimport { Component, input, ChangeDetectionStrategy } from '@angular/core';\n\n//#region ---- Azure AD logo (owned by SSO extension) ----\n\n@Component({\n selector: 'axe-sso-azure-ad-logo',\n host: { class: 'inline-flex items-center justify-center' },\n changeDetection: ChangeDetectionStrategy.Eager,\n template: `\n <svg [attr.width]=\"size()\" [attr.height]=\"size()\" viewBox=\"0 0 23 23\" aria-hidden=\"true\">\n <path fill=\"#F35325\" d=\"M1 1h10v10H1z\" />\n <path fill=\"#81BC06\" d=\"M12 1h10v10H12z\" />\n <path fill=\"#05A6F0\" d=\"M1 12h10v10H1z\" />\n <path fill=\"#FFBA08\" d=\"M12 12h10v10H12z\" />\n </svg>\n `,\n})\nexport class AXESSOAzureAdLogoComponent {\n appearance = input<AXPLogoAppearance>('colored');\n size = input(20);\n}\n\n//#endregion\n"],"names":[],"mappings":";;;AAGA;MAea,0BAA0B,CAAA;AAbvC,IAAA,WAAA,GAAA;QAcE,IAAA,CAAA,UAAU,GAAG,KAAK,CAAoB,SAAS;uFAAC;QAChD,IAAA,CAAA,IAAI,GAAG,KAAK,CAAC,EAAE;iFAAC;AACjB,IAAA;8GAHY,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA1B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,yCAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAT3B;;;;;;;AAOT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,KAAA,EAAA,CAAA,CAAA;;2FAEU,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAbtC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,uBAAuB;AACjC,oBAAA,IAAI,EAAE,EAAE,KAAK,EAAE,yCAAyC,EAAE;oBAC1D,eAAe,EAAE,uBAAuB,CAAC,KAAK;AAC9C,oBAAA,QAAQ,EAAE;;;;;;;AAOT,EAAA,CAAA;AACF,iBAAA;;;;;"}
@@ -0,0 +1,23 @@
1
+ //#region ---- Module Config ----
2
+ const config = {
3
+ i18n: 'extensions-sso',
4
+ module: 'sso-extension',
5
+ };
6
+ const RootConfig = {
7
+ config,
8
+ module: {
9
+ name: config.module,
10
+ icon: 'fa-solid fa-building-shield',
11
+ },
12
+ };
13
+ //#endregion
14
+
15
+ //#region ---- SSO provider definition ----
16
+ //#endregion
17
+
18
+ /**
19
+ * Generated bundle index. Do not edit.
20
+ */
21
+
22
+ export { RootConfig };
23
+ //# sourceMappingURL=acorex-platform-extension-sso-client-contracts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-extension-sso-client-contracts.mjs","sources":["../../../../libs/extensions/sso/contracts/src/root-config.ts","../../../../libs/extensions/sso/contracts/src/sso-provider.types.ts","../../../../libs/extensions/sso/contracts/src/acorex-platform-extension-sso-client-contracts.ts"],"sourcesContent":["//#region ---- Module Config ----\n\nconst config = {\n i18n: 'extensions-sso',\n module: 'sso-extension',\n};\n\nexport const RootConfig = {\n config,\n module: {\n name: config.module,\n icon: 'fa-solid fa-building-shield',\n },\n};\n\n//#endregion\n","//#region ---- SSO provider definition ----\n\nexport type AXESSOProviderProtocol = 'oidc' | 'saml';\n\n/** Enterprise IdP definition for SSO platform login (client + server). */\nexport interface AXESSOProviderDefinition {\n id: string;\n title: string;\n /** Optional Font Awesome icon class (client may override with extension-owned logo). */\n icon?: string;\n protocol: AXESSOProviderProtocol;\n /** Platform authorize path or full URL — extension resolves against API baseUrl. */\n authorizationPath?: string;\n /** Passed to platform OAuth as acr_values, e.g. 'okta-hr'. */\n acrValues: string;\n enabled?: boolean;\n /** Slot ordering (lower = higher on page). */\n priority?: number;\n}\n\n/** Runtime enablement entry returned by GET /v1/auth/providers. */\nexport interface AXESSOProviderStatus extends Pick<\n AXESSOProviderDefinition,\n 'id' | 'title' | 'icon' | 'protocol' | 'acrValues'\n> {\n enabled: boolean;\n}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAAA;AAEA,MAAM,MAAM,GAAG;AACb,IAAA,IAAI,EAAE,gBAAgB;AACtB,IAAA,MAAM,EAAE,eAAe;CACxB;AAEM,MAAM,UAAU,GAAG;IACxB,MAAM;AACN,IAAA,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC,MAAM;AACnB,QAAA,IAAI,EAAE,6BAA6B;AACpC,KAAA;;AAGH;;ACfA;AA4BA;;AC5BA;;AAEG;;;;"}
@@ -0,0 +1,50 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, Component } from '@angular/core';
3
+
4
+ //#region ---- Okta HR logo (owned by SSO extension) ----
5
+ class AXESSOOktaHrLogoComponent {
6
+ constructor() {
7
+ this.appearance = input('colored', /* @ts-ignore */
8
+ ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
9
+ this.size = input(20, /* @ts-ignore */
10
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
11
+ }
12
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOOktaHrLogoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
13
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXESSOOktaHrLogoComponent, isStandalone: true, selector: "axe-sso-okta-hr-logo", inputs: { appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "inline-flex items-center justify-center" }, ngImport: i0, template: `
14
+ <svg
15
+ [attr.width]="size()"
16
+ [attr.height]="size()"
17
+ viewBox="0 0 24 24"
18
+ [attr.fill]="appearance() === 'onDark' ? '#ffffff' : '#007DC1'"
19
+ aria-hidden="true"
20
+ >
21
+ <path
22
+ d="M3 21V3h8.5a4.5 4.5 0 0 1 0 9H6v9H3zm3-12h5.5a1.5 1.5 0 0 0 0-3H6v3zm13.2 9.6-1.8-3.1a4.8 4.8 0 0 0 1.9-3.8V6h-3v5.7a1.8 1.8 0 0 1-3.1 1.3l-4.7 8.1 2.6 1.5 3.3-5.7 3.3 5.7 2.6-1.5z"
23
+ />
24
+ </svg>
25
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.Eager }); }
26
+ }
27
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOOktaHrLogoComponent, decorators: [{
28
+ type: Component,
29
+ args: [{
30
+ selector: 'axe-sso-okta-hr-logo',
31
+ host: { class: 'inline-flex items-center justify-center' },
32
+ changeDetection: ChangeDetectionStrategy.Eager,
33
+ template: `
34
+ <svg
35
+ [attr.width]="size()"
36
+ [attr.height]="size()"
37
+ viewBox="0 0 24 24"
38
+ [attr.fill]="appearance() === 'onDark' ? '#ffffff' : '#007DC1'"
39
+ aria-hidden="true"
40
+ >
41
+ <path
42
+ d="M3 21V3h8.5a4.5 4.5 0 0 1 0 9H6v9H3zm3-12h5.5a1.5 1.5 0 0 0 0-3H6v3zm13.2 9.6-1.8-3.1a4.8 4.8 0 0 0 1.9-3.8V6h-3v5.7a1.8 1.8 0 0 1-3.1 1.3l-4.7 8.1 2.6 1.5 3.3-5.7 3.3 5.7 2.6-1.5z"
43
+ />
44
+ </svg>
45
+ `,
46
+ }]
47
+ }], propDecorators: { appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
48
+
49
+ export { AXESSOOktaHrLogoComponent };
50
+ //# sourceMappingURL=acorex-platform-extension-sso-client-okta-hr-logo.component-SI3O0UNU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-extension-sso-client-okta-hr-logo.component-SI3O0UNU.mjs","sources":["../../../../libs/extensions/sso/client/src/lib/brand/okta-hr-logo.component.ts"],"sourcesContent":["import type { AXPLogoAppearance } from '@acorex-platform/framework-client/core';\nimport { Component, input, ChangeDetectionStrategy } from '@angular/core';\n\n//#region ---- Okta HR logo (owned by SSO extension) ----\n\n@Component({\n selector: 'axe-sso-okta-hr-logo',\n host: { class: 'inline-flex items-center justify-center' },\n changeDetection: ChangeDetectionStrategy.Eager,\n template: `\n <svg\n [attr.width]=\"size()\"\n [attr.height]=\"size()\"\n viewBox=\"0 0 24 24\"\n [attr.fill]=\"appearance() === 'onDark' ? '#ffffff' : '#007DC1'\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M3 21V3h8.5a4.5 4.5 0 0 1 0 9H6v9H3zm3-12h5.5a1.5 1.5 0 0 0 0-3H6v3zm13.2 9.6-1.8-3.1a4.8 4.8 0 0 0 1.9-3.8V6h-3v5.7a1.8 1.8 0 0 1-3.1 1.3l-4.7 8.1 2.6 1.5 3.3-5.7 3.3 5.7 2.6-1.5z\"\n />\n </svg>\n `,\n})\nexport class AXESSOOktaHrLogoComponent {\n appearance = input<AXPLogoAppearance>('colored');\n size = input(20);\n}\n\n//#endregion\n"],"names":[],"mappings":";;;AAGA;MAoBa,yBAAyB,CAAA;AAlBtC,IAAA,WAAA,GAAA;QAmBE,IAAA,CAAA,UAAU,GAAG,KAAK,CAAoB,SAAS;uFAAC;QAChD,IAAA,CAAA,IAAI,GAAG,KAAK,CAAC,EAAE;iFAAC;AACjB,IAAA;8GAHY,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAzB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,yCAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAd1B;;;;;;;;;;;;AAYT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,KAAA,EAAA,CAAA,CAAA;;2FAEU,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAlBrC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sBAAsB;AAChC,oBAAA,IAAI,EAAE,EAAE,KAAK,EAAE,yCAAyC,EAAE;oBAC1D,eAAe,EAAE,uBAAuB,CAAC,KAAK;AAC9C,oBAAA,QAAQ,EAAE;;;;;;;;;;;;AAYT,EAAA,CAAA;AACF,iBAAA;;;;;"}
@@ -0,0 +1,96 @@
1
+ import * as i1 from '@acorex/components/button';
2
+ import { AXButtonModule } from '@acorex/components/button';
3
+ import * as i2 from '@acorex/components/decorators';
4
+ import { AXDecoratorModule } from '@acorex/components/decorators';
5
+ import * as i3 from '@acorex/components/loading';
6
+ import { AXLoadingModule } from '@acorex/components/loading';
7
+ import * as i4 from '@acorex/components/skeleton';
8
+ import { AXSkeletonModule } from '@acorex/components/skeleton';
9
+ import { AXToastService } from '@acorex/components/toast';
10
+ import { AXPSessionService } from '@acorex-platform/framework-client/auth';
11
+ import { AXPLogoRegistryService, axpSsoLogoKey, AXPLogoComponent } from '@acorex-platform/framework-client/core';
12
+ import { CommonModule } from '@angular/common';
13
+ import * as i0 from '@angular/core';
14
+ import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
15
+ import { AXESSOPlatformLoginAvailabilityService, axpCreateSsoLogoProvider } from './acorex-platform-extension-sso-client.mjs';
16
+
17
+ //#region ---- SSO platform login slot (server-driven list) ----
18
+ class AXESSOLoginSlotComponent {
19
+ constructor() {
20
+ //#region ----- Services & Dependencies -----
21
+ this.sessionService = inject(AXPSessionService);
22
+ this.toastService = inject(AXToastService);
23
+ this.ssoAvailability = inject(AXESSOPlatformLoginAvailabilityService);
24
+ this.logoRegistry = inject(AXPLogoRegistryService);
25
+ //#endregion
26
+ //#region ----- Constants -----
27
+ this.skeletonItems = [1, 2];
28
+ //#endregion
29
+ //#region ----- State Signals -----
30
+ this.isCatalogLoading = signal(true, /* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "isCatalogLoading" }] : /* istanbul ignore next */ []));
32
+ this.providers = signal([], /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "providers" }] : /* istanbul ignore next */ []));
34
+ this.loadingProviderId = signal(null, /* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "loadingProviderId" }] : /* istanbul ignore next */ []));
36
+ }
37
+ //#endregion
38
+ //#region ----- Lifecycle -----
39
+ async ngOnInit() {
40
+ try {
41
+ const enabled = await this.ssoAvailability.getEnabledProviders();
42
+ for (const provider of enabled) {
43
+ this.logoRegistry.register(axpCreateSsoLogoProvider(provider));
44
+ }
45
+ this.providers.set(enabled);
46
+ }
47
+ finally {
48
+ this.isCatalogLoading.set(false);
49
+ }
50
+ }
51
+ //#endregion
52
+ //#region ----- Event Handlers -----
53
+ logoKey(providerId) {
54
+ return axpSsoLogoKey(providerId);
55
+ }
56
+ isLoading(providerId) {
57
+ return this.loadingProviderId() === providerId;
58
+ }
59
+ async handleSsoSignIn(provider) {
60
+ this.loadingProviderId.set(provider.id);
61
+ try {
62
+ this.sessionService.setStrategy('sso');
63
+ await this.sessionService.signin({
64
+ strategy: 'sso',
65
+ acrValues: provider.acrValues,
66
+ });
67
+ }
68
+ catch (error) {
69
+ const message = error instanceof Error ? error.message : `${provider.title} sign-in failed.`;
70
+ this.toastService.show({
71
+ color: 'danger',
72
+ content: message,
73
+ timeOut: 6000,
74
+ });
75
+ }
76
+ finally {
77
+ this.loadingProviderId.set(null);
78
+ }
79
+ }
80
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOLoginSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
81
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXESSOLoginSlotComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "@if (isCatalogLoading()) {\n <!-- ----- Skeleton placeholders while Auth:ListProviders loads ----- -->\n <div class=\"w-full flex flex-col gap-2 mt-2\">\n @for (item of skeletonItems; track item) {\n <ax-skeleton [animated]=\"true\" class=\"w-full h-10 rounded-md\"></ax-skeleton>\n }\n </div>\n}\n<!-- ----- Server-enabled SSO IdP buttons ----- -->\n@else {\n @for (provider of providers(); track provider.id) {\n <ax-button\n class=\"w-full mt-2\"\n [text]=\"provider.title\"\n [color]=\"'default'\"\n [id]=\"'sso-' + provider.id\"\n (onClick)=\"handleSsoSignIn(provider)\"\n [disabled]=\"loadingProviderId() !== null\"\n >\n <ax-prefix>\n <axp-logo [logoKey]=\"logoKey(provider.id)\" appearance=\"colored\" [size]=\"20\" />\n </ax-prefix>\n @if (isLoading(provider.id)) {\n <!-- ----- Spinner while this IdP sign-in is in progress ----- -->\n <ax-loading></ax-loading>\n }\n </ax-button>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i3.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i4.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
82
+ }
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOLoginSlotComponent, decorators: [{
84
+ type: Component,
85
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, imports: [
86
+ CommonModule,
87
+ AXButtonModule,
88
+ AXDecoratorModule,
89
+ AXLoadingModule,
90
+ AXSkeletonModule,
91
+ AXPLogoComponent,
92
+ ], template: "@if (isCatalogLoading()) {\n <!-- ----- Skeleton placeholders while Auth:ListProviders loads ----- -->\n <div class=\"w-full flex flex-col gap-2 mt-2\">\n @for (item of skeletonItems; track item) {\n <ax-skeleton [animated]=\"true\" class=\"w-full h-10 rounded-md\"></ax-skeleton>\n }\n </div>\n}\n<!-- ----- Server-enabled SSO IdP buttons ----- -->\n@else {\n @for (provider of providers(); track provider.id) {\n <ax-button\n class=\"w-full mt-2\"\n [text]=\"provider.title\"\n [color]=\"'default'\"\n [id]=\"'sso-' + provider.id\"\n (onClick)=\"handleSsoSignIn(provider)\"\n [disabled]=\"loadingProviderId() !== null\"\n >\n <ax-prefix>\n <axp-logo [logoKey]=\"logoKey(provider.id)\" appearance=\"colored\" [size]=\"20\" />\n </ax-prefix>\n @if (isLoading(provider.id)) {\n <!-- ----- Spinner while this IdP sign-in is in progress ----- -->\n <ax-loading></ax-loading>\n }\n </ax-button>\n }\n}\n" }]
93
+ }] });
94
+
95
+ export { AXESSOLoginSlotComponent };
96
+ //# sourceMappingURL=acorex-platform-extension-sso-client-sso-login-slot.component-D5Ad7GHw.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-extension-sso-client-sso-login-slot.component-D5Ad7GHw.mjs","sources":["../../../../libs/extensions/sso/client/src/lib/platform-auth/sso-login-slot.component.ts","../../../../libs/extensions/sso/client/src/lib/platform-auth/sso-login-slot.component.html"],"sourcesContent":["import { AXButtonModule } from '@acorex/components/button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXSkeletonModule } from '@acorex/components/skeleton';\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXESSOProviderStatus } from '@acorex-platform/extension-sso-client/contracts';\nimport { AXPSessionService } from '@acorex-platform/framework-client/auth';\nimport { AXPLogoComponent, AXPLogoRegistryService, axpSsoLogoKey } from '@acorex-platform/framework-client/core';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n OnInit,\n inject,\n signal,\n} from '@angular/core';\nimport { axpCreateSsoLogoProvider } from '../brand/sso-logo-resolver';\nimport { AXESSOPlatformLoginAvailabilityService } from './sso-platform-login-availability.service';\n\n//#region ---- SSO platform login slot (server-driven list) ----\n\n@Component({\n templateUrl: './sso-login-slot.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n AXButtonModule,\n AXDecoratorModule,\n AXLoadingModule,\n AXSkeletonModule,\n AXPLogoComponent,\n ],\n})\nexport class AXESSOLoginSlotComponent implements OnInit {\n //#region ----- Services & Dependencies -----\n\n private readonly sessionService = inject(AXPSessionService);\n private readonly toastService = inject(AXToastService);\n private readonly ssoAvailability = inject(AXESSOPlatformLoginAvailabilityService);\n private readonly logoRegistry = inject(AXPLogoRegistryService);\n\n //#endregion\n\n //#region ----- Constants -----\n\n protected readonly skeletonItems = [1, 2];\n\n //#endregion\n\n //#region ----- State Signals -----\n\n protected readonly isCatalogLoading = signal(true);\n protected readonly providers = signal<AXESSOProviderStatus[]>([]);\n protected readonly loadingProviderId = signal<string | null>(null);\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n async ngOnInit(): Promise<void> {\n try {\n const enabled = await this.ssoAvailability.getEnabledProviders();\n for (const provider of enabled) {\n this.logoRegistry.register(axpCreateSsoLogoProvider(provider));\n }\n this.providers.set(enabled);\n } finally {\n this.isCatalogLoading.set(false);\n }\n }\n\n //#endregion\n\n //#region ----- Event Handlers -----\n\n protected logoKey(providerId: string): string {\n return axpSsoLogoKey(providerId);\n }\n\n protected isLoading(providerId: string): boolean {\n return this.loadingProviderId() === providerId;\n }\n\n protected async handleSsoSignIn(provider: AXESSOProviderStatus): Promise<void> {\n this.loadingProviderId.set(provider.id);\n try {\n this.sessionService.setStrategy('sso');\n await this.sessionService.signin({\n strategy: 'sso',\n acrValues: provider.acrValues,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : `${provider.title} sign-in failed.`;\n this.toastService.show({\n color: 'danger',\n content: message,\n timeOut: 6000,\n });\n } finally {\n this.loadingProviderId.set(null);\n }\n }\n\n //#endregion\n}\n\n//#endregion\n","@if (isCatalogLoading()) {\n <!-- ----- Skeleton placeholders while Auth:ListProviders loads ----- -->\n <div class=\"w-full flex flex-col gap-2 mt-2\">\n @for (item of skeletonItems; track item) {\n <ax-skeleton [animated]=\"true\" class=\"w-full h-10 rounded-md\"></ax-skeleton>\n }\n </div>\n}\n<!-- ----- Server-enabled SSO IdP buttons ----- -->\n@else {\n @for (provider of providers(); track provider.id) {\n <ax-button\n class=\"w-full mt-2\"\n [text]=\"provider.title\"\n [color]=\"'default'\"\n [id]=\"'sso-' + provider.id\"\n (onClick)=\"handleSsoSignIn(provider)\"\n [disabled]=\"loadingProviderId() !== null\"\n >\n <ax-prefix>\n <axp-logo [logoKey]=\"logoKey(provider.id)\" appearance=\"colored\" [size]=\"20\" />\n </ax-prefix>\n @if (isLoading(provider.id)) {\n <!-- ----- Spinner while this IdP sign-in is in progress ----- -->\n <ax-loading></ax-loading>\n }\n </ax-button>\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,346 @@
1
+ import * as i2 from '@acorex-platform/framework-client/auth';
2
+ import { AXPAuthStrategy, AXPSessionService, AXPPlatformAuthRuntimeService, resolvePlatformOAuthIssuer, resolvePlatformOAuthClientConfig, PkceUtil, toPlatformOAuthSignInResult, shouldPlatformOAuthBindSession, platformOAuthSessionUpdateParams, resolvePlatformOAuthTokenEndpoint, JwtUtil, TimeUtil, resolvePlatformOAuthAuthorizeEndpoint, AXPAuthModule } from '@acorex-platform/framework-client/auth';
3
+ import * as i1 from '@acorex-platform/framework-client/core';
4
+ import { axpSsoLogoKey } from '@acorex-platform/framework-client/core';
5
+ import { AXM_AUTH_CONFIG_TOKEN, AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT } from '@acorex-platform/module-auth-client';
6
+ import * as i0 from '@angular/core';
7
+ import { inject, Injectable, NgModule } from '@angular/core';
8
+
9
+ //#region ---- SSO platform auth strategy ----
10
+ const SSO_ACR_VALUES_STORAGE_KEY = 'sso_acr_values';
11
+ class AXESSOPlatformAuthStrategy extends AXPAuthStrategy {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.authConfigs = inject(AXM_AUTH_CONFIG_TOKEN);
15
+ this.sessionService = inject(AXPSessionService);
16
+ this.platformAuthRuntime = inject(AXPPlatformAuthRuntimeService);
17
+ }
18
+ get name() {
19
+ return 'sso';
20
+ }
21
+ resolveIssuer() {
22
+ return resolvePlatformOAuthIssuer(this.authConfigs.baseUrl);
23
+ }
24
+ resolveClientConfig() {
25
+ return resolvePlatformOAuthClientConfig(this.authConfigs.authConfig);
26
+ }
27
+ resolveAcrValues(credentials) {
28
+ const fromCredentials = credentials?.['acrValues']?.trim();
29
+ if (fromCredentials) {
30
+ localStorage.setItem(SSO_ACR_VALUES_STORAGE_KEY, fromCredentials);
31
+ return fromCredentials;
32
+ }
33
+ const stored = localStorage.getItem(SSO_ACR_VALUES_STORAGE_KEY)?.trim();
34
+ if (stored) {
35
+ return stored;
36
+ }
37
+ throw new Error('SSO provider (acr_values) is not specified');
38
+ }
39
+ async signin(credentials) {
40
+ const acrValues = this.resolveAcrValues(credentials);
41
+ await this.redirectToSsoPlatformAuthorize(acrValues);
42
+ }
43
+ async redirectToSsoPlatformAuthorize(acrValues) {
44
+ const issuer = this.resolveIssuer();
45
+ const { clientId, redirectUri, scope } = this.resolveClientConfig();
46
+ const codeVerifier = PkceUtil.generateRandomString(128);
47
+ localStorage.setItem('pkce_code_verifier', codeVerifier);
48
+ const codeChallenge = await PkceUtil.generateCodeChallenge(codeVerifier);
49
+ this.sessionService.setStrategy('sso');
50
+ const params = new URLSearchParams({
51
+ response_type: 'code',
52
+ client_id: clientId,
53
+ redirect_uri: redirectUri,
54
+ scope,
55
+ code_challenge: codeChallenge,
56
+ code_challenge_method: 'S256',
57
+ prompt: 'login',
58
+ acr_values: acrValues,
59
+ });
60
+ window.location.assign(`${issuer}/connect/authorize?${params.toString()}`);
61
+ await this.waitForOAuthRedirect();
62
+ }
63
+ async signout() {
64
+ localStorage.removeItem('pkce_code_verifier');
65
+ localStorage.removeItem('oauth_provider');
66
+ localStorage.removeItem(SSO_ACR_VALUES_STORAGE_KEY);
67
+ await this.platformAuthRuntime.logout();
68
+ }
69
+ async refreshToken(_context) {
70
+ try {
71
+ const authData = this.loadAuthData();
72
+ const tokenData = await this.platformAuthRuntime.refresh();
73
+ return toPlatformOAuthSignInResult(tokenData, {
74
+ user: tokenData.user,
75
+ tenant: authData?.tenant ?? null,
76
+ application: authData?.application ?? null,
77
+ });
78
+ }
79
+ catch (error) {
80
+ console.error('Error refreshing token', error);
81
+ return { succeed: false };
82
+ }
83
+ }
84
+ async updateToken(params) {
85
+ try {
86
+ if (params['code']) {
87
+ return this.exchangeAuthorizationCode(params);
88
+ }
89
+ if (shouldPlatformOAuthBindSession(this.sessionService.hasSessionCredentials(), params)) {
90
+ const { tenant, application, tenantId, applicationId } = platformOAuthSessionUpdateParams(params);
91
+ const result = await this.platformAuthRuntime.updateSession({
92
+ tenantId,
93
+ applicationId,
94
+ tenant,
95
+ application,
96
+ });
97
+ return toPlatformOAuthSignInResult(result, {
98
+ user: params['user'] ?? null,
99
+ tenant: tenant ?? null,
100
+ application: application ?? null,
101
+ });
102
+ }
103
+ return this.beginAuthorizationCodeFlow(params);
104
+ }
105
+ catch (error) {
106
+ console.error('Error in updateToken:', error);
107
+ throw error;
108
+ }
109
+ }
110
+ async exchangeAuthorizationCode(params) {
111
+ const code = params['code'];
112
+ const issuer = this.resolveIssuer();
113
+ const { clientId, redirectUri } = this.resolveClientConfig();
114
+ const resolvedRedirectUri = params['redirectUri'] || redirectUri;
115
+ const resolvedClientId = params['clientId'] || clientId;
116
+ const tokenEndpoint = resolvePlatformOAuthTokenEndpoint(issuer);
117
+ const codeVerifier = localStorage.getItem('pkce_code_verifier');
118
+ if (!codeVerifier) {
119
+ throw new Error('Code verifier not found. Please try signing in again.');
120
+ }
121
+ const body = new URLSearchParams({
122
+ grant_type: 'authorization_code',
123
+ client_id: resolvedClientId,
124
+ code_verifier: codeVerifier,
125
+ code,
126
+ redirect_uri: resolvedRedirectUri,
127
+ });
128
+ const response = await fetch(tokenEndpoint, {
129
+ method: 'POST',
130
+ credentials: 'include',
131
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
132
+ body: body.toString(),
133
+ });
134
+ if (!response.ok) {
135
+ const detail = await response.text().catch(() => '');
136
+ throw new Error(`Token exchange failed: ${response.status} ${response.statusText}${detail ? ` — ${detail}` : ''}`);
137
+ }
138
+ localStorage.removeItem('pkce_code_verifier');
139
+ const tokenData = await response.json();
140
+ const payload = JwtUtil.parseJwt(tokenData.id_token);
141
+ if (!payload) {
142
+ throw new Error('Payload not found');
143
+ }
144
+ const user = {
145
+ id: payload['sub'] || '',
146
+ title: payload['name'] || payload['email'] || '',
147
+ name: payload['name'] || payload['email'] || '',
148
+ avatar: payload['picture'] || '',
149
+ };
150
+ return {
151
+ succeed: true,
152
+ data: {
153
+ accessToken: tokenData.access_token ?? tokenData.accessToken,
154
+ refreshToken: tokenData.refresh_token ?? tokenData.refreshToken,
155
+ idToken: tokenData.id_token ?? null,
156
+ expiresIn: TimeUtil.calculateExpireInDate(tokenData.expires_in || 0),
157
+ user,
158
+ tenant: null,
159
+ application: null,
160
+ },
161
+ };
162
+ }
163
+ async beginAuthorizationCodeFlow(params) {
164
+ const issuer = this.resolveIssuer();
165
+ const acrValues = this.resolveAcrValues();
166
+ const tenantId = params['tenantId'] ?? params['tenant']?.id ?? null;
167
+ const applicationId = params['applicationId'] ?? params['application']?.id ?? null;
168
+ const { clientId, redirectUri, scope } = this.resolveClientConfig();
169
+ const resolvedRedirectUri = params['redirectUri'] || redirectUri;
170
+ const resolvedScope = params['scope'] || scope;
171
+ const codeVerifier = PkceUtil.generateRandomString(128);
172
+ localStorage.setItem('pkce_code_verifier', codeVerifier);
173
+ const codeChallenge = await PkceUtil.generateCodeChallenge(codeVerifier);
174
+ const authorizeEndpoint = resolvePlatformOAuthAuthorizeEndpoint(issuer);
175
+ const state = Math.random().toString(36).substring(2);
176
+ const queryParams = [
177
+ `response_type=code`,
178
+ `client_id=${encodeURIComponent(clientId)}`,
179
+ `redirect_uri=${encodeURIComponent(resolvedRedirectUri)}`,
180
+ `scope=${encodeURIComponent(resolvedScope)}`,
181
+ `state=${encodeURIComponent(state)}`,
182
+ tenantId ? `tenant_id=${encodeURIComponent(tenantId)}` : null,
183
+ applicationId ? `application_id=${encodeURIComponent(applicationId)}` : null,
184
+ `code_challenge=${encodeURIComponent(codeChallenge)}`,
185
+ `code_challenge_method=S256`,
186
+ `acr_values=${encodeURIComponent(acrValues)}`,
187
+ ]
188
+ .filter(Boolean)
189
+ .join('&');
190
+ window.location.href = `${authorizeEndpoint}?${queryParams}`;
191
+ await this.waitForOAuthRedirect();
192
+ return undefined;
193
+ }
194
+ waitForOAuthRedirect() {
195
+ return new Promise(() => { });
196
+ }
197
+ loadAuthData() {
198
+ return this.sessionService.getSessionData() || undefined;
199
+ }
200
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOPlatformAuthStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
201
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOPlatformAuthStrategy }); }
202
+ }
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOPlatformAuthStrategy, decorators: [{
204
+ type: Injectable
205
+ }] });
206
+
207
+ //#region ---- Constants ----
208
+ /** Built-in broker keys rendered by dedicated Google/Microsoft login slots. */
209
+ const BUILTIN_PLATFORM_IDP_KEYS = new Set(['google', 'microsoft']);
210
+ //#endregion
211
+ //#region ---- SSO platform login availability ----
212
+ /**
213
+ * Loads enterprise SSO IdPs from Auth:ListProviders (`identityProviders`).
214
+ * Excludes Google/Microsoft keys (those have dedicated login slots).
215
+ * `id` is passed through as OAuth `acr_values`.
216
+ */
217
+ class AXESSOPlatformLoginAvailabilityService {
218
+ constructor() {
219
+ this.platformAuthRuntime = inject(AXPPlatformAuthRuntimeService);
220
+ this.cachedProviders = null;
221
+ this.loadInFlight = null;
222
+ }
223
+ /** True when at least one server-enabled SSO IdP exists. */
224
+ async hasAnyEnabled() {
225
+ const providers = await this.getEnabledProviders();
226
+ return providers.length > 0;
227
+ }
228
+ async isEnabled(providerId) {
229
+ const providers = await this.getEnabledProviders();
230
+ return providers.some((provider) => provider.id === providerId);
231
+ }
232
+ /** Enabled SSO IdPs from the server (stable order from Auth:ListProviders). */
233
+ async getEnabledProviders() {
234
+ const all = await this.loadServerProviders();
235
+ return all.filter((provider) => provider.enabled === true);
236
+ }
237
+ async loadServerProviders() {
238
+ if (this.cachedProviders !== null) {
239
+ return this.cachedProviders;
240
+ }
241
+ if (this.loadInFlight) {
242
+ return this.loadInFlight;
243
+ }
244
+ this.loadInFlight = this.fetchProviders().finally(() => {
245
+ this.loadInFlight = null;
246
+ });
247
+ return this.loadInFlight;
248
+ }
249
+ async fetchProviders() {
250
+ try {
251
+ const payload = await this.platformAuthRuntime.listProviders();
252
+ this.cachedProviders = payload.identityProviders
253
+ .filter((p) => !BUILTIN_PLATFORM_IDP_KEYS.has(p.id))
254
+ .map((p) => ({
255
+ id: p.id,
256
+ title: p.title,
257
+ icon: p.icon,
258
+ protocol: 'oidc',
259
+ acrValues: p.id,
260
+ enabled: true,
261
+ }));
262
+ return this.cachedProviders;
263
+ }
264
+ catch {
265
+ this.cachedProviders = [];
266
+ return [];
267
+ }
268
+ }
269
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOPlatformLoginAvailabilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
270
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOPlatformLoginAvailabilityService }); }
271
+ }
272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOPlatformLoginAvailabilityService, decorators: [{
273
+ type: Injectable
274
+ }] });
275
+
276
+ //#region ---- Imports ----
277
+ //#endregion
278
+ //#region ---- Module ----
279
+ /**
280
+ * Enterprise SSO platform login — one slot host; IdP buttons come from Auth:ListProviders.
281
+ * Slot always mounts so the host can show a skeleton during the providers fetch.
282
+ */
283
+ class AXESSOExtensionModule {
284
+ constructor(registry) {
285
+ registry.register(AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT, {
286
+ name: 'sso-platform-login',
287
+ priority: 20,
288
+ loadComponent: () => import('./acorex-platform-extension-sso-client-sso-login-slot.component-D5Ad7GHw.mjs').then((component) => component.AXESSOLoginSlotComponent),
289
+ });
290
+ }
291
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOExtensionModule, deps: [{ token: i1.AXPComponentSlotRegistryService }], target: i0.ɵɵFactoryTarget.NgModule }); }
292
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXESSOExtensionModule, imports: [i2.AXPAuthModule] }); }
293
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOExtensionModule, providers: [AXESSOPlatformLoginAvailabilityService], imports: [AXPAuthModule.forChild({ strategies: [AXESSOPlatformAuthStrategy] })] }); }
294
+ }
295
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESSOExtensionModule, decorators: [{
296
+ type: NgModule,
297
+ args: [{
298
+ imports: [AXPAuthModule.forChild({ strategies: [AXESSOPlatformAuthStrategy] })],
299
+ providers: [AXESSOPlatformLoginAvailabilityService],
300
+ }]
301
+ }], ctorParameters: () => [{ type: i1.AXPComponentSlotRegistryService }] });
302
+
303
+ //#region ---- SSO logo resolution (convention + server icon fallback) ----
304
+ const SSO_LOGO_COMPONENT_LOADERS = {
305
+ 'okta-hr': () => import('./acorex-platform-extension-sso-client-okta-hr-logo.component-SI3O0UNU.mjs').then((module) => module.AXESSOOktaHrLogoComponent),
306
+ 'azure-ad-corp': () => import('./acorex-platform-extension-sso-client-azure-ad-logo.component-Bt55e572.mjs').then((module) => module.AXESSOAzureAdLogoComponent),
307
+ };
308
+ async function axpResolveSsoLogo(provider, request) {
309
+ const loader = SSO_LOGO_COMPONENT_LOADERS[provider.id];
310
+ if (loader) {
311
+ return {
312
+ kind: 'component',
313
+ load: loader,
314
+ inputs: {
315
+ appearance: request.appearance,
316
+ size: request.size,
317
+ },
318
+ };
319
+ }
320
+ if (provider.icon) {
321
+ return {
322
+ kind: 'icon',
323
+ icon: provider.icon,
324
+ color: 'neutral-600',
325
+ };
326
+ }
327
+ return {
328
+ kind: 'icon',
329
+ icon: 'fa-solid fa-building',
330
+ color: 'neutral-500',
331
+ };
332
+ }
333
+ function axpCreateSsoLogoProvider(provider) {
334
+ return {
335
+ key: axpSsoLogoKey(provider.id),
336
+ resolve: (request) => axpResolveSsoLogo(provider, request),
337
+ };
338
+ }
339
+ //#endregion
340
+
341
+ /**
342
+ * Generated bundle index. Do not edit.
343
+ */
344
+
345
+ export { AXESSOExtensionModule, AXESSOPlatformAuthStrategy, AXESSOPlatformLoginAvailabilityService, axpCreateSsoLogoProvider, axpResolveSsoLogo };
346
+ //# sourceMappingURL=acorex-platform-extension-sso-client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-extension-sso-client.mjs","sources":["../../../../libs/extensions/sso/client/src/lib/platform-auth/sso-platform-auth.strategy.ts","../../../../libs/extensions/sso/client/src/lib/platform-auth/sso-platform-login-availability.service.ts","../../../../libs/extensions/sso/client/src/lib/sso-extension.module.ts","../../../../libs/extensions/sso/client/src/lib/brand/sso-logo-resolver.ts","../../../../libs/extensions/sso/client/src/acorex-platform-extension-sso-client.ts"],"sourcesContent":["import { AXM_AUTH_CONFIG_TOKEN, AXMAuthConfigs } from '@acorex-platform/module-auth-client';\nimport {\n AXPAuthStrategy,\n AXPBaseCredentials,\n AXPPlatformAuthRuntimeService,\n AXPSessionContext,\n AXPSessionData,\n AXPSessionService,\n AXPSignInResult,\n AXPUser,\n JwtUtil,\n PkceUtil,\n platformOAuthSessionUpdateParams,\n resolvePlatformOAuthAuthorizeEndpoint,\n resolvePlatformOAuthClientConfig,\n resolvePlatformOAuthIssuer,\n resolvePlatformOAuthTokenEndpoint,\n shouldPlatformOAuthBindSession,\n TimeUtil,\n toPlatformOAuthSignInResult,\n} from '@acorex-platform/framework-client/auth';\nimport { inject, Injectable } from '@angular/core';\n\n//#region ---- SSO platform auth strategy ----\n\nconst SSO_ACR_VALUES_STORAGE_KEY = 'sso_acr_values';\n\n@Injectable()\nexport class AXESSOPlatformAuthStrategy extends AXPAuthStrategy {\n private readonly authConfigs: AXMAuthConfigs = inject(AXM_AUTH_CONFIG_TOKEN);\n private readonly sessionService = inject(AXPSessionService);\n private readonly platformAuthRuntime = inject(AXPPlatformAuthRuntimeService);\n\n get name(): string {\n return 'sso';\n }\n\n private resolveIssuer(): string {\n return resolvePlatformOAuthIssuer(this.authConfigs.baseUrl);\n }\n\n private resolveClientConfig() {\n return resolvePlatformOAuthClientConfig(this.authConfigs.authConfig);\n }\n\n private resolveAcrValues(credentials?: AXPBaseCredentials): string {\n const fromCredentials = credentials?.['acrValues']?.trim();\n if (fromCredentials) {\n localStorage.setItem(SSO_ACR_VALUES_STORAGE_KEY, fromCredentials);\n return fromCredentials;\n }\n\n const stored = localStorage.getItem(SSO_ACR_VALUES_STORAGE_KEY)?.trim();\n if (stored) {\n return stored;\n }\n\n throw new Error('SSO provider (acr_values) is not specified');\n }\n\n override async signin(credentials: AXPBaseCredentials): Promise<void> {\n const acrValues = this.resolveAcrValues(credentials);\n await this.redirectToSsoPlatformAuthorize(acrValues);\n }\n\n private async redirectToSsoPlatformAuthorize(acrValues: string): Promise<void> {\n const issuer = this.resolveIssuer();\n const { clientId, redirectUri, scope } = this.resolveClientConfig();\n\n const codeVerifier = PkceUtil.generateRandomString(128);\n localStorage.setItem('pkce_code_verifier', codeVerifier);\n const codeChallenge = await PkceUtil.generateCodeChallenge(codeVerifier);\n\n this.sessionService.setStrategy('sso');\n\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: clientId,\n redirect_uri: redirectUri,\n scope,\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n prompt: 'login',\n acr_values: acrValues,\n });\n\n window.location.assign(`${issuer}/connect/authorize?${params.toString()}`);\n await this.waitForOAuthRedirect();\n }\n\n async signout(): Promise<void> {\n localStorage.removeItem('pkce_code_verifier');\n localStorage.removeItem('oauth_provider');\n localStorage.removeItem(SSO_ACR_VALUES_STORAGE_KEY);\n await this.platformAuthRuntime.logout();\n }\n\n async refreshToken(_context: AXPSessionContext): Promise<AXPSignInResult> {\n try {\n const authData = this.loadAuthData();\n const tokenData = await this.platformAuthRuntime.refresh();\n return toPlatformOAuthSignInResult(tokenData, {\n user: tokenData.user,\n tenant: authData?.tenant ?? null,\n application: authData?.application ?? null,\n });\n } catch (error) {\n console.error('Error refreshing token', error);\n return { succeed: false };\n }\n }\n\n override async updateToken(params: { [key: string]: any }): Promise<AXPSignInResult | undefined> {\n try {\n if (params['code']) {\n return this.exchangeAuthorizationCode(params);\n }\n\n if (shouldPlatformOAuthBindSession(this.sessionService.hasSessionCredentials(), params)) {\n const { tenant, application, tenantId, applicationId } = platformOAuthSessionUpdateParams(params);\n const result = await this.platformAuthRuntime.updateSession({\n tenantId,\n applicationId,\n tenant,\n application,\n });\n return toPlatformOAuthSignInResult(result, {\n user: (params['user'] as AXPUser) ?? null,\n tenant: tenant ?? null,\n application: application ?? null,\n });\n }\n\n return this.beginAuthorizationCodeFlow(params);\n } catch (error) {\n console.error('Error in updateToken:', error);\n throw error;\n }\n }\n\n private async exchangeAuthorizationCode(params: { [key: string]: any }): Promise<AXPSignInResult> {\n const code = params['code'];\n const issuer = this.resolveIssuer();\n const { clientId, redirectUri } = this.resolveClientConfig();\n const resolvedRedirectUri = params['redirectUri'] || redirectUri;\n const resolvedClientId = params['clientId'] || clientId;\n const tokenEndpoint = resolvePlatformOAuthTokenEndpoint(issuer);\n\n const codeVerifier = localStorage.getItem('pkce_code_verifier');\n if (!codeVerifier) {\n throw new Error('Code verifier not found. Please try signing in again.');\n }\n\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: resolvedClientId,\n code_verifier: codeVerifier,\n code,\n redirect_uri: resolvedRedirectUri,\n });\n\n const response = await fetch(tokenEndpoint, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n });\n\n if (!response.ok) {\n const detail = await response.text().catch(() => '');\n throw new Error(\n `Token exchange failed: ${response.status} ${response.statusText}${detail ? ` — ${detail}` : ''}`,\n );\n }\n\n localStorage.removeItem('pkce_code_verifier');\n\n const tokenData = await response.json();\n const payload = JwtUtil.parseJwt(tokenData.id_token);\n if (!payload) {\n throw new Error('Payload not found');\n }\n\n const user = {\n id: payload['sub'] || '',\n title: payload['name'] || payload['email'] || '',\n name: payload['name'] || payload['email'] || '',\n avatar: payload['picture'] || '',\n } as AXPUser;\n\n return {\n succeed: true,\n data: {\n accessToken: tokenData.access_token ?? tokenData.accessToken,\n refreshToken: tokenData.refresh_token ?? tokenData.refreshToken,\n idToken: tokenData.id_token ?? null,\n expiresIn: TimeUtil.calculateExpireInDate(tokenData.expires_in || 0),\n user,\n tenant: null,\n application: null,\n },\n };\n }\n\n private async beginAuthorizationCodeFlow(params: { [key: string]: any }): Promise<undefined> {\n const issuer = this.resolveIssuer();\n const acrValues = this.resolveAcrValues();\n const tenantId = params['tenantId'] ?? params['tenant']?.id ?? null;\n const applicationId = params['applicationId'] ?? params['application']?.id ?? null;\n const { clientId, redirectUri, scope } = this.resolveClientConfig();\n const resolvedRedirectUri = params['redirectUri'] || redirectUri;\n const resolvedScope = params['scope'] || scope;\n\n const codeVerifier = PkceUtil.generateRandomString(128);\n localStorage.setItem('pkce_code_verifier', codeVerifier);\n const codeChallenge = await PkceUtil.generateCodeChallenge(codeVerifier);\n\n const authorizeEndpoint = resolvePlatformOAuthAuthorizeEndpoint(issuer);\n const state = Math.random().toString(36).substring(2);\n\n const queryParams = [\n `response_type=code`,\n `client_id=${encodeURIComponent(clientId)}`,\n `redirect_uri=${encodeURIComponent(resolvedRedirectUri)}`,\n `scope=${encodeURIComponent(resolvedScope)}`,\n `state=${encodeURIComponent(state)}`,\n tenantId ? `tenant_id=${encodeURIComponent(tenantId)}` : null,\n applicationId ? `application_id=${encodeURIComponent(applicationId)}` : null,\n `code_challenge=${encodeURIComponent(codeChallenge)}`,\n `code_challenge_method=S256`,\n `acr_values=${encodeURIComponent(acrValues)}`,\n ]\n .filter(Boolean)\n .join('&');\n\n window.location.href = `${authorizeEndpoint}?${queryParams}`;\n await this.waitForOAuthRedirect();\n\n return undefined;\n }\n\n private waitForOAuthRedirect(): Promise<void> {\n return new Promise<void>(() => {});\n }\n\n private loadAuthData(): AXPSessionData | undefined {\n return this.sessionService.getSessionData() || undefined;\n }\n}\n\n//#endregion\n","import { AXPPlatformAuthRuntimeService } from '@acorex-platform/framework-client/auth';\nimport { AXESSOProviderStatus } from '@acorex-platform/extension-sso-client/contracts';\nimport { Injectable, inject } from '@angular/core';\n\n//#region ---- Constants ----\n\n/** Built-in broker keys rendered by dedicated Google/Microsoft login slots. */\nconst BUILTIN_PLATFORM_IDP_KEYS = new Set(['google', 'microsoft']);\n\n//#endregion\n\n//#region ---- SSO platform login availability ----\n\n/**\n * Loads enterprise SSO IdPs from Auth:ListProviders (`identityProviders`).\n * Excludes Google/Microsoft keys (those have dedicated login slots).\n * `id` is passed through as OAuth `acr_values`.\n */\n@Injectable()\nexport class AXESSOPlatformLoginAvailabilityService {\n private readonly platformAuthRuntime = inject(AXPPlatformAuthRuntimeService);\n private cachedProviders: AXESSOProviderStatus[] | null = null;\n private loadInFlight: Promise<AXESSOProviderStatus[]> | null = null;\n\n /** True when at least one server-enabled SSO IdP exists. */\n async hasAnyEnabled(): Promise<boolean> {\n const providers = await this.getEnabledProviders();\n return providers.length > 0;\n }\n\n async isEnabled(providerId: string): Promise<boolean> {\n const providers = await this.getEnabledProviders();\n return providers.some((provider) => provider.id === providerId);\n }\n\n /** Enabled SSO IdPs from the server (stable order from Auth:ListProviders). */\n async getEnabledProviders(): Promise<AXESSOProviderStatus[]> {\n const all = await this.loadServerProviders();\n return all.filter((provider) => provider.enabled === true);\n }\n\n private async loadServerProviders(): Promise<AXESSOProviderStatus[]> {\n if (this.cachedProviders !== null) {\n return this.cachedProviders;\n }\n if (this.loadInFlight) {\n return this.loadInFlight;\n }\n\n this.loadInFlight = this.fetchProviders().finally(() => {\n this.loadInFlight = null;\n });\n return this.loadInFlight;\n }\n\n private async fetchProviders(): Promise<AXESSOProviderStatus[]> {\n try {\n const payload = await this.platformAuthRuntime.listProviders();\n this.cachedProviders = payload.identityProviders\n .filter((p) => !BUILTIN_PLATFORM_IDP_KEYS.has(p.id))\n .map((p) => ({\n id: p.id,\n title: p.title,\n icon: p.icon,\n protocol: 'oidc' as const,\n acrValues: p.id,\n enabled: true,\n }));\n return this.cachedProviders;\n } catch {\n this.cachedProviders = [];\n return [];\n }\n }\n}\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { AXPAuthModule } from '@acorex-platform/framework-client/auth';\nimport { AXPComponentSlotRegistryService } from '@acorex-platform/framework-client/core';\nimport { AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT } from '@acorex-platform/module-auth-client';\nimport { NgModule } from '@angular/core';\nimport { AXESSOPlatformAuthStrategy } from './platform-auth/sso-platform-auth.strategy';\nimport { AXESSOPlatformLoginAvailabilityService } from './platform-auth/sso-platform-login-availability.service';\n\n//#endregion\n\n//#region ---- Module ----\n\n/**\n * Enterprise SSO platform login — one slot host; IdP buttons come from Auth:ListProviders.\n * Slot always mounts so the host can show a skeleton during the providers fetch.\n */\n@NgModule({\n imports: [AXPAuthModule.forChild({ strategies: [AXESSOPlatformAuthStrategy] })],\n providers: [AXESSOPlatformLoginAvailabilityService],\n})\nexport class AXESSOExtensionModule {\n constructor(registry: AXPComponentSlotRegistryService) {\n registry.register(AUTH_LOGIN_EXTERNAL_PROVIDERS_SLOT, {\n name: 'sso-platform-login',\n priority: 20,\n loadComponent: () =>\n import('./platform-auth/sso-login-slot.component').then((component) => component.AXESSOLoginSlotComponent),\n });\n }\n}\n\n//#endregion\n","import type { AXESSOProviderStatus } from '@acorex-platform/extension-sso-client/contracts';\nimport type { Type } from '@angular/core';\nimport {\n axpSsoLogoKey,\n type AXPLogoRequest,\n type AXPLogoView,\n} from '@acorex-platform/framework-client/core';\n\n//#region ---- SSO logo resolution (convention + server icon fallback) ----\n\nconst SSO_LOGO_COMPONENT_LOADERS: Record<string, () => Promise<Type<unknown>>> = {\n 'okta-hr': () => import('./okta-hr-logo.component').then((module) => module.AXESSOOktaHrLogoComponent),\n 'azure-ad-corp': () =>\n import('./azure-ad-logo.component').then((module) => module.AXESSOAzureAdLogoComponent),\n};\n\nexport async function axpResolveSsoLogo(\n provider: Pick<AXESSOProviderStatus, 'id' | 'icon'>,\n request: AXPLogoRequest,\n): Promise<AXPLogoView> {\n const loader = SSO_LOGO_COMPONENT_LOADERS[provider.id];\n if (loader) {\n return {\n kind: 'component',\n load: loader,\n inputs: {\n appearance: request.appearance,\n size: request.size,\n },\n };\n }\n\n if (provider.icon) {\n return {\n kind: 'icon',\n icon: provider.icon,\n color: 'neutral-600',\n };\n }\n\n return {\n kind: 'icon',\n icon: 'fa-solid fa-building',\n color: 'neutral-500',\n };\n}\n\nexport function axpCreateSsoLogoProvider(provider: Pick<AXESSOProviderStatus, 'id' | 'icon'>) {\n return {\n key: axpSsoLogoKey(provider.id),\n resolve: (request: AXPLogoRequest) => axpResolveSsoLogo(provider, request),\n };\n}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@acorex-platform/extension-sso-client",
3
+ "version": "0.0.21",
4
+ "sideEffects": false,
5
+ "peerDependencies": {
6
+ "@angular/common": "^21.0.0",
7
+ "@angular/core": "^21.0.0"
8
+ },
9
+ "dependencies": {
10
+ "tslib": "^2.3.0"
11
+ },
12
+ "module": "fesm2022/acorex-platform-extension-sso-client.mjs",
13
+ "typings": "types/acorex-platform-extension-sso-client.d.ts",
14
+ "exports": {
15
+ "./package.json": {
16
+ "default": "./package.json"
17
+ },
18
+ ".": {
19
+ "types": "./types/acorex-platform-extension-sso-client.d.ts",
20
+ "default": "./fesm2022/acorex-platform-extension-sso-client.mjs"
21
+ },
22
+ "./contracts": {
23
+ "types": "./types/acorex-platform-extension-sso-client-contracts.d.ts",
24
+ "default": "./fesm2022/acorex-platform-extension-sso-client-contracts.mjs"
25
+ }
26
+ },
27
+ "type": "module"
28
+ }
@@ -0,0 +1,34 @@
1
+ declare const RootConfig: {
2
+ config: {
3
+ i18n: string;
4
+ module: string;
5
+ };
6
+ module: {
7
+ name: string;
8
+ icon: string;
9
+ };
10
+ };
11
+
12
+ type AXESSOProviderProtocol = 'oidc' | 'saml';
13
+ /** Enterprise IdP definition for SSO platform login (client + server). */
14
+ interface AXESSOProviderDefinition {
15
+ id: string;
16
+ title: string;
17
+ /** Optional Font Awesome icon class (client may override with extension-owned logo). */
18
+ icon?: string;
19
+ protocol: AXESSOProviderProtocol;
20
+ /** Platform authorize path or full URL — extension resolves against API baseUrl. */
21
+ authorizationPath?: string;
22
+ /** Passed to platform OAuth as acr_values, e.g. 'okta-hr'. */
23
+ acrValues: string;
24
+ enabled?: boolean;
25
+ /** Slot ordering (lower = higher on page). */
26
+ priority?: number;
27
+ }
28
+ /** Runtime enablement entry returned by GET /v1/auth/providers. */
29
+ interface AXESSOProviderStatus extends Pick<AXESSOProviderDefinition, 'id' | 'title' | 'icon' | 'protocol' | 'acrValues'> {
30
+ enabled: boolean;
31
+ }
32
+
33
+ export { RootConfig };
34
+ export type { AXESSOProviderDefinition, AXESSOProviderProtocol, AXESSOProviderStatus };
@@ -0,0 +1,67 @@
1
+ import { AXPComponentSlotRegistryService, AXPLogoRequest, AXPLogoView } from '@acorex-platform/framework-client/core';
2
+ import * as i0 from '@angular/core';
3
+ import * as i1 from '@acorex-platform/framework-client/auth';
4
+ import { AXPAuthStrategy, AXPBaseCredentials, AXPSessionContext, AXPSignInResult } from '@acorex-platform/framework-client/auth';
5
+ import { AXESSOProviderStatus } from '@acorex-platform/extension-sso-client/contracts';
6
+
7
+ /**
8
+ * Enterprise SSO platform login — one slot host; IdP buttons come from Auth:ListProviders.
9
+ * Slot always mounts so the host can show a skeleton during the providers fetch.
10
+ */
11
+ declare class AXESSOExtensionModule {
12
+ constructor(registry: AXPComponentSlotRegistryService);
13
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXESSOExtensionModule, never>;
14
+ static ɵmod: i0.ɵɵNgModuleDeclaration<AXESSOExtensionModule, never, [typeof i1.AXPAuthModule], never>;
15
+ static ɵinj: i0.ɵɵInjectorDeclaration<AXESSOExtensionModule>;
16
+ }
17
+
18
+ declare class AXESSOPlatformAuthStrategy extends AXPAuthStrategy {
19
+ private readonly authConfigs;
20
+ private readonly sessionService;
21
+ private readonly platformAuthRuntime;
22
+ get name(): string;
23
+ private resolveIssuer;
24
+ private resolveClientConfig;
25
+ private resolveAcrValues;
26
+ signin(credentials: AXPBaseCredentials): Promise<void>;
27
+ private redirectToSsoPlatformAuthorize;
28
+ signout(): Promise<void>;
29
+ refreshToken(_context: AXPSessionContext): Promise<AXPSignInResult>;
30
+ updateToken(params: {
31
+ [key: string]: any;
32
+ }): Promise<AXPSignInResult | undefined>;
33
+ private exchangeAuthorizationCode;
34
+ private beginAuthorizationCodeFlow;
35
+ private waitForOAuthRedirect;
36
+ private loadAuthData;
37
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXESSOPlatformAuthStrategy, never>;
38
+ static ɵprov: i0.ɵɵInjectableDeclaration<AXESSOPlatformAuthStrategy>;
39
+ }
40
+
41
+ /**
42
+ * Loads enterprise SSO IdPs from Auth:ListProviders (`identityProviders`).
43
+ * Excludes Google/Microsoft keys (those have dedicated login slots).
44
+ * `id` is passed through as OAuth `acr_values`.
45
+ */
46
+ declare class AXESSOPlatformLoginAvailabilityService {
47
+ private readonly platformAuthRuntime;
48
+ private cachedProviders;
49
+ private loadInFlight;
50
+ /** True when at least one server-enabled SSO IdP exists. */
51
+ hasAnyEnabled(): Promise<boolean>;
52
+ isEnabled(providerId: string): Promise<boolean>;
53
+ /** Enabled SSO IdPs from the server (stable order from Auth:ListProviders). */
54
+ getEnabledProviders(): Promise<AXESSOProviderStatus[]>;
55
+ private loadServerProviders;
56
+ private fetchProviders;
57
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXESSOPlatformLoginAvailabilityService, never>;
58
+ static ɵprov: i0.ɵɵInjectableDeclaration<AXESSOPlatformLoginAvailabilityService>;
59
+ }
60
+
61
+ declare function axpResolveSsoLogo(provider: Pick<AXESSOProviderStatus, 'id' | 'icon'>, request: AXPLogoRequest): Promise<AXPLogoView>;
62
+ declare function axpCreateSsoLogoProvider(provider: Pick<AXESSOProviderStatus, 'id' | 'icon'>): {
63
+ key: string;
64
+ resolve: (request: AXPLogoRequest) => Promise<AXPLogoView>;
65
+ };
66
+
67
+ export { AXESSOExtensionModule, AXESSOPlatformAuthStrategy, AXESSOPlatformLoginAvailabilityService, axpCreateSsoLogoProvider, axpResolveSsoLogo };