@portaidentity/cli 1.7.3 → 1.8.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.
- package/CHANGELOG.md +5 -0
- package/README.md +125 -105
- package/dist/admin/admin-date-time.d.ts +6 -0
- package/dist/admin/admin-date-time.d.ts.map +1 -0
- package/dist/admin/admin-date-time.js +33 -0
- package/dist/admin/admin-date-time.js.map +1 -0
- package/dist/admin/application-client-features.d.ts +38 -0
- package/dist/admin/application-client-features.d.ts.map +1 -0
- package/dist/admin/application-client-features.js +545 -0
- package/dist/admin/application-client-features.js.map +1 -0
- package/dist/admin/application-controller.d.ts +58 -0
- package/dist/admin/application-controller.d.ts.map +1 -0
- package/dist/admin/application-controller.js +286 -0
- package/dist/admin/application-controller.js.map +1 -0
- package/dist/admin/application-dialogs.d.ts +91 -0
- package/dist/admin/application-dialogs.d.ts.map +1 -0
- package/dist/admin/application-dialogs.js +250 -0
- package/dist/admin/application-dialogs.js.map +1 -0
- package/dist/admin/application-rbac-controller.d.ts +56 -0
- package/dist/admin/application-rbac-controller.d.ts.map +1 -0
- package/dist/admin/application-rbac-controller.js +280 -0
- package/dist/admin/application-rbac-controller.js.map +1 -0
- package/dist/admin/application-rbac-features.d.ts +51 -0
- package/dist/admin/application-rbac-features.d.ts.map +1 -0
- package/dist/admin/application-rbac-features.js +175 -0
- package/dist/admin/application-rbac-features.js.map +1 -0
- package/dist/admin/application-rbac-workspace.d.ts +62 -0
- package/dist/admin/application-rbac-workspace.d.ts.map +1 -0
- package/dist/admin/application-rbac-workspace.js +344 -0
- package/dist/admin/application-rbac-workspace.js.map +1 -0
- package/dist/admin/application-runtime.d.ts +44 -0
- package/dist/admin/application-runtime.d.ts.map +1 -0
- package/dist/admin/application-runtime.js +183 -0
- package/dist/admin/application-runtime.js.map +1 -0
- package/dist/admin/application-service.d.ts +39 -0
- package/dist/admin/application-service.d.ts.map +1 -0
- package/dist/admin/application-service.js +248 -0
- package/dist/admin/application-service.js.map +1 -0
- package/dist/admin/application-state.d.ts +109 -0
- package/dist/admin/application-state.d.ts.map +1 -0
- package/dist/admin/application-state.js +3 -0
- package/dist/admin/application-state.js.map +1 -0
- package/dist/admin/application-workspace.d.ts +77 -0
- package/dist/admin/application-workspace.d.ts.map +1 -0
- package/dist/admin/application-workspace.js +302 -0
- package/dist/admin/application-workspace.js.map +1 -0
- package/dist/admin/application.d.ts +88 -0
- package/dist/admin/application.d.ts.map +1 -0
- package/dist/admin/application.js +932 -0
- package/dist/admin/application.js.map +1 -0
- package/dist/admin/client-authentication-dialog.d.ts +77 -0
- package/dist/admin/client-authentication-dialog.d.ts.map +1 -0
- package/dist/admin/client-authentication-dialog.js +217 -0
- package/dist/admin/client-authentication-dialog.js.map +1 -0
- package/dist/admin/client-controller.d.ts +58 -0
- package/dist/admin/client-controller.d.ts.map +1 -0
- package/dist/admin/client-controller.js +462 -0
- package/dist/admin/client-controller.js.map +1 -0
- package/dist/admin/client-credential-dialogs.d.ts +36 -0
- package/dist/admin/client-credential-dialogs.d.ts.map +1 -0
- package/dist/admin/client-credential-dialogs.js +145 -0
- package/dist/admin/client-credential-dialogs.js.map +1 -0
- package/dist/admin/client-dialogs.d.ts +64 -0
- package/dist/admin/client-dialogs.d.ts.map +1 -0
- package/dist/admin/client-dialogs.js +110 -0
- package/dist/admin/client-dialogs.js.map +1 -0
- package/dist/admin/client-form-scroller.d.ts +17 -0
- package/dist/admin/client-form-scroller.d.ts.map +1 -0
- package/dist/admin/client-form-scroller.js +67 -0
- package/dist/admin/client-form-scroller.js.map +1 -0
- package/dist/admin/client-registration-dialog.d.ts +27 -0
- package/dist/admin/client-registration-dialog.d.ts.map +1 -0
- package/dist/admin/client-registration-dialog.js +195 -0
- package/dist/admin/client-registration-dialog.js.map +1 -0
- package/dist/admin/client-service.d.ts +41 -0
- package/dist/admin/client-service.d.ts.map +1 -0
- package/dist/admin/client-service.js +484 -0
- package/dist/admin/client-service.js.map +1 -0
- package/dist/admin/client-state.d.ts +157 -0
- package/dist/admin/client-state.d.ts.map +1 -0
- package/dist/admin/client-state.js +3 -0
- package/dist/admin/client-state.js.map +1 -0
- package/dist/admin/client-workspace.d.ts +88 -0
- package/dist/admin/client-workspace.d.ts.map +1 -0
- package/dist/admin/client-workspace.js +484 -0
- package/dist/admin/client-workspace.js.map +1 -0
- package/dist/admin/delete-confirmation-layout.d.ts +38 -0
- package/dist/admin/delete-confirmation-layout.d.ts.map +1 -0
- package/dist/admin/delete-confirmation-layout.js +52 -0
- package/dist/admin/delete-confirmation-layout.js.map +1 -0
- package/dist/admin/index.d.ts +64 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +31 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/organization-controller.d.ts +77 -0
- package/dist/admin/organization-controller.d.ts.map +1 -0
- package/dist/admin/organization-controller.js +472 -0
- package/dist/admin/organization-controller.js.map +1 -0
- package/dist/admin/organization-dialogs.d.ts +63 -0
- package/dist/admin/organization-dialogs.d.ts.map +1 -0
- package/dist/admin/organization-dialogs.js +303 -0
- package/dist/admin/organization-dialogs.js.map +1 -0
- package/dist/admin/organization-service.d.ts +110 -0
- package/dist/admin/organization-service.d.ts.map +1 -0
- package/dist/admin/organization-service.js +548 -0
- package/dist/admin/organization-service.js.map +1 -0
- package/dist/admin/organization-workspace.d.ts +29 -0
- package/dist/admin/organization-workspace.d.ts.map +1 -0
- package/dist/admin/organization-workspace.js +421 -0
- package/dist/admin/organization-workspace.js.map +1 -0
- package/dist/admin/portability-controller.d.ts +83 -0
- package/dist/admin/portability-controller.d.ts.map +1 -0
- package/dist/admin/portability-controller.js +466 -0
- package/dist/admin/portability-controller.js.map +1 -0
- package/dist/admin/portability-service.d.ts +31 -0
- package/dist/admin/portability-service.d.ts.map +1 -0
- package/dist/admin/portability-service.js +51 -0
- package/dist/admin/portability-service.js.map +1 -0
- package/dist/admin/portability-state.d.ts +88 -0
- package/dist/admin/portability-state.d.ts.map +1 -0
- package/dist/admin/portability-state.js +3 -0
- package/dist/admin/portability-state.js.map +1 -0
- package/dist/admin/portability-workspace.d.ts +78 -0
- package/dist/admin/portability-workspace.d.ts.map +1 -0
- package/dist/admin/portability-workspace.js +337 -0
- package/dist/admin/portability-workspace.js.map +1 -0
- package/dist/admin/presentation.d.ts +46 -0
- package/dist/admin/presentation.d.ts.map +1 -0
- package/dist/admin/presentation.js +271 -0
- package/dist/admin/presentation.js.map +1 -0
- package/dist/admin/rbac-dialogs.d.ts +73 -0
- package/dist/admin/rbac-dialogs.d.ts.map +1 -0
- package/dist/admin/rbac-dialogs.js +345 -0
- package/dist/admin/rbac-dialogs.js.map +1 -0
- package/dist/admin/rbac-service.d.ts +47 -0
- package/dist/admin/rbac-service.d.ts.map +1 -0
- package/dist/admin/rbac-service.js +258 -0
- package/dist/admin/rbac-service.js.map +1 -0
- package/dist/admin/rbac-state.d.ts +129 -0
- package/dist/admin/rbac-state.d.ts.map +1 -0
- package/dist/admin/rbac-state.js +136 -0
- package/dist/admin/rbac-state.js.map +1 -0
- package/dist/admin/selectable-read-only-input.d.ts +18 -0
- package/dist/admin/selectable-read-only-input.d.ts.map +1 -0
- package/dist/admin/selectable-read-only-input.js +24 -0
- package/dist/admin/selectable-read-only-input.js.map +1 -0
- package/dist/admin/session-service.d.ts +169 -0
- package/dist/admin/session-service.d.ts.map +1 -0
- package/dist/admin/session-service.js +353 -0
- package/dist/admin/session-service.js.map +1 -0
- package/dist/admin/state.d.ts +301 -0
- package/dist/admin/state.d.ts.map +1 -0
- package/dist/admin/state.js +10 -0
- package/dist/admin/state.js.map +1 -0
- package/dist/admin/system-config-controller.d.ts +58 -0
- package/dist/admin/system-config-controller.d.ts.map +1 -0
- package/dist/admin/system-config-controller.js +218 -0
- package/dist/admin/system-config-controller.js.map +1 -0
- package/dist/admin/system-config-service.d.ts +54 -0
- package/dist/admin/system-config-service.d.ts.map +1 -0
- package/dist/admin/system-config-service.js +180 -0
- package/dist/admin/system-config-service.js.map +1 -0
- package/dist/admin/system-config-state.d.ts +77 -0
- package/dist/admin/system-config-state.d.ts.map +1 -0
- package/dist/admin/system-config-state.js +78 -0
- package/dist/admin/system-config-state.js.map +1 -0
- package/dist/admin/system-config-workspace.d.ts +47 -0
- package/dist/admin/system-config-workspace.d.ts.map +1 -0
- package/dist/admin/system-config-workspace.js +217 -0
- package/dist/admin/system-config-workspace.js.map +1 -0
- package/dist/admin/user-controller-types.d.ts +67 -0
- package/dist/admin/user-controller-types.d.ts.map +1 -0
- package/dist/admin/user-controller-types.js +3 -0
- package/dist/admin/user-controller-types.js.map +1 -0
- package/dist/admin/user-controller.d.ts +6 -0
- package/dist/admin/user-controller.d.ts.map +1 -0
- package/dist/admin/user-controller.js +674 -0
- package/dist/admin/user-controller.js.map +1 -0
- package/dist/admin/user-dialog-fields.d.ts +44 -0
- package/dist/admin/user-dialog-fields.d.ts.map +1 -0
- package/dist/admin/user-dialog-fields.js +130 -0
- package/dist/admin/user-dialog-fields.js.map +1 -0
- package/dist/admin/user-dialogs.d.ts +66 -0
- package/dist/admin/user-dialogs.d.ts.map +1 -0
- package/dist/admin/user-dialogs.js +374 -0
- package/dist/admin/user-dialogs.js.map +1 -0
- package/dist/admin/user-role-controller.d.ts +82 -0
- package/dist/admin/user-role-controller.d.ts.map +1 -0
- package/dist/admin/user-role-controller.js +337 -0
- package/dist/admin/user-role-controller.js.map +1 -0
- package/dist/admin/user-role-dialog.d.ts +94 -0
- package/dist/admin/user-role-dialog.d.ts.map +1 -0
- package/dist/admin/user-role-dialog.js +265 -0
- package/dist/admin/user-role-dialog.js.map +1 -0
- package/dist/admin/user-service-types.d.ts +100 -0
- package/dist/admin/user-service-types.d.ts.map +1 -0
- package/dist/admin/user-service-types.js +3 -0
- package/dist/admin/user-service-types.js.map +1 -0
- package/dist/admin/user-service.d.ts +14 -0
- package/dist/admin/user-service.d.ts.map +1 -0
- package/dist/admin/user-service.js +612 -0
- package/dist/admin/user-service.js.map +1 -0
- package/dist/admin/user-state.d.ts +158 -0
- package/dist/admin/user-state.d.ts.map +1 -0
- package/dist/admin/user-state.js +3 -0
- package/dist/admin/user-state.js.map +1 -0
- package/dist/admin/user-workspace.d.ts +65 -0
- package/dist/admin/user-workspace.d.ts.map +1 -0
- package/dist/admin/user-workspace.js +366 -0
- package/dist/admin/user-workspace.js.map +1 -0
- package/dist/auth/browser-flow.d.ts +27 -1
- package/dist/auth/browser-flow.d.ts.map +1 -1
- package/dist/auth/browser-flow.js +55 -33
- package/dist/auth/browser-flow.js.map +1 -1
- package/dist/auth/callback-server.d.ts.map +1 -1
- package/dist/auth/callback-server.js +5 -9
- package/dist/auth/callback-server.js.map +1 -1
- package/dist/auth/id-token-verifier.d.ts +39 -0
- package/dist/auth/id-token-verifier.d.ts.map +1 -0
- package/dist/auth/id-token-verifier.js +104 -0
- package/dist/auth/id-token-verifier.js.map +1 -0
- package/dist/auth/login-coordinator.d.ts +72 -0
- package/dist/auth/login-coordinator.d.ts.map +1 -0
- package/dist/auth/login-coordinator.js +190 -0
- package/dist/auth/login-coordinator.js.map +1 -0
- package/dist/auth/metadata.d.ts +2 -1
- package/dist/auth/metadata.d.ts.map +1 -1
- package/dist/auth/metadata.js +67 -6
- package/dist/auth/metadata.js.map +1 -1
- package/dist/auth/types.d.ts +14 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/client-factory.d.ts.map +1 -1
- package/dist/client-factory.js +15 -2
- package/dist/client-factory.js.map +1 -1
- package/dist/commands/admin.d.ts +22 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +112 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/app-claim.d.ts.map +1 -1
- package/dist/commands/app-claim.js +11 -4
- package/dist/commands/app-claim.js.map +1 -1
- package/dist/commands/app-module.d.ts.map +1 -1
- package/dist/commands/app-module.js +61 -12
- package/dist/commands/app-module.js.map +1 -1
- package/dist/commands/app-permission.d.ts.map +1 -1
- package/dist/commands/app-permission.js +66 -24
- package/dist/commands/app-permission.js.map +1 -1
- package/dist/commands/app-role.d.ts.map +1 -1
- package/dist/commands/app-role.js +48 -27
- package/dist/commands/app-role.js.map +1 -1
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +37 -25
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/bulk.d.ts.map +1 -1
- package/dist/commands/bulk.js +9 -2
- package/dist/commands/bulk.js.map +1 -1
- package/dist/commands/client-secret.d.ts.map +1 -1
- package/dist/commands/client-secret.js +12 -6
- package/dist/commands/client-secret.js.map +1 -1
- package/dist/commands/client.d.ts +3 -2
- package/dist/commands/client.d.ts.map +1 -1
- package/dist/commands/client.js +87 -43
- package/dist/commands/client.js.map +1 -1
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +68 -7
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/export.d.ts +6 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +182 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +6 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +142 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/keys.d.ts.map +1 -1
- package/dist/commands/keys.js +11 -4
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +24 -10
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/org.d.ts +2 -4
- package/dist/commands/org.d.ts.map +1 -1
- package/dist/commands/org.js +16 -76
- package/dist/commands/org.js.map +1 -1
- package/dist/commands/user-role.d.ts.map +1 -1
- package/dist/commands/user-role.js +19 -14
- package/dist/commands/user-role.js.map +1 -1
- package/dist/commands/user.d.ts +3 -2
- package/dist/commands/user.d.ts.map +1 -1
- package/dist/commands/user.js +47 -71
- package/dist/commands/user.js.map +1 -1
- package/dist/commands/version.d.ts +1 -1
- package/dist/commands/version.js +1 -1
- package/dist/credential-lock.d.ts +20 -0
- package/dist/credential-lock.d.ts.map +1 -0
- package/dist/credential-lock.js +130 -0
- package/dist/credential-lock.js.map +1 -0
- package/dist/credential-store.d.ts +14 -0
- package/dist/credential-store.d.ts.map +1 -1
- package/dist/credential-store.js +114 -3
- package/dist/credential-store.js.map +1 -1
- package/dist/error-handler.d.ts.map +1 -1
- package/dist/error-handler.js +2 -0
- package/dist/error-handler.js.map +1 -1
- package/dist/global-options.d.ts +8 -0
- package/dist/global-options.d.ts.map +1 -1
- package/dist/global-options.js +19 -8
- package/dist/global-options.js.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +11 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +25 -6
- package/dist/output.js.map +1 -1
- package/dist/prompt.d.ts +2 -2
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +27 -7
- package/dist/prompt.js.map +1 -1
- package/package.json +7 -3
- package/dist/commands/gui.d.ts +0 -21
- package/dist/commands/gui.d.ts.map +0 -1
- package/dist/commands/gui.js +0 -67
- package/dist/commands/gui.js.map +0 -1
- package/dist/commands/provision.d.ts +0 -47
- package/dist/commands/provision.d.ts.map +0 -1
- package/dist/commands/provision.js +0 -444
- package/dist/commands/provision.js.map +0 -1
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @module auth/browser-flow
|
|
19
19
|
*/
|
|
20
|
-
import type { AuthFlowResult } from './types.js';
|
|
20
|
+
import type { AuthFlowResult, CliAuthOperationOptions, TokenResponse } from './types.js';
|
|
21
21
|
/** Options for the browser flow */
|
|
22
22
|
export interface BrowserFlowOptions {
|
|
23
23
|
/** Porta server URL */
|
|
@@ -26,7 +26,33 @@ export interface BrowserFlowOptions {
|
|
|
26
26
|
clientId?: string;
|
|
27
27
|
/** Force manual mode (print URL instead of opening browser) */
|
|
28
28
|
noBrowser?: boolean;
|
|
29
|
+
/** Optional cancellation signal owned by the calling UI. */
|
|
30
|
+
signal?: AbortSignal;
|
|
29
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Exchange an authorization code for tokens at the OIDC token endpoint.
|
|
34
|
+
*
|
|
35
|
+
* Sends a POST request with the authorization code, PKCE code_verifier,
|
|
36
|
+
* and redirect URI to complete the Authorization Code flow.
|
|
37
|
+
*
|
|
38
|
+
* @param params - Token exchange parameters
|
|
39
|
+
* @returns Token response with access, refresh, and ID tokens
|
|
40
|
+
* @throws Error if the token exchange fails
|
|
41
|
+
*/
|
|
42
|
+
export interface AuthorizationCodeExchange {
|
|
43
|
+
/** Exact discovered token endpoint. */
|
|
44
|
+
readonly tokenEndpoint: string;
|
|
45
|
+
/** Public client identifier. */
|
|
46
|
+
readonly clientId: string;
|
|
47
|
+
/** Single-use authorization code. */
|
|
48
|
+
readonly code: string;
|
|
49
|
+
/** PKCE verifier bound to the authorization request. */
|
|
50
|
+
readonly codeVerifier: string;
|
|
51
|
+
/** Exact redirect URI used in the authorization request. */
|
|
52
|
+
readonly redirectUri: string;
|
|
53
|
+
}
|
|
54
|
+
/** Exchanges a code once while propagating caller-owned cancellation. */
|
|
55
|
+
export declare function exchangeAuthorizationCode(params: AuthorizationCodeExchange, options: CliAuthOperationOptions): Promise<TokenResponse>;
|
|
30
56
|
/**
|
|
31
57
|
* Execute the OIDC Authorization Code + PKCE login flow.
|
|
32
58
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-flow.d.ts","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAaH,OAAO,KAAK,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"browser-flow.d.ts","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAaH,OAAO,KAAK,EAAE,cAAc,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAazF,mCAAmC;AACnC,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAMD;;;;;;;;;GASG;AACH,MAAM,WAAW,yBAAyB;IACxC,uCAAuC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,yEAAyE;AACzE,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,yBAAyB,EACjC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CA6CxB;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,kBAAkB,EAC3B,GAAG,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAkB,GAC3C,OAAO,CAAC,cAAc,CAAC,CAoKzB"}
|
|
@@ -17,33 +17,20 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @module auth/browser-flow
|
|
19
19
|
*/
|
|
20
|
-
import { decodeJwt } from 'jose';
|
|
21
20
|
import { URL } from 'node:url';
|
|
22
21
|
import { question } from '../prompt.js';
|
|
23
22
|
import { MANUAL_REDIRECT_URI, isContainerized, parseCallbackUrl, startCallbackServer, } from './callback-server.js';
|
|
24
23
|
import { fetchAdminMetadata } from './metadata.js';
|
|
24
|
+
import { fetchIssuerJwks, verifyCliIdToken } from './id-token-verifier.js';
|
|
25
25
|
import { generateCodeChallenge, generateCodeVerifier, generateState } from './pkce.js';
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
27
|
// Constants
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
/** OIDC scopes requested during the login flow */
|
|
30
30
|
const SCOPES = 'openid profile email offline_access';
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Exchange an authorization code for tokens at the OIDC token endpoint.
|
|
36
|
-
*
|
|
37
|
-
* Sends a POST request with the authorization code, PKCE code_verifier,
|
|
38
|
-
* and redirect URI to complete the Authorization Code flow.
|
|
39
|
-
*
|
|
40
|
-
* @param params - Token exchange parameters
|
|
41
|
-
* @returns Token response with access, refresh, and ID tokens
|
|
42
|
-
* @throws Error if the token exchange fails
|
|
43
|
-
*/
|
|
44
|
-
async function exchangeCode(params) {
|
|
45
|
-
const tokenUrl = `${params.server}/${params.orgSlug}/token`;
|
|
46
|
-
const response = await fetch(tokenUrl, {
|
|
31
|
+
/** Exchanges a code once while propagating caller-owned cancellation. */
|
|
32
|
+
export async function exchangeAuthorizationCode(params, options) {
|
|
33
|
+
const response = await fetch(params.tokenEndpoint, {
|
|
47
34
|
method: 'POST',
|
|
48
35
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
49
36
|
body: new URLSearchParams({
|
|
@@ -53,15 +40,38 @@ async function exchangeCode(params) {
|
|
|
53
40
|
client_id: params.clientId,
|
|
54
41
|
code_verifier: params.codeVerifier,
|
|
55
42
|
}),
|
|
43
|
+
signal: options.signal,
|
|
56
44
|
});
|
|
57
45
|
if (!response.ok) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
46
|
+
throw new Error(`Authentication failed (HTTP ${response.status})`);
|
|
47
|
+
}
|
|
48
|
+
let value;
|
|
49
|
+
try {
|
|
50
|
+
value = await response.json();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
throw new Error('Authentication failed');
|
|
63
54
|
}
|
|
64
|
-
|
|
55
|
+
if (!value || typeof value !== 'object')
|
|
56
|
+
throw new Error('Authentication failed');
|
|
57
|
+
const token = value;
|
|
58
|
+
if (typeof token.access_token !== 'string' ||
|
|
59
|
+
token.access_token.length === 0 ||
|
|
60
|
+
typeof token.id_token !== 'string' ||
|
|
61
|
+
token.id_token.length === 0 ||
|
|
62
|
+
typeof token.expires_in !== 'number' ||
|
|
63
|
+
!Number.isFinite(token.expires_in) ||
|
|
64
|
+
token.expires_in <= 0 ||
|
|
65
|
+
(token.refresh_token !== undefined &&
|
|
66
|
+
(typeof token.refresh_token !== 'string' || token.refresh_token.length === 0))) {
|
|
67
|
+
throw new Error('Authentication failed');
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
access_token: token.access_token,
|
|
71
|
+
refresh_token: token.refresh_token,
|
|
72
|
+
id_token: token.id_token,
|
|
73
|
+
expires_in: token.expires_in,
|
|
74
|
+
};
|
|
65
75
|
}
|
|
66
76
|
// ---------------------------------------------------------------------------
|
|
67
77
|
// Flow Orchestration
|
|
@@ -79,6 +89,7 @@ async function exchangeCode(params) {
|
|
|
79
89
|
*/
|
|
80
90
|
export async function executeBrowserFlow(options, log = console.log) {
|
|
81
91
|
const { server, noBrowser } = options;
|
|
92
|
+
const signal = options.signal ?? new AbortController().signal;
|
|
82
93
|
// ---------------------------------------------------------------
|
|
83
94
|
// Step 1: Determine login mode (browser vs. manual)
|
|
84
95
|
// ---------------------------------------------------------------
|
|
@@ -91,14 +102,17 @@ export async function executeBrowserFlow(options, log = console.log) {
|
|
|
91
102
|
// ---------------------------------------------------------------
|
|
92
103
|
let clientId;
|
|
93
104
|
let orgSlug;
|
|
105
|
+
let issuer;
|
|
94
106
|
if (options.clientId) {
|
|
95
107
|
clientId = options.clientId;
|
|
96
108
|
orgSlug = 'porta-admin';
|
|
109
|
+
issuer = `${server}/porta-admin`;
|
|
97
110
|
}
|
|
98
111
|
else {
|
|
99
|
-
const metadata = await fetchAdminMetadata(server);
|
|
112
|
+
const metadata = await fetchAdminMetadata(server, { signal });
|
|
100
113
|
clientId = metadata.clientId;
|
|
101
114
|
orgSlug = metadata.orgSlug;
|
|
115
|
+
issuer = metadata.issuer;
|
|
102
116
|
}
|
|
103
117
|
// ---------------------------------------------------------------
|
|
104
118
|
// Step 3: Generate PKCE parameters
|
|
@@ -106,6 +120,7 @@ export async function executeBrowserFlow(options, log = console.log) {
|
|
|
106
120
|
const codeVerifier = generateCodeVerifier();
|
|
107
121
|
const codeChallenge = generateCodeChallenge(codeVerifier);
|
|
108
122
|
const state = generateState();
|
|
123
|
+
const nonce = generateState();
|
|
109
124
|
// ---------------------------------------------------------------
|
|
110
125
|
// Step 4: Set up redirect URI — mode-dependent
|
|
111
126
|
// ---------------------------------------------------------------
|
|
@@ -131,6 +146,7 @@ export async function executeBrowserFlow(options, log = console.log) {
|
|
|
131
146
|
authUrl.searchParams.set('code_challenge', codeChallenge);
|
|
132
147
|
authUrl.searchParams.set('code_challenge_method', 'S256');
|
|
133
148
|
authUrl.searchParams.set('state', state);
|
|
149
|
+
authUrl.searchParams.set('nonce', nonce);
|
|
134
150
|
// prompt MUST include `consent` for `offline_access` to survive.
|
|
135
151
|
//
|
|
136
152
|
// Per OIDC Core §3.1.2.1 and node-oidc-provider's check_scope, the provider
|
|
@@ -169,14 +185,13 @@ export async function executeBrowserFlow(options, log = console.log) {
|
|
|
169
185
|
// ---------------------------------------------------------------
|
|
170
186
|
// Step 7: Exchange the authorization code for tokens
|
|
171
187
|
// ---------------------------------------------------------------
|
|
172
|
-
const tokens = await
|
|
173
|
-
server
|
|
174
|
-
orgSlug,
|
|
188
|
+
const tokens = await exchangeAuthorizationCode({
|
|
189
|
+
tokenEndpoint: `${server}/${orgSlug}/token`,
|
|
175
190
|
code,
|
|
176
191
|
redirectUri,
|
|
177
192
|
clientId,
|
|
178
193
|
codeVerifier,
|
|
179
|
-
});
|
|
194
|
+
}, { signal });
|
|
180
195
|
// ---------------------------------------------------------------
|
|
181
196
|
// Step 7.5: Warn if the server did not issue a refresh token.
|
|
182
197
|
//
|
|
@@ -192,9 +207,16 @@ export async function executeBrowserFlow(options, log = console.log) {
|
|
|
192
207
|
"'refresh_token' grant and the 'offline_access' scope.");
|
|
193
208
|
}
|
|
194
209
|
// ---------------------------------------------------------------
|
|
195
|
-
// Step 8:
|
|
210
|
+
// Step 8: Authenticate the ID token before accepting identity
|
|
196
211
|
// ---------------------------------------------------------------
|
|
197
|
-
const
|
|
212
|
+
const jwks = await fetchIssuerJwks(`${issuer}/jwks`, { signal });
|
|
213
|
+
const identity = await verifyCliIdToken({
|
|
214
|
+
token: tokens.id_token,
|
|
215
|
+
issuer,
|
|
216
|
+
clientId,
|
|
217
|
+
nonce,
|
|
218
|
+
jwks,
|
|
219
|
+
});
|
|
198
220
|
// ---------------------------------------------------------------
|
|
199
221
|
// Step 9: Build and return the auth flow result
|
|
200
222
|
// ---------------------------------------------------------------
|
|
@@ -207,9 +229,9 @@ export async function executeBrowserFlow(options, log = console.log) {
|
|
|
207
229
|
idToken: tokens.id_token,
|
|
208
230
|
expiresAt: new Date(Date.now() + tokens.expires_in * 1000).toISOString(),
|
|
209
231
|
userInfo: {
|
|
210
|
-
sub:
|
|
211
|
-
email:
|
|
212
|
-
name:
|
|
232
|
+
sub: identity.sub,
|
|
233
|
+
email: identity.email ?? '',
|
|
234
|
+
name: identity.name,
|
|
213
235
|
},
|
|
214
236
|
};
|
|
215
237
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-flow.js","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"browser-flow.js","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback-server.d.ts","sourceRoot":"","sources":["../../src/auth/callback-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAaH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,oCAAoC,CAAC;AAMrE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,8CAA8C;IAC9C,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"callback-server.d.ts","sourceRoot":"","sources":["../../src/auth/callback-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAaH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,oCAAoC,CAAC;AAMrE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,8CAA8C;IAC9C,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAyFxF;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CA2BjF;AAMD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAUzC"}
|
|
@@ -72,12 +72,10 @@ export function startCallbackServer(expectedState) {
|
|
|
72
72
|
const errorParam = url.searchParams.get('error');
|
|
73
73
|
// Case 1: OIDC provider returned an error (user cancelled, etc.)
|
|
74
74
|
if (errorParam) {
|
|
75
|
-
const desc = url.searchParams.get('error_description') || errorParam;
|
|
76
75
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
77
|
-
res.end('<html><body><h1>Login Failed</h1>' +
|
|
78
|
-
'<p>You can close this tab.</p></body></html>');
|
|
76
|
+
res.end('<html><body><h1>Login Failed</h1>' + '<p>You can close this tab.</p></body></html>');
|
|
79
77
|
server.close();
|
|
80
|
-
rejectCode(new Error(
|
|
78
|
+
rejectCode(new Error('Authentication failed'));
|
|
81
79
|
return;
|
|
82
80
|
}
|
|
83
81
|
// Case 2: State mismatch — possible CSRF attack
|
|
@@ -92,8 +90,7 @@ export function startCallbackServer(expectedState) {
|
|
|
92
90
|
// Case 3: No authorization code in the callback
|
|
93
91
|
if (!code) {
|
|
94
92
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
95
|
-
res.end('<html><body><h1>Error</h1>' +
|
|
96
|
-
'<p>No authorization code received.</p></body></html>');
|
|
93
|
+
res.end('<html><body><h1>Error</h1>' + '<p>No authorization code received.</p></body></html>');
|
|
97
94
|
server.close();
|
|
98
95
|
rejectCode(new Error('No authorization code received'));
|
|
99
96
|
return;
|
|
@@ -145,13 +142,12 @@ export function parseCallbackUrl(pastedUrl, expectedState) {
|
|
|
145
142
|
url = new URL(pastedUrl.trim());
|
|
146
143
|
}
|
|
147
144
|
catch {
|
|
148
|
-
throw new Error(
|
|
145
|
+
throw new Error("Invalid URL. Please copy the full URL from your browser's address bar.");
|
|
149
146
|
}
|
|
150
147
|
// Check for OIDC error response in the callback URL
|
|
151
148
|
const errorParam = url.searchParams.get('error');
|
|
152
149
|
if (errorParam) {
|
|
153
|
-
|
|
154
|
-
throw new Error(`Authentication failed: ${desc}`);
|
|
150
|
+
throw new Error('Authentication failed');
|
|
155
151
|
}
|
|
156
152
|
// Validate state parameter (CSRF protection)
|
|
157
153
|
const returnedState = url.searchParams.get('state');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback-server.js","sourceRoot":"","sources":["../../src/auth/callback-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,wEAAwE;AACxE,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEvC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,iCAAiC,CAAC;AAkBrE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,
|
|
1
|
+
{"version":3,"file":"callback-server.js","sourceRoot":"","sources":["../../src/auth/callback-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Secure OIDC ID-token verification for interactive CLI authentication. */
|
|
2
|
+
import { type JSONWebKeySet } from 'jose';
|
|
3
|
+
import type { CliAuthOperationOptions, VerifiedIdentity } from './types.js';
|
|
4
|
+
/** Inputs that bind an ID token to one authorization request. */
|
|
5
|
+
export interface VerifyCliIdTokenRequest {
|
|
6
|
+
/** Compact ID token returned by the issuer. */
|
|
7
|
+
readonly token: string;
|
|
8
|
+
/** Exact discovered issuer URL. */
|
|
9
|
+
readonly issuer: string;
|
|
10
|
+
/** Public CLI client identifier. */
|
|
11
|
+
readonly clientId: string;
|
|
12
|
+
/** Unpredictable nonce sent in the matching authorization request. */
|
|
13
|
+
readonly nonce: string;
|
|
14
|
+
/** Issuer key set obtained from trusted discovery metadata. */
|
|
15
|
+
readonly jwks: JSONWebKeySet;
|
|
16
|
+
}
|
|
17
|
+
/** Optional context required to authenticate a refreshed ID token. */
|
|
18
|
+
export type IdTokenValidationContext = Omit<VerifyCliIdTokenRequest, 'token'>;
|
|
19
|
+
/** Inputs for retaining or safely updating display identity after refresh. */
|
|
20
|
+
export interface RefreshIdentityRequest {
|
|
21
|
+
/** Previously authenticated identity. */
|
|
22
|
+
readonly original: VerifiedIdentity;
|
|
23
|
+
/** Immutable subject established by the original login. */
|
|
24
|
+
readonly originalSubject: string;
|
|
25
|
+
/** Optional ID token returned by refresh. */
|
|
26
|
+
readonly token?: string;
|
|
27
|
+
/** Original validation context, when still available. */
|
|
28
|
+
readonly validationContext?: IdTokenValidationContext;
|
|
29
|
+
}
|
|
30
|
+
/** Verifies signature, issuer, audience, time, nonce, and subject. */
|
|
31
|
+
export declare function verifyCliIdToken(request: VerifyCliIdTokenRequest): Promise<VerifiedIdentity>;
|
|
32
|
+
/** Fetches and minimally validates an issuer JWKS with caller-owned cancellation. */
|
|
33
|
+
export declare function fetchIssuerJwks(endpoint: string, options: CliAuthOperationOptions): Promise<JSONWebKeySet>;
|
|
34
|
+
/**
|
|
35
|
+
* Accepts refreshed display claims only when the original verification context
|
|
36
|
+
* is available and the immutable subject remains unchanged.
|
|
37
|
+
*/
|
|
38
|
+
export declare function updateDisplayIdentityFromRefresh(request: RefreshIdentityRequest): Promise<VerifiedIdentity>;
|
|
39
|
+
//# sourceMappingURL=id-token-verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-token-verifier.d.ts","sourceRoot":"","sources":["../../src/auth/id-token-verifier.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAW5E,iEAAiE;AACjE,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC9B;AAED,sEAAsE;AACtE,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;AAE9E,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,2DAA2D;IAC3D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;CACvD;AAaD,sEAAsE;AACtE,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAwC3B;AAED,qFAAqF;AACrF,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAmBxB;AAED;;;GAGG;AACH,wBAAsB,gCAAgC,CACpD,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAW3B"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Secure OIDC ID-token verification for interactive CLI authentication. */
|
|
2
|
+
import { createLocalJWKSet, decodeProtectedHeader, jwtVerify, } from 'jose';
|
|
3
|
+
/** Detects ASCII and C1 controls that can alter terminal presentation. */
|
|
4
|
+
function containsTerminalControl(value) {
|
|
5
|
+
for (const character of value) {
|
|
6
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
7
|
+
if (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f))
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
/** Returns an allowlisted optional string claim. */
|
|
13
|
+
function optionalString(payload, claim) {
|
|
14
|
+
const value = payload[claim];
|
|
15
|
+
return typeof value === 'string' &&
|
|
16
|
+
value.length > 0 &&
|
|
17
|
+
value.length <= 256 &&
|
|
18
|
+
!containsTerminalControl(value)
|
|
19
|
+
? value
|
|
20
|
+
: undefined;
|
|
21
|
+
}
|
|
22
|
+
/** Verifies signature, issuer, audience, time, nonce, and subject. */
|
|
23
|
+
export async function verifyCliIdToken(request) {
|
|
24
|
+
try {
|
|
25
|
+
const verificationTime = Math.floor(Date.now() / 1000);
|
|
26
|
+
const protectedHeader = decodeProtectedHeader(request.token);
|
|
27
|
+
if (protectedHeader.alg !== 'ES256')
|
|
28
|
+
throw new Error('Unexpected signing algorithm');
|
|
29
|
+
const { payload } = await jwtVerify(request.token, createLocalJWKSet(request.jwks), {
|
|
30
|
+
algorithms: ['ES256'],
|
|
31
|
+
audience: request.clientId,
|
|
32
|
+
issuer: request.issuer,
|
|
33
|
+
});
|
|
34
|
+
if (typeof payload.iat !== 'number' ||
|
|
35
|
+
payload.iat > verificationTime + 60 ||
|
|
36
|
+
typeof payload.exp !== 'number' ||
|
|
37
|
+
payload.exp <= verificationTime ||
|
|
38
|
+
payload.nonce !== request.nonce ||
|
|
39
|
+
typeof payload.sub !== 'string' ||
|
|
40
|
+
payload.sub.length === 0 ||
|
|
41
|
+
payload.sub.length > 255 ||
|
|
42
|
+
containsTerminalControl(payload.sub)) {
|
|
43
|
+
throw new Error('Invalid required claims');
|
|
44
|
+
}
|
|
45
|
+
const audiences = Array.isArray(payload.aud) ? payload.aud : [payload.aud];
|
|
46
|
+
if (!audiences.includes(request.clientId) ||
|
|
47
|
+
(audiences.length > 1 && payload.azp !== request.clientId) ||
|
|
48
|
+
(payload.azp !== undefined && payload.azp !== request.clientId)) {
|
|
49
|
+
throw new Error('Invalid audience binding');
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
sub: payload.sub,
|
|
53
|
+
email: optionalString(payload, 'email'),
|
|
54
|
+
name: optionalString(payload, 'name'),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw new Error('Authentication failed');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Fetches and minimally validates an issuer JWKS with caller-owned cancellation. */
|
|
62
|
+
export async function fetchIssuerJwks(endpoint, options) {
|
|
63
|
+
let response;
|
|
64
|
+
try {
|
|
65
|
+
response = await fetch(endpoint, { signal: options.signal });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (error instanceof DOMException && error.name === 'AbortError')
|
|
69
|
+
throw error;
|
|
70
|
+
throw new Error('Authentication failed', { cause: error });
|
|
71
|
+
}
|
|
72
|
+
if (!response.ok)
|
|
73
|
+
throw new Error('Authentication failed');
|
|
74
|
+
let value;
|
|
75
|
+
try {
|
|
76
|
+
value = await response.json();
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new Error('Authentication failed');
|
|
80
|
+
}
|
|
81
|
+
if (!value || typeof value !== 'object' || !('keys' in value) || !Array.isArray(value.keys)) {
|
|
82
|
+
throw new Error('Authentication failed');
|
|
83
|
+
}
|
|
84
|
+
return { keys: value.keys };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Accepts refreshed display claims only when the original verification context
|
|
88
|
+
* is available and the immutable subject remains unchanged.
|
|
89
|
+
*/
|
|
90
|
+
export async function updateDisplayIdentityFromRefresh(request) {
|
|
91
|
+
if (!request.token || !request.validationContext)
|
|
92
|
+
return request.original;
|
|
93
|
+
try {
|
|
94
|
+
const refreshed = await verifyCliIdToken({
|
|
95
|
+
...request.validationContext,
|
|
96
|
+
token: request.token,
|
|
97
|
+
});
|
|
98
|
+
return refreshed.sub === request.originalSubject ? refreshed : request.original;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return request.original;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=id-token-verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-token-verifier.js","sourceRoot":"","sources":["../../src/auth/id-token-verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** UI-neutral coordination for the CLI Authorization Code + PKCE flow. */
|
|
2
|
+
import type { AdminCapabilities } from '../admin/state.js';
|
|
3
|
+
import type { AuthFlowResult, CliAuthOperationOptions, VerifiedIdentity } from './types.js';
|
|
4
|
+
/** Parameters used to create one authorization request. */
|
|
5
|
+
export interface AuthorizationRequestOptions {
|
|
6
|
+
/** Exact organization issuer. */
|
|
7
|
+
readonly issuer: string;
|
|
8
|
+
/** Public CLI client identifier. */
|
|
9
|
+
readonly clientId: string;
|
|
10
|
+
/** Redirect URI registered for the native CLI. */
|
|
11
|
+
readonly redirectUri?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Security values bound to one authorization request and callback. */
|
|
14
|
+
export interface AuthorizationRequest {
|
|
15
|
+
/** Complete browser authorization URL. */
|
|
16
|
+
readonly url: URL;
|
|
17
|
+
/** CSRF state value. */
|
|
18
|
+
readonly state: string;
|
|
19
|
+
/** OIDC nonce value. */
|
|
20
|
+
readonly nonce: string;
|
|
21
|
+
/** PKCE verifier retained for the token exchange. */
|
|
22
|
+
readonly codeVerifier: string;
|
|
23
|
+
/** Exact redirect URI included in the request. */
|
|
24
|
+
readonly redirectUri: string;
|
|
25
|
+
}
|
|
26
|
+
/** UI interactions needed by the authentication coordinator. */
|
|
27
|
+
export interface LoginInteraction {
|
|
28
|
+
/** Shows a browser URL when automatic opening is unavailable. */
|
|
29
|
+
readonly presentAuthorizationUrl: (url: URL, signal: AbortSignal) => Promise<void>;
|
|
30
|
+
/** Reads one complete callback URL from the owning UI. */
|
|
31
|
+
readonly requestManualCallback: (signal: AbortSignal) => Promise<string>;
|
|
32
|
+
/** Confirms replacement of credentials belonging to another origin. */
|
|
33
|
+
readonly confirmCredentialReplacement: (currentServer: URL, nextServer: URL, signal: AbortSignal) => Promise<boolean>;
|
|
34
|
+
}
|
|
35
|
+
/** Injectable boundaries used by a CLI authentication attempt. */
|
|
36
|
+
export interface LoginRequest {
|
|
37
|
+
/** Selected Porta server origin. */
|
|
38
|
+
readonly server: URL;
|
|
39
|
+
/** Optional public client override retained for existing CLI usage. */
|
|
40
|
+
readonly clientId?: string;
|
|
41
|
+
/** Uses pasted callback completion instead of a local listener. */
|
|
42
|
+
readonly noBrowser?: boolean;
|
|
43
|
+
/** Browser opener, injectable for tests and alternate UIs. */
|
|
44
|
+
readonly openBrowser?: (url: URL) => Promise<unknown>;
|
|
45
|
+
/** Existing profile origin, used to prevent silent cross-server replacement. */
|
|
46
|
+
readonly currentServer?: URL;
|
|
47
|
+
/** Persists only a fully authenticated credential result. */
|
|
48
|
+
readonly persistCredentials?: (credentials: AuthFlowResult) => Promise<void> | void;
|
|
49
|
+
}
|
|
50
|
+
/** Result returned after a successful authenticated login. */
|
|
51
|
+
export interface VerifiedSession {
|
|
52
|
+
/** Successful login discriminator. */
|
|
53
|
+
readonly status: 'authenticated';
|
|
54
|
+
/** Fully verified identity accepted from the ID token. */
|
|
55
|
+
readonly identity: VerifiedIdentity;
|
|
56
|
+
/** Organization actions from live UserInfo, retained only in memory. */
|
|
57
|
+
readonly capabilities: AdminCapabilities;
|
|
58
|
+
/** Credentials committed by the coordinator. */
|
|
59
|
+
readonly credentials: AuthFlowResult;
|
|
60
|
+
}
|
|
61
|
+
/** Typed cancellation returned without persisting partial authentication state. */
|
|
62
|
+
export interface CancelledLogin {
|
|
63
|
+
/** Cancellation discriminator. */
|
|
64
|
+
readonly status: 'cancelled';
|
|
65
|
+
}
|
|
66
|
+
/** Creates fresh state, PKCE, and nonce values for one browser request. */
|
|
67
|
+
export declare function createAuthorizationRequest(options: AuthorizationRequestOptions): Promise<AuthorizationRequest>;
|
|
68
|
+
/** Validates one callback URL against its exact request state. */
|
|
69
|
+
export declare function validateAuthorizationCallback(callbackUrl: string, request: AuthorizationRequest): string;
|
|
70
|
+
/** Completes one authentication attempt and persists only verified credentials. */
|
|
71
|
+
export declare function authenticateCliSession(request: LoginRequest, interaction: LoginInteraction, options: CliAuthOperationOptions): Promise<VerifiedSession | CancelledLogin>;
|
|
72
|
+
//# sourceMappingURL=login-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-coordinator.d.ts","sourceRoot":"","sources":["../../src/auth/login-coordinator.ts"],"names":[],"mappings":"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"}
|