capacitor-oidc 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -104,7 +104,7 @@ callback route, call `signinCallback()`; on the web logout callback route, call
104
104
  `web` or `native`, then the matching `ios` or `android` override.
105
105
 
106
106
  A runnable Keycloak-backed iOS application and its UI test live in
107
- [`example`](example).
107
+ [`example`](example/).
108
108
 
109
109
  ## Documentation
110
110
 
@@ -127,7 +127,7 @@ npm run verify:android
127
127
 
128
128
  Architecture decisions and contributor constraints are documented in
129
129
  [ARCHITECTURE.md](ARCHITECTURE.md), [REQUIREMENTS.md](REQUIREMENTS.md), and
130
- [docs/adr](docs/adr).
130
+ [docs/adr](docs/adr/).
131
131
 
132
132
  ## License
133
133
 
package/SECURITY.md CHANGED
@@ -12,33 +12,6 @@ with PKCE and cannot contain a client secret. Native authorization and provider
12
12
  logout run in system authentication UI, never an embedded WebView; web uses
13
13
  normal browser redirect or popup navigation.
14
14
 
15
- ## ID-token validation in `oidc-client-ts` 3.5.0
16
-
17
- The pinned `oidc-client-ts` 3.5.0 decodes ID-token claims and validates `sub`,
18
- `nonce`, and selected refresh-token continuity claims. It does not independently
19
- compare the decoded `iss`, `aud`, and `exp` claims with the configured client and
20
- current time. This behavior is visible in the
21
- [v3.5.0 ResponseValidator](https://github.com/authts/oidc-client-ts/blob/v3.5.0/src/ResponseValidator.ts)
22
- and is the subject of the open upstream report
23
- [authts/oidc-client-ts#2475](https://github.com/authts/oidc-client-ts/issues/2475).
24
-
25
- The practical exposure is narrower than an implicit-flow token parser: this
26
- package uses Authorization Code Flow only, and the token response comes from the
27
- configured token endpoint over TLS after state, nonce, and PKCE processing. The
28
- upstream project has not yet classified or resolved the report.
29
-
30
- This is a standards-conformance and threat-model consideration, not a categorical
31
- claim that every application using `oidc-client-ts` is unsafe. Consumers should
32
- evaluate it against their provider, reliance on ID-token claims, and assurance
33
- requirements. Resource servers must always validate access tokens independently;
34
- an application must not use unverified client-side profile claims as its API
35
- authorization boundary.
36
-
37
- The package will follow the upstream resolution and cover the expected behavior
38
- in provider integration tests before a stable v1 decision. It will not add a
39
- package-local JWT or cryptographic-validation layer, because duplicating protocol
40
- security code would expand the attack surface and create a second OIDC engine.
41
-
42
15
  ## Secure-storage boundary
43
16
 
44
17
  OIDC transactions and sessions are stored through iOS Keychain or an Android
@@ -59,3 +32,26 @@ absent. Their behavior must be verified in packaged applications on supported
59
32
  physical devices.
60
33
 
61
34
  See [Testing](docs/TESTING.md) for current platform and provider coverage.
35
+
36
+ ## Known issues
37
+
38
+ ### ID-token claim validation in `oidc-client-ts` 3.5.0
39
+
40
+ The pinned `oidc-client-ts` 3.5.0 decodes ID-token claims and validates `sub`,
41
+ `nonce`, and selected refresh-token continuity claims. It does not independently
42
+ compare the decoded `iss`, `aud`, and `exp` claims with the configured client and
43
+ current time. This behavior is visible in the
44
+ [v3.5.0 ResponseValidator](https://github.com/authts/oidc-client-ts/blob/v3.5.0/src/ResponseValidator.ts)
45
+ and is the subject of the unresolved upstream report
46
+ [authts/oidc-client-ts#2475](https://github.com/authts/oidc-client-ts/issues/2475).
47
+
48
+ This package uses Authorization Code Flow, so the token response comes from the
49
+ configured token endpoint over TLS after state, nonce, and PKCE processing.
50
+ Applications that rely on `iss`, `aud`, or `exp` claims should still evaluate
51
+ the upstream gap against their assurance requirements. Resource servers must
52
+ validate access tokens independently, and client-side ID-token claims must not
53
+ be an API authorization boundary.
54
+
55
+ The package will follow the upstream resolution and cover the expected behavior
56
+ in provider integration tests before a stable v1 decision. It will not add a
57
+ package-local JWT validation layer that would duplicate protocol security code.
@@ -1,4 +1,5 @@
1
1
  import { CapacitorOidcError } from './errors.js';
2
+ import { WEB_ONLY_SETTINGS } from './user-manager-settings-policy.js';
2
3
  export function resolveConfiguration(configuration, platform) {
3
4
  if (platform === 'web')
4
5
  return resolveWebConfiguration(configuration);
@@ -61,7 +62,7 @@ function assertPublicClient(settings) {
61
62
  }
62
63
  }
63
64
  function assertNativeSettings(settings) {
64
- const unsupported = ['dpop', 'monitorSession', 'silent_redirect_uri', 'stateStore', 'userStore'].find((key) => key in settings);
65
+ const unsupported = WEB_ONLY_SETTINGS.find((key) => key in settings);
65
66
  if (unsupported) {
66
67
  throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Native configuration does not support ${unsupported}`);
67
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/configuration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { UserManagerSettings } from 'oidc-client-ts';\n\nimport type {\n CapacitorOidcNativeOptions,\n CapacitorSigninArgs,\n CapacitorSignoutArgs,\n CapacitorUserManagerConfiguration,\n CapacitorUserManagerSettings,\n} from './definitions.js';\nimport { CapacitorOidcError } from './errors.js';\n\nexport type RuntimePlatform = 'android' | 'ios' | 'web';\n\nexport interface ResolvedUserManagerConfiguration {\n platform: RuntimePlatform;\n settings: UserManagerSettings;\n nativeOptions?: CapacitorOidcNativeOptions;\n signinMode: 'popup' | 'redirect';\n signoutMode: 'popup' | 'redirect';\n signinArgs: CapacitorSigninArgs;\n signoutArgs: CapacitorSignoutArgs;\n}\n\nexport function resolveConfiguration(\n configuration: CapacitorUserManagerConfiguration,\n platform: RuntimePlatform,\n): ResolvedUserManagerConfiguration {\n if (platform === 'web') return resolveWebConfiguration(configuration);\n return resolveNativeConfiguration(configuration, platform);\n}\n\nexport function resolveLegacyNativeConfiguration(\n settings: CapacitorUserManagerSettings,\n nativeOptions: CapacitorOidcNativeOptions,\n platform: RuntimePlatform,\n): ResolvedUserManagerConfiguration {\n if (platform === 'web') {\n throw new CapacitorOidcError(\n 'UNSUPPORTED_RUNTIME',\n 'Legacy CapacitorUserManager settings are only supported on iOS and Android',\n );\n }\n\n assertPublicClient(settings);\n if ('dpop' in settings) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Native configuration does not support dpop');\n }\n\n return resolvedNativeConfiguration(platform, settings, nativeOptions);\n}\n\nfunction resolveWebConfiguration(configuration: CapacitorUserManagerConfiguration): ResolvedUserManagerConfiguration {\n const web = configuration.web;\n if (!web) unsupportedConfiguration('web');\n\n const signoutMode = web.signoutMode ?? 'redirect';\n const settings: UserManagerSettings = { ...configuration.common, ...web.settings };\n assertPublicClient(settings);\n if (signoutMode === 'popup' && !settings.popup_post_logout_redirect_uri && !settings.post_logout_redirect_uri) {\n throw new CapacitorOidcError(\n 'UNSUPPORTED_RUNTIME',\n 'Web popup signout requires post_logout_redirect_uri or popup_post_logout_redirect_uri',\n );\n }\n\n return {\n platform: 'web',\n settings,\n signinMode: web.signinMode ?? 'redirect',\n signoutMode,\n signinArgs: web.signinArgs ?? {},\n signoutArgs: web.signoutArgs ?? {},\n };\n}\n\nfunction resolveNativeConfiguration(\n configuration: CapacitorUserManagerConfiguration,\n platform: 'android' | 'ios',\n): ResolvedUserManagerConfiguration {\n const native = configuration.native;\n if (!native) unsupportedConfiguration(platform);\n\n const override = configuration[platform];\n const settings = { ...configuration.common, ...native.settings, ...override?.settings };\n assertPublicClient(settings);\n assertNativeSettings(settings);\n\n return resolvedNativeConfiguration(\n platform,\n settings,\n { ...native.options, ...override?.options },\n { ...native.signinArgs, ...override?.signinArgs },\n { ...native.signoutArgs, ...override?.signoutArgs },\n );\n}\n\nfunction resolvedNativeConfiguration(\n platform: 'android' | 'ios',\n settings: UserManagerSettings,\n nativeOptions: CapacitorOidcNativeOptions,\n signinArgs: CapacitorSigninArgs = {},\n signoutArgs: CapacitorSignoutArgs = {},\n): ResolvedUserManagerConfiguration {\n return {\n platform,\n settings: { ...settings, response_type: 'code', disablePKCE: false, monitorSession: false },\n nativeOptions,\n signinMode: 'popup',\n signoutMode: 'popup',\n signinArgs,\n signoutArgs,\n };\n}\n\nfunction assertPublicClient(settings: object): void {\n const unsupported = ['client_authentication', 'client_secret', 'disablePKCE', 'response_type'].find(\n (key) => key in settings,\n );\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Public-client configuration does not support ${unsupported}`);\n }\n}\n\nfunction assertNativeSettings(settings: object): void {\n const unsupported = ['dpop', 'monitorSession', 'silent_redirect_uri', 'stateStore', 'userStore'].find(\n (key) => key in settings,\n );\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Native configuration does not support ${unsupported}`);\n }\n}\n\nfunction unsupportedConfiguration(platform: RuntimePlatform): never {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `No ${platform} configuration was provided`);\n}\n"]}
1
+ {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/configuration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { UserManagerSettings } from 'oidc-client-ts';\n\nimport type {\n CapacitorOidcNativeOptions,\n CapacitorSigninArgs,\n CapacitorSignoutArgs,\n CapacitorUserManagerConfiguration,\n CapacitorUserManagerSettings,\n} from './definitions.js';\nimport { CapacitorOidcError } from './errors.js';\nimport { WEB_ONLY_SETTINGS } from './user-manager-settings-policy.js';\n\nexport type RuntimePlatform = 'android' | 'ios' | 'web';\n\nexport interface ResolvedUserManagerConfiguration {\n platform: RuntimePlatform;\n settings: UserManagerSettings;\n nativeOptions?: CapacitorOidcNativeOptions;\n signinMode: 'popup' | 'redirect';\n signoutMode: 'popup' | 'redirect';\n signinArgs: CapacitorSigninArgs;\n signoutArgs: CapacitorSignoutArgs;\n}\n\nexport function resolveConfiguration(\n configuration: CapacitorUserManagerConfiguration,\n platform: RuntimePlatform,\n): ResolvedUserManagerConfiguration {\n if (platform === 'web') return resolveWebConfiguration(configuration);\n return resolveNativeConfiguration(configuration, platform);\n}\n\nexport function resolveLegacyNativeConfiguration(\n settings: CapacitorUserManagerSettings,\n nativeOptions: CapacitorOidcNativeOptions,\n platform: RuntimePlatform,\n): ResolvedUserManagerConfiguration {\n if (platform === 'web') {\n throw new CapacitorOidcError(\n 'UNSUPPORTED_RUNTIME',\n 'Legacy CapacitorUserManager settings are only supported on iOS and Android',\n );\n }\n\n assertPublicClient(settings);\n if ('dpop' in settings) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Native configuration does not support dpop');\n }\n\n return resolvedNativeConfiguration(platform, settings, nativeOptions);\n}\n\nfunction resolveWebConfiguration(configuration: CapacitorUserManagerConfiguration): ResolvedUserManagerConfiguration {\n const web = configuration.web;\n if (!web) unsupportedConfiguration('web');\n\n const signoutMode = web.signoutMode ?? 'redirect';\n const settings: UserManagerSettings = { ...configuration.common, ...web.settings };\n assertPublicClient(settings);\n if (signoutMode === 'popup' && !settings.popup_post_logout_redirect_uri && !settings.post_logout_redirect_uri) {\n throw new CapacitorOidcError(\n 'UNSUPPORTED_RUNTIME',\n 'Web popup signout requires post_logout_redirect_uri or popup_post_logout_redirect_uri',\n );\n }\n\n return {\n platform: 'web',\n settings,\n signinMode: web.signinMode ?? 'redirect',\n signoutMode,\n signinArgs: web.signinArgs ?? {},\n signoutArgs: web.signoutArgs ?? {},\n };\n}\n\nfunction resolveNativeConfiguration(\n configuration: CapacitorUserManagerConfiguration,\n platform: 'android' | 'ios',\n): ResolvedUserManagerConfiguration {\n const native = configuration.native;\n if (!native) unsupportedConfiguration(platform);\n\n const override = configuration[platform];\n const settings = { ...configuration.common, ...native.settings, ...override?.settings };\n assertPublicClient(settings);\n assertNativeSettings(settings);\n\n return resolvedNativeConfiguration(\n platform,\n settings,\n { ...native.options, ...override?.options },\n { ...native.signinArgs, ...override?.signinArgs },\n { ...native.signoutArgs, ...override?.signoutArgs },\n );\n}\n\nfunction resolvedNativeConfiguration(\n platform: 'android' | 'ios',\n settings: UserManagerSettings,\n nativeOptions: CapacitorOidcNativeOptions,\n signinArgs: CapacitorSigninArgs = {},\n signoutArgs: CapacitorSignoutArgs = {},\n): ResolvedUserManagerConfiguration {\n return {\n platform,\n settings: { ...settings, response_type: 'code', disablePKCE: false, monitorSession: false },\n nativeOptions,\n signinMode: 'popup',\n signoutMode: 'popup',\n signinArgs,\n signoutArgs,\n };\n}\n\nfunction assertPublicClient(settings: object): void {\n const unsupported = ['client_authentication', 'client_secret', 'disablePKCE', 'response_type'].find(\n (key) => key in settings,\n );\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Public-client configuration does not support ${unsupported}`);\n }\n}\n\nfunction assertNativeSettings(settings: object): void {\n const unsupported = WEB_ONLY_SETTINGS.find((key) => key in settings);\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Native configuration does not support ${unsupported}`);\n }\n}\n\nfunction unsupportedConfiguration(platform: RuntimePlatform): never {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `No ${platform} configuration was provided`);\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { SigninPopupArgs, SigninRedirectArgs, SignoutPopupArgs, SignoutRedirectArgs, UserManagerSettings } from 'oidc-client-ts';
2
+ import type { WebOnlySetting } from './user-manager-settings-policy.js';
2
3
  export type CapacitorOidcErrorCode = 'AUTH_SESSION_IN_PROGRESS' | 'USER_CANCELLED' | 'BROWSER_UNAVAILABLE' | 'INVALID_CALLBACK' | 'SECURE_STORAGE_ERROR' | 'UNSUPPORTED_RUNTIME';
3
4
  export interface IOSNativeOptions {
4
5
  keychainAccessGroup?: string;
@@ -11,12 +12,11 @@ export interface CapacitorOidcNativeOptions {
11
12
  }
12
13
  type UnsafePublicClientSettings = 'client_secret' | 'client_authentication' | 'disablePKCE' | 'response_type';
13
14
  type LegacyUnsupportedSettings = UnsafePublicClientSettings | 'dpop' | 'monitorSession' | 'silent_redirect_uri' | 'stateStore' | 'userStore';
14
- type WebOnlySettings = 'checkSessionIntervalInSeconds' | 'dpop' | 'iframeNotifyParentOrigin' | 'iframeScriptOrigin' | 'includeIdTokenInSilentSignout' | 'monitorAnonymousSession' | 'monitorSession' | 'popup_post_logout_redirect_uri' | 'popup_redirect_uri' | 'popupWindowFeatures' | 'popupWindowTarget' | 'query_status_response_type' | 'redirectMethod' | 'redirectTarget' | 'silent_redirect_uri' | 'silentRequestTimeoutInSeconds' | 'stateStore' | 'stopCheckSessionOnError' | 'userStore';
15
15
  type PublicClientUserManagerSettings = Omit<UserManagerSettings, UnsafePublicClientSettings>;
16
- type NativeUserManagerSettings = Omit<PublicClientUserManagerSettings, WebOnlySettings>;
16
+ type NativeUserManagerSettings = Omit<PublicClientUserManagerSettings, WebOnlySetting>;
17
17
  /** @deprecated Use CapacitorUserManagerConfiguration. */
18
18
  export type CapacitorUserManagerSettings = Omit<UserManagerSettings, LegacyUnsupportedSettings>;
19
- export type CapacitorUserManagerCommonSettings = Omit<PublicClientUserManagerSettings, WebOnlySettings | 'post_logout_redirect_uri' | 'redirect_uri'>;
19
+ export type CapacitorUserManagerCommonSettings = Omit<PublicClientUserManagerSettings, WebOnlySetting | 'post_logout_redirect_uri' | 'redirect_uri'>;
20
20
  export type CapacitorWebUserManagerSettings = Partial<Omit<PublicClientUserManagerSettings, 'redirect_uri'>> & {
21
21
  redirect_uri: string;
22
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n SigninPopupArgs,\n SigninRedirectArgs,\n SignoutPopupArgs,\n SignoutRedirectArgs,\n UserManagerSettings,\n} from 'oidc-client-ts';\n\nexport type CapacitorOidcErrorCode =\n | 'AUTH_SESSION_IN_PROGRESS'\n | 'USER_CANCELLED'\n | 'BROWSER_UNAVAILABLE'\n | 'INVALID_CALLBACK'\n | 'SECURE_STORAGE_ERROR'\n | 'UNSUPPORTED_RUNTIME';\n\nexport interface IOSNativeOptions {\n keychainAccessGroup?: string;\n keychainAccessibility?: 'afterFirstUnlockThisDeviceOnly' | 'whenUnlockedThisDeviceOnly';\n}\n\nexport interface CapacitorOidcNativeOptions {\n ios?: IOSNativeOptions;\n prefersEphemeralWebBrowserSession?: boolean;\n storageNamespace?: string;\n}\n\ntype UnsafePublicClientSettings = 'client_secret' | 'client_authentication' | 'disablePKCE' | 'response_type';\n\ntype LegacyUnsupportedSettings =\n | UnsafePublicClientSettings\n | 'dpop'\n | 'monitorSession'\n | 'silent_redirect_uri'\n | 'stateStore'\n | 'userStore';\n\ntype WebOnlySettings =\n | 'checkSessionIntervalInSeconds'\n | 'dpop'\n | 'iframeNotifyParentOrigin'\n | 'iframeScriptOrigin'\n | 'includeIdTokenInSilentSignout'\n | 'monitorAnonymousSession'\n | 'monitorSession'\n | 'popup_post_logout_redirect_uri'\n | 'popup_redirect_uri'\n | 'popupWindowFeatures'\n | 'popupWindowTarget'\n | 'query_status_response_type'\n | 'redirectMethod'\n | 'redirectTarget'\n | 'silent_redirect_uri'\n | 'silentRequestTimeoutInSeconds'\n | 'stateStore'\n | 'stopCheckSessionOnError'\n | 'userStore';\n\ntype PublicClientUserManagerSettings = Omit<UserManagerSettings, UnsafePublicClientSettings>;\ntype NativeUserManagerSettings = Omit<PublicClientUserManagerSettings, WebOnlySettings>;\n\n/** @deprecated Use CapacitorUserManagerConfiguration. */\nexport type CapacitorUserManagerSettings = Omit<UserManagerSettings, LegacyUnsupportedSettings>;\n\nexport type CapacitorUserManagerCommonSettings = Omit<\n PublicClientUserManagerSettings,\n WebOnlySettings | 'post_logout_redirect_uri' | 'redirect_uri'\n>;\n\nexport type CapacitorWebUserManagerSettings = Partial<Omit<PublicClientUserManagerSettings, 'redirect_uri'>> & {\n redirect_uri: string;\n};\n\nexport type CapacitorNativeUserManagerSettings = Partial<Omit<NativeUserManagerSettings, 'redirect_uri'>> & {\n redirect_uri: string;\n};\n\nexport type CapacitorSigninArgs = SigninPopupArgs & SigninRedirectArgs;\nexport type CapacitorSignoutArgs = SignoutPopupArgs & SignoutRedirectArgs;\n\ninterface CapacitorWebUserManagerConfigurationBase {\n settings: CapacitorWebUserManagerSettings;\n signinMode?: 'popup' | 'redirect';\n signinArgs?: CapacitorSigninArgs;\n signoutArgs?: CapacitorSignoutArgs;\n}\n\ntype PopupSignoutSettings = CapacitorWebUserManagerSettings &\n ({ popup_post_logout_redirect_uri: string } | { post_logout_redirect_uri: string });\n\nexport type CapacitorWebUserManagerConfiguration =\n | (CapacitorWebUserManagerConfigurationBase & {\n signoutMode: 'popup';\n settings: PopupSignoutSettings;\n })\n | (CapacitorWebUserManagerConfigurationBase & {\n signoutMode?: 'redirect';\n });\n\nexport interface CapacitorNativeUserManagerConfiguration {\n settings: CapacitorNativeUserManagerSettings;\n options?: CapacitorOidcNativeOptions;\n signinArgs?: CapacitorSigninArgs;\n signoutArgs?: CapacitorSignoutArgs;\n}\n\nexport interface CapacitorNativeUserManagerOverride {\n settings?: Partial<CapacitorNativeUserManagerSettings>;\n options?: CapacitorOidcNativeOptions;\n signinArgs?: CapacitorSigninArgs;\n signoutArgs?: CapacitorSignoutArgs;\n}\n\nexport interface CapacitorUserManagerConfiguration {\n common: CapacitorUserManagerCommonSettings;\n web?: CapacitorWebUserManagerConfiguration;\n native?: CapacitorNativeUserManagerConfiguration;\n ios?: CapacitorNativeUserManagerOverride;\n android?: CapacitorNativeUserManagerOverride;\n}\n\nexport interface StoredSessionV1 {\n version: 1;\n issuer: string;\n clientId: string;\n accessToken: string;\n refreshToken?: string;\n idToken?: string;\n tokenType: string;\n scope?: string;\n expiresAt?: number;\n}\n\nexport interface NativeOpenOptions {\n url: string;\n callbackUrl: string;\n prefersEphemeralWebBrowserSession: boolean;\n}\n\nexport interface NativeStorageOptions {\n namespace: string;\n key: string;\n}\n\nexport interface CapacitorOidcPlugin {\n configure(options: IOSNativeOptions): Promise<void>;\n open(options: NativeOpenOptions): Promise<{ url: string }>;\n cancel(): Promise<void>;\n storageSet(options: NativeStorageOptions & { value: string }): Promise<void>;\n storageGet(options: NativeStorageOptions): Promise<{ value: string | null }>;\n storageRemove(options: NativeStorageOptions): Promise<{ value: string | null }>;\n storageGetAllKeys(options: { namespace: string }): Promise<{ keys: string[] }>;\n setSessionSnapshot(options: { namespace: string; value: string | null }): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n SigninPopupArgs,\n SigninRedirectArgs,\n SignoutPopupArgs,\n SignoutRedirectArgs,\n UserManagerSettings,\n} from 'oidc-client-ts';\n\nimport type { WebOnlySetting } from './user-manager-settings-policy.js';\n\nexport type CapacitorOidcErrorCode =\n | 'AUTH_SESSION_IN_PROGRESS'\n | 'USER_CANCELLED'\n | 'BROWSER_UNAVAILABLE'\n | 'INVALID_CALLBACK'\n | 'SECURE_STORAGE_ERROR'\n | 'UNSUPPORTED_RUNTIME';\n\nexport interface IOSNativeOptions {\n keychainAccessGroup?: string;\n keychainAccessibility?: 'afterFirstUnlockThisDeviceOnly' | 'whenUnlockedThisDeviceOnly';\n}\n\nexport interface CapacitorOidcNativeOptions {\n ios?: IOSNativeOptions;\n prefersEphemeralWebBrowserSession?: boolean;\n storageNamespace?: string;\n}\n\ntype UnsafePublicClientSettings = 'client_secret' | 'client_authentication' | 'disablePKCE' | 'response_type';\n\ntype LegacyUnsupportedSettings =\n | UnsafePublicClientSettings\n | 'dpop'\n | 'monitorSession'\n | 'silent_redirect_uri'\n | 'stateStore'\n | 'userStore';\n\ntype PublicClientUserManagerSettings = Omit<UserManagerSettings, UnsafePublicClientSettings>;\ntype NativeUserManagerSettings = Omit<PublicClientUserManagerSettings, WebOnlySetting>;\n\n/** @deprecated Use CapacitorUserManagerConfiguration. */\nexport type CapacitorUserManagerSettings = Omit<UserManagerSettings, LegacyUnsupportedSettings>;\n\nexport type CapacitorUserManagerCommonSettings = Omit<\n PublicClientUserManagerSettings,\n WebOnlySetting | 'post_logout_redirect_uri' | 'redirect_uri'\n>;\n\nexport type CapacitorWebUserManagerSettings = Partial<Omit<PublicClientUserManagerSettings, 'redirect_uri'>> & {\n redirect_uri: string;\n};\n\nexport type CapacitorNativeUserManagerSettings = Partial<Omit<NativeUserManagerSettings, 'redirect_uri'>> & {\n redirect_uri: string;\n};\n\nexport type CapacitorSigninArgs = SigninPopupArgs & SigninRedirectArgs;\nexport type CapacitorSignoutArgs = SignoutPopupArgs & SignoutRedirectArgs;\n\ninterface CapacitorWebUserManagerConfigurationBase {\n settings: CapacitorWebUserManagerSettings;\n signinMode?: 'popup' | 'redirect';\n signinArgs?: CapacitorSigninArgs;\n signoutArgs?: CapacitorSignoutArgs;\n}\n\ntype PopupSignoutSettings = CapacitorWebUserManagerSettings &\n ({ popup_post_logout_redirect_uri: string } | { post_logout_redirect_uri: string });\n\nexport type CapacitorWebUserManagerConfiguration =\n | (CapacitorWebUserManagerConfigurationBase & {\n signoutMode: 'popup';\n settings: PopupSignoutSettings;\n })\n | (CapacitorWebUserManagerConfigurationBase & {\n signoutMode?: 'redirect';\n });\n\nexport interface CapacitorNativeUserManagerConfiguration {\n settings: CapacitorNativeUserManagerSettings;\n options?: CapacitorOidcNativeOptions;\n signinArgs?: CapacitorSigninArgs;\n signoutArgs?: CapacitorSignoutArgs;\n}\n\nexport interface CapacitorNativeUserManagerOverride {\n settings?: Partial<CapacitorNativeUserManagerSettings>;\n options?: CapacitorOidcNativeOptions;\n signinArgs?: CapacitorSigninArgs;\n signoutArgs?: CapacitorSignoutArgs;\n}\n\nexport interface CapacitorUserManagerConfiguration {\n common: CapacitorUserManagerCommonSettings;\n web?: CapacitorWebUserManagerConfiguration;\n native?: CapacitorNativeUserManagerConfiguration;\n ios?: CapacitorNativeUserManagerOverride;\n android?: CapacitorNativeUserManagerOverride;\n}\n\nexport interface StoredSessionV1 {\n version: 1;\n issuer: string;\n clientId: string;\n accessToken: string;\n refreshToken?: string;\n idToken?: string;\n tokenType: string;\n scope?: string;\n expiresAt?: number;\n}\n\nexport interface NativeOpenOptions {\n url: string;\n callbackUrl: string;\n prefersEphemeralWebBrowserSession: boolean;\n}\n\nexport interface NativeStorageOptions {\n namespace: string;\n key: string;\n}\n\nexport interface CapacitorOidcPlugin {\n configure(options: IOSNativeOptions): Promise<void>;\n open(options: NativeOpenOptions): Promise<{ url: string }>;\n cancel(): Promise<void>;\n storageSet(options: NativeStorageOptions & { value: string }): Promise<void>;\n storageGet(options: NativeStorageOptions): Promise<{ value: string | null }>;\n storageRemove(options: NativeStorageOptions): Promise<{ value: string | null }>;\n storageGetAllKeys(options: { namespace: string }): Promise<{ keys: string[] }>;\n setSessionSnapshot(options: { namespace: string; value: string | null }): Promise<void>;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const WEB_ONLY_SETTINGS: readonly ["checkSessionIntervalInSeconds", "dpop", "iframeNotifyParentOrigin", "iframeScriptOrigin", "includeIdTokenInSilentSignout", "monitorAnonymousSession", "monitorSession", "popup_post_logout_redirect_uri", "popup_redirect_uri", "popupWindowFeatures", "popupWindowTarget", "query_status_response_type", "redirectMethod", "redirectTarget", "silent_redirect_uri", "silentRequestTimeoutInSeconds", "stateStore", "stopCheckSessionOnError", "userStore"];
2
+ export type WebOnlySetting = (typeof WEB_ONLY_SETTINGS)[number];
@@ -0,0 +1,22 @@
1
+ export const WEB_ONLY_SETTINGS = [
2
+ 'checkSessionIntervalInSeconds',
3
+ 'dpop',
4
+ 'iframeNotifyParentOrigin',
5
+ 'iframeScriptOrigin',
6
+ 'includeIdTokenInSilentSignout',
7
+ 'monitorAnonymousSession',
8
+ 'monitorSession',
9
+ 'popup_post_logout_redirect_uri',
10
+ 'popup_redirect_uri',
11
+ 'popupWindowFeatures',
12
+ 'popupWindowTarget',
13
+ 'query_status_response_type',
14
+ 'redirectMethod',
15
+ 'redirectTarget',
16
+ 'silent_redirect_uri',
17
+ 'silentRequestTimeoutInSeconds',
18
+ 'stateStore',
19
+ 'stopCheckSessionOnError',
20
+ 'userStore',
21
+ ];
22
+ //# sourceMappingURL=user-manager-settings-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-manager-settings-policy.js","sourceRoot":"","sources":["../../src/user-manager-settings-policy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,+BAA+B;IAC/B,MAAM;IACN,0BAA0B;IAC1B,oBAAoB;IACpB,+BAA+B;IAC/B,yBAAyB;IACzB,gBAAgB;IAChB,gCAAgC;IAChC,oBAAoB;IACpB,qBAAqB;IACrB,mBAAmB;IACnB,4BAA4B;IAC5B,gBAAgB;IAChB,gBAAgB;IAChB,qBAAqB;IACrB,+BAA+B;IAC/B,YAAY;IACZ,yBAAyB;IACzB,WAAW;CACH,CAAC","sourcesContent":["export const WEB_ONLY_SETTINGS = [\n 'checkSessionIntervalInSeconds',\n 'dpop',\n 'iframeNotifyParentOrigin',\n 'iframeScriptOrigin',\n 'includeIdTokenInSilentSignout',\n 'monitorAnonymousSession',\n 'monitorSession',\n 'popup_post_logout_redirect_uri',\n 'popup_redirect_uri',\n 'popupWindowFeatures',\n 'popupWindowTarget',\n 'query_status_response_type',\n 'redirectMethod',\n 'redirectTarget',\n 'silent_redirect_uri',\n 'silentRequestTimeoutInSeconds',\n 'stateStore',\n 'stopCheckSessionOnError',\n 'userStore',\n] as const;\n\nexport type WebOnlySetting = (typeof WEB_ONLY_SETTINGS)[number];\n"]}
package/dist/plugin.cjs CHANGED
@@ -118,6 +118,28 @@ class BaseCapacitorUserManager extends oidcClientTs.UserManager {
118
118
  }
119
119
  }
120
120
 
121
+ const WEB_ONLY_SETTINGS = [
122
+ 'checkSessionIntervalInSeconds',
123
+ 'dpop',
124
+ 'iframeNotifyParentOrigin',
125
+ 'iframeScriptOrigin',
126
+ 'includeIdTokenInSilentSignout',
127
+ 'monitorAnonymousSession',
128
+ 'monitorSession',
129
+ 'popup_post_logout_redirect_uri',
130
+ 'popup_redirect_uri',
131
+ 'popupWindowFeatures',
132
+ 'popupWindowTarget',
133
+ 'query_status_response_type',
134
+ 'redirectMethod',
135
+ 'redirectTarget',
136
+ 'silent_redirect_uri',
137
+ 'silentRequestTimeoutInSeconds',
138
+ 'stateStore',
139
+ 'stopCheckSessionOnError',
140
+ 'userStore',
141
+ ];
142
+
121
143
  function resolveConfiguration(configuration, platform) {
122
144
  if (platform === 'web')
123
145
  return resolveWebConfiguration(configuration);
@@ -180,7 +202,7 @@ function assertPublicClient(settings) {
180
202
  }
181
203
  }
182
204
  function assertNativeSettings(settings) {
183
- const unsupported = ['dpop', 'monitorSession', 'silent_redirect_uri', 'stateStore', 'userStore'].find((key) => key in settings);
205
+ const unsupported = WEB_ONLY_SETTINGS.find((key) => key in settings);
184
206
  if (unsupported) {
185
207
  throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Native configuration does not support ${unsupported}`);
186
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs","sources":["esm/errors.js","esm/base-capacitor-user-manager.js","esm/configuration.js","esm/capacitor-user-manager.js","esm/native.js","esm/capacitor-navigator.js","esm/capacitor-secure-state-store.js","esm/native-capacitor-user-manager.js","esm/web-capacitor-user-manager.js","esm/index.js"],"sourcesContent":["export class CapacitorOidcError extends Error {\n code;\n constructor(code, message) {\n super(message);\n this.code = code;\n this.name = 'CapacitorOidcError';\n }\n}\nexport function unsupported(feature) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `${feature} is not available in a native Capacitor runtime`);\n}\n//# sourceMappingURL=errors.js.map","import { UserManager, } from 'oidc-client-ts';\nimport { unsupported } from './errors.js';\nexport class BaseCapacitorUserManager extends UserManager {\n automaticRenewalPromise;\n refreshPromise;\n signinMode;\n signoutMode;\n defaultSigninArgs;\n defaultSignoutArgs;\n constructor(configuration, redirectNavigator, popupNavigator, iframeNavigator) {\n super(configuration.settings, redirectNavigator, popupNavigator, iframeNavigator);\n this.signinMode = configuration.signinMode;\n this.signoutMode = configuration.signoutMode;\n this.defaultSigninArgs = configuration.signinArgs;\n this.defaultSignoutArgs = configuration.signoutArgs;\n }\n async initialize() {\n await this.getUser();\n }\n async signin(args = {}) {\n const mergedArgs = { ...this.defaultSigninArgs, ...args };\n if (this.signinMode === 'redirect')\n return this.signinRedirect(mergedArgs);\n await this.signinPopup(mergedArgs);\n }\n async signout(args = {}) {\n const mergedArgs = { ...this.defaultSignoutArgs, ...args };\n if (this.signoutMode === 'redirect')\n return this.signoutRedirect(mergedArgs);\n await this.signoutPopup(mergedArgs);\n }\n async getValidUser(minimumValiditySeconds = 60) {\n const user = await this.getUser();\n if (!user)\n return null;\n if (user.expires_in === undefined || user.expires_in > minimumValiditySeconds)\n return user;\n return this.signinSilent();\n }\n async signinPopup(args = {}) {\n await this.waitForRenewal();\n return super.signinPopup(args);\n }\n async signoutPopup(args = {}) {\n await this.waitForRenewal();\n await super.signoutPopup(args);\n }\n async signinRedirect(args = {}) {\n await this.waitForRenewal();\n await super.signinRedirect(args);\n }\n async signoutRedirect(args = {}) {\n await this.waitForRenewal();\n await super.signoutRedirect(args);\n }\n signinSilent(args = {}) {\n if (!this.refreshPromise) {\n const refresh = this.performSilentSignin(args);\n this.refreshPromise = refresh.finally(() => {\n this.refreshPromise = undefined;\n });\n }\n return this.refreshPromise;\n }\n async signinResourceOwnerCredentials(_args) {\n unsupported('Resource Owner Password Credentials');\n }\n async removeUser() {\n await this.waitForRenewal();\n await this.removeUserWithoutWaiting();\n }\n cancel() {\n return Promise.resolve();\n }\n async dispose() {\n this.stopSilentRenew();\n await this.disposePlatform();\n await this.waitForRenewal();\n await this.cancel();\n }\n performSilentSignin(args) {\n return super.signinSilent(args);\n }\n removeUserWithoutWaiting() {\n return super.removeUser();\n }\n checkForAutomaticRenewal() {\n if (!this.settings.automaticSilentRenew || this.automaticRenewalPromise)\n return;\n const renewal = this.getValidUser();\n this.automaticRenewalPromise = renewal;\n void renewal\n .catch((error) => this.events._raiseSilentRenewError(error instanceof Error ? error : new Error('Silent renewal failed')))\n .finally(() => {\n if (this.automaticRenewalPromise === renewal)\n this.automaticRenewalPromise = undefined;\n });\n }\n async waitForRenewal() {\n await this.automaticRenewalPromise?.catch(() => undefined);\n await this.refreshPromise?.catch(() => undefined);\n }\n}\n//# sourceMappingURL=base-capacitor-user-manager.js.map","import { CapacitorOidcError } from './errors.js';\nexport function resolveConfiguration(configuration, platform) {\n if (platform === 'web')\n return resolveWebConfiguration(configuration);\n return resolveNativeConfiguration(configuration, platform);\n}\nexport function resolveLegacyNativeConfiguration(settings, nativeOptions, platform) {\n if (platform === 'web') {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Legacy CapacitorUserManager settings are only supported on iOS and Android');\n }\n assertPublicClient(settings);\n if ('dpop' in settings) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Native configuration does not support dpop');\n }\n return resolvedNativeConfiguration(platform, settings, nativeOptions);\n}\nfunction resolveWebConfiguration(configuration) {\n const web = configuration.web;\n if (!web)\n unsupportedConfiguration('web');\n const signoutMode = web.signoutMode ?? 'redirect';\n const settings = { ...configuration.common, ...web.settings };\n assertPublicClient(settings);\n if (signoutMode === 'popup' && !settings.popup_post_logout_redirect_uri && !settings.post_logout_redirect_uri) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Web popup signout requires post_logout_redirect_uri or popup_post_logout_redirect_uri');\n }\n return {\n platform: 'web',\n settings,\n signinMode: web.signinMode ?? 'redirect',\n signoutMode,\n signinArgs: web.signinArgs ?? {},\n signoutArgs: web.signoutArgs ?? {},\n };\n}\nfunction resolveNativeConfiguration(configuration, platform) {\n const native = configuration.native;\n if (!native)\n unsupportedConfiguration(platform);\n const override = configuration[platform];\n const settings = { ...configuration.common, ...native.settings, ...override?.settings };\n assertPublicClient(settings);\n assertNativeSettings(settings);\n return resolvedNativeConfiguration(platform, settings, { ...native.options, ...override?.options }, { ...native.signinArgs, ...override?.signinArgs }, { ...native.signoutArgs, ...override?.signoutArgs });\n}\nfunction resolvedNativeConfiguration(platform, settings, nativeOptions, signinArgs = {}, signoutArgs = {}) {\n return {\n platform,\n settings: { ...settings, response_type: 'code', disablePKCE: false, monitorSession: false },\n nativeOptions,\n signinMode: 'popup',\n signoutMode: 'popup',\n signinArgs,\n signoutArgs,\n };\n}\nfunction assertPublicClient(settings) {\n const unsupported = ['client_authentication', 'client_secret', 'disablePKCE', 'response_type'].find((key) => key in settings);\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Public-client configuration does not support ${unsupported}`);\n }\n}\nfunction assertNativeSettings(settings) {\n const unsupported = ['dpop', 'monitorSession', 'silent_redirect_uri', 'stateStore', 'userStore'].find((key) => key in settings);\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Native configuration does not support ${unsupported}`);\n }\n}\nfunction unsupportedConfiguration(platform) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `No ${platform} configuration was provided`);\n}\n//# sourceMappingURL=configuration.js.map","import { Capacitor } from '@capacitor/core';\nimport { BaseCapacitorUserManager } from './base-capacitor-user-manager.js';\nimport { resolveConfiguration, resolveLegacyNativeConfiguration, } from './configuration.js';\nimport { CapacitorOidcError } from './errors.js';\nexport class CapacitorUserManager extends BaseCapacitorUserManager {\n static async create(configuration, nativeOptions = {}) {\n assertRuntime();\n const platform = currentPlatform();\n const resolved = 'redirect_uri' in configuration\n ? resolveLegacyNativeConfiguration(configuration, nativeOptions, platform)\n : resolveConfiguration(configuration, platform);\n const manager = await platformUserManagerFactory(resolved);\n await manager.initialize();\n return manager;\n }\n}\nlet platformUserManagerFactory;\nexport function setPlatformUserManagerFactory(factory) {\n platformUserManagerFactory = factory;\n}\nfunction currentPlatform() {\n const platform = Capacitor.getPlatform();\n return platform === 'ios' || platform === 'android' ? platform : 'web';\n}\nfunction assertRuntime() {\n if (!globalThis.crypto?.subtle || !globalThis.crypto.getRandomValues) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Web Crypto is required by oidc-client-ts');\n }\n}\n//# sourceMappingURL=capacitor-user-manager.js.map","import { registerPlugin } from '@capacitor/core';\nexport const NativeOidc = registerPlugin('CapacitorOidc');\n//# sourceMappingURL=native.js.map","import { CapacitorOidcError, unsupported } from './errors.js';\nimport { NativeOidc } from './native.js';\nexport class CapacitorNavigator {\n prefersEphemeralWebBrowserSession;\n constructor(prefersEphemeralWebBrowserSession) {\n this.prefersEphemeralWebBrowserSession = prefersEphemeralWebBrowserSession;\n }\n async prepare() {\n return new CapacitorWindow(this.prefersEphemeralWebBrowserSession);\n }\n async callback() {\n unsupported('Navigator callbacks');\n }\n}\nclass CapacitorWindow {\n prefersEphemeralWebBrowserSession;\n constructor(prefersEphemeralWebBrowserSession) {\n this.prefersEphemeralWebBrowserSession = prefersEphemeralWebBrowserSession;\n }\n async navigate({ url }) {\n assertSecureRequestUrl(url);\n const callbackUrl = callbackUrlFromRequest(url);\n const response = await NativeOidc.open({\n url,\n callbackUrl,\n prefersEphemeralWebBrowserSession: this.prefersEphemeralWebBrowserSession,\n });\n if (!isExpectedCallback(response.url, callbackUrl)) {\n throw new CapacitorOidcError('INVALID_CALLBACK', 'The authentication callback does not match the configured redirect URI');\n }\n return response;\n }\n close() {\n void NativeOidc.cancel();\n }\n}\nexport function assertSecureRequestUrl(requestUrl) {\n const url = new URL(requestUrl);\n const isHttpLoopback = url.protocol === 'http:' &&\n (url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]');\n if (url.protocol !== 'https:' && !isHttpLoopback) {\n throw new CapacitorOidcError('BROWSER_UNAVAILABLE', 'OIDC authorization and logout endpoints must use HTTPS');\n }\n}\nexport function callbackUrlFromRequest(requestUrl) {\n const url = new URL(requestUrl);\n const callback = url.searchParams.get('post_logout_redirect_uri') ??\n url.searchParams.get('logout_uri') ??\n url.searchParams.get('redirect_uri');\n if (!callback) {\n throw new CapacitorOidcError('INVALID_CALLBACK', 'The OIDC request does not contain a callback URI');\n }\n return callback;\n}\nexport function isExpectedCallback(actualValue, expectedValue) {\n const actual = new URL(actualValue);\n const expected = new URL(expectedValue);\n return (actual.protocol.toLowerCase() === expected.protocol.toLowerCase() &&\n actual.host.toLowerCase() === expected.host.toLowerCase() &&\n actual.pathname === expected.pathname);\n}\nexport class UnsupportedIframeNavigator {\n async prepare() {\n unsupported('Iframe navigation');\n }\n async callback() {\n unsupported('Iframe navigation');\n }\n}\n//# sourceMappingURL=capacitor-navigator.js.map","import { NativeOidc } from './native.js';\nexport class CapacitorSecureStateStore {\n namespace;\n constructor(namespace) {\n this.namespace = namespace;\n }\n async set(key, value) {\n await NativeOidc.storageSet({ namespace: this.namespace, key, value });\n }\n async get(key) {\n return (await NativeOidc.storageGet({ namespace: this.namespace, key })).value;\n }\n async remove(key) {\n return (await NativeOidc.storageRemove({ namespace: this.namespace, key })).value;\n }\n async getAllKeys() {\n return (await NativeOidc.storageGetAllKeys({ namespace: this.namespace })).keys;\n }\n}\n//# sourceMappingURL=capacitor-secure-state-store.js.map","import { App } from '@capacitor/app';\nimport { ErrorResponse, } from 'oidc-client-ts';\nimport { CapacitorNavigator, UnsupportedIframeNavigator } from './capacitor-navigator.js';\nimport { CapacitorSecureStateStore } from './capacitor-secure-state-store.js';\nimport { CapacitorUserManager } from './capacitor-user-manager.js';\nimport { unsupported } from './errors.js';\nimport { NativeOidc } from './native.js';\nexport class NativeCapacitorUserManager extends CapacitorUserManager {\n appStateListener;\n storageNamespace;\n constructor(configuration) {\n const storageNamespace = configuration.nativeOptions?.storageNamespace ?? 'default';\n const stateStore = new CapacitorSecureStateStore(`${storageNamespace}.transactions`);\n const userStore = new CapacitorSecureStateStore(`${storageNamespace}.session`);\n const navigator = new CapacitorNavigator(configuration.nativeOptions?.prefersEphemeralWebBrowserSession ?? false);\n super({\n ...configuration,\n settings: {\n ...configuration.settings,\n popup_redirect_uri: configuration.settings.redirect_uri,\n popup_post_logout_redirect_uri: configuration.settings.post_logout_redirect_uri,\n stateStore,\n userStore,\n },\n }, navigator, navigator, new UnsupportedIframeNavigator());\n this.storageNamespace = storageNamespace;\n }\n static async fromConfiguration(configuration) {\n await NativeOidc.configure(configuration.nativeOptions?.ios ?? {});\n return new NativeCapacitorUserManager(configuration);\n }\n async initialize() {\n await super.initialize();\n this.appStateListener = await App.addListener('appStateChange', ({ isActive }) => {\n if (isActive)\n this.checkForAutomaticRenewal();\n });\n this.checkForAutomaticRenewal();\n }\n async signinRedirect(_args = {}) {\n unsupported('Redirect navigation');\n }\n async signinRedirectCallback(_url) {\n unsupported('Redirect navigation');\n }\n async signinCallback(_url) {\n unsupported('Browser callback dispatch');\n }\n async signinSilentCallback(_url) {\n unsupported('Iframe navigation');\n }\n async signoutRedirect(_args = {}) {\n unsupported('Redirect navigation');\n }\n async signoutRedirectCallback(_url) {\n unsupported('Redirect navigation');\n }\n async signoutCallback(_url, _keepOpen) {\n unsupported('Browser callback dispatch');\n }\n async signoutSilent(_args = {}) {\n unsupported('Iframe logout');\n }\n async signoutSilentCallback(_url) {\n unsupported('Iframe logout');\n }\n async querySessionStatus(_args = {}) {\n unsupported('Browser session monitoring');\n }\n async storeUser(user) {\n await super.storeUser(user);\n await NativeOidc.setSessionSnapshot({\n namespace: this.storageNamespace,\n value: user\n ? JSON.stringify(toStoredSession(user, user.profile.iss ?? this.settings.metadata?.issuer ?? this.settings.authority, this.settings.client_id))\n : null,\n });\n }\n cancel() {\n return NativeOidc.cancel();\n }\n async disposePlatform() {\n await this.appStateListener?.remove();\n }\n async performSilentSignin(args) {\n const user = await this.getUser();\n if (!user?.refresh_token) {\n if (user?.expired)\n await this.removeUserWithoutWaiting();\n return null;\n }\n return super.performSilentSignin({ ...args, forceIframeAuth: false }).catch(async (error) => {\n if (error instanceof ErrorResponse && error.error === 'invalid_grant')\n await this.removeUserWithoutWaiting();\n throw error;\n });\n }\n}\nfunction toStoredSession(user, issuer, clientId) {\n return {\n version: 1,\n issuer,\n clientId,\n accessToken: user.access_token,\n refreshToken: user.refresh_token,\n idToken: user.id_token,\n tokenType: user.token_type,\n scope: user.scope,\n expiresAt: user.expires_at,\n };\n}\n//# sourceMappingURL=native-capacitor-user-manager.js.map","import { CapacitorUserManager } from './capacitor-user-manager.js';\nexport class WebCapacitorUserManager extends CapacitorUserManager {\n sessionMonitor;\n disposed = false;\n constructor(configuration) {\n super(configuration);\n this.sessionMonitor = this.captureSessionMonitor();\n }\n async querySessionStatus(args = {}) {\n if (this.disposed)\n return null;\n const session = await super.querySessionStatus(args);\n return this.disposed ? null : session;\n }\n disposePlatform() {\n this.disposed = true;\n if (this.sessionMonitor) {\n this.events.removeUserLoaded(this.sessionMonitor.start);\n this.events.removeUserUnloaded(this.sessionMonitor.stop);\n this.sessionMonitor.stop();\n }\n return Promise.resolve();\n }\n captureSessionMonitor() {\n // oidc-client-ts does not expose public session-monitor lifecycle hooks.\n const monitor = this._sessionMonitor;\n if (!monitor)\n return undefined;\n const originalStart = monitor._start;\n const stop = monitor._stop;\n const start = async (user) => {\n if (this.disposed)\n return;\n await originalStart(user);\n if (this.disposed)\n stop();\n };\n this.events.removeUserLoaded(originalStart);\n this.events.addUserLoaded(start);\n monitor._start = start;\n return { start, stop };\n }\n}\n//# sourceMappingURL=web-capacitor-user-manager.js.map","import { CapacitorUserManager, setPlatformUserManagerFactory } from './capacitor-user-manager.js';\nimport { NativeCapacitorUserManager } from './native-capacitor-user-manager.js';\nimport { WebCapacitorUserManager } from './web-capacitor-user-manager.js';\nsetPlatformUserManagerFactory((configuration) => configuration.platform === 'web'\n ? new WebCapacitorUserManager(configuration)\n : NativeCapacitorUserManager.fromConfiguration(configuration));\nexport { CapacitorUserManager };\nexport { CapacitorSecureStateStore } from './capacitor-secure-state-store.js';\nexport { CapacitorOidcError } from './errors.js';\nexport { User, WebStorageStateStore } from 'oidc-client-ts';\n//# sourceMappingURL=index.js.map"],"names":["UserManager","Capacitor","registerPlugin","App","ErrorResponse"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.cjs","sources":["esm/errors.js","esm/base-capacitor-user-manager.js","esm/user-manager-settings-policy.js","esm/configuration.js","esm/capacitor-user-manager.js","esm/native.js","esm/capacitor-navigator.js","esm/capacitor-secure-state-store.js","esm/native-capacitor-user-manager.js","esm/web-capacitor-user-manager.js","esm/index.js"],"sourcesContent":["export class CapacitorOidcError extends Error {\n code;\n constructor(code, message) {\n super(message);\n this.code = code;\n this.name = 'CapacitorOidcError';\n }\n}\nexport function unsupported(feature) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `${feature} is not available in a native Capacitor runtime`);\n}\n//# sourceMappingURL=errors.js.map","import { UserManager, } from 'oidc-client-ts';\nimport { unsupported } from './errors.js';\nexport class BaseCapacitorUserManager extends UserManager {\n automaticRenewalPromise;\n refreshPromise;\n signinMode;\n signoutMode;\n defaultSigninArgs;\n defaultSignoutArgs;\n constructor(configuration, redirectNavigator, popupNavigator, iframeNavigator) {\n super(configuration.settings, redirectNavigator, popupNavigator, iframeNavigator);\n this.signinMode = configuration.signinMode;\n this.signoutMode = configuration.signoutMode;\n this.defaultSigninArgs = configuration.signinArgs;\n this.defaultSignoutArgs = configuration.signoutArgs;\n }\n async initialize() {\n await this.getUser();\n }\n async signin(args = {}) {\n const mergedArgs = { ...this.defaultSigninArgs, ...args };\n if (this.signinMode === 'redirect')\n return this.signinRedirect(mergedArgs);\n await this.signinPopup(mergedArgs);\n }\n async signout(args = {}) {\n const mergedArgs = { ...this.defaultSignoutArgs, ...args };\n if (this.signoutMode === 'redirect')\n return this.signoutRedirect(mergedArgs);\n await this.signoutPopup(mergedArgs);\n }\n async getValidUser(minimumValiditySeconds = 60) {\n const user = await this.getUser();\n if (!user)\n return null;\n if (user.expires_in === undefined || user.expires_in > minimumValiditySeconds)\n return user;\n return this.signinSilent();\n }\n async signinPopup(args = {}) {\n await this.waitForRenewal();\n return super.signinPopup(args);\n }\n async signoutPopup(args = {}) {\n await this.waitForRenewal();\n await super.signoutPopup(args);\n }\n async signinRedirect(args = {}) {\n await this.waitForRenewal();\n await super.signinRedirect(args);\n }\n async signoutRedirect(args = {}) {\n await this.waitForRenewal();\n await super.signoutRedirect(args);\n }\n signinSilent(args = {}) {\n if (!this.refreshPromise) {\n const refresh = this.performSilentSignin(args);\n this.refreshPromise = refresh.finally(() => {\n this.refreshPromise = undefined;\n });\n }\n return this.refreshPromise;\n }\n async signinResourceOwnerCredentials(_args) {\n unsupported('Resource Owner Password Credentials');\n }\n async removeUser() {\n await this.waitForRenewal();\n await this.removeUserWithoutWaiting();\n }\n cancel() {\n return Promise.resolve();\n }\n async dispose() {\n this.stopSilentRenew();\n await this.disposePlatform();\n await this.waitForRenewal();\n await this.cancel();\n }\n performSilentSignin(args) {\n return super.signinSilent(args);\n }\n removeUserWithoutWaiting() {\n return super.removeUser();\n }\n checkForAutomaticRenewal() {\n if (!this.settings.automaticSilentRenew || this.automaticRenewalPromise)\n return;\n const renewal = this.getValidUser();\n this.automaticRenewalPromise = renewal;\n void renewal\n .catch((error) => this.events._raiseSilentRenewError(error instanceof Error ? error : new Error('Silent renewal failed')))\n .finally(() => {\n if (this.automaticRenewalPromise === renewal)\n this.automaticRenewalPromise = undefined;\n });\n }\n async waitForRenewal() {\n await this.automaticRenewalPromise?.catch(() => undefined);\n await this.refreshPromise?.catch(() => undefined);\n }\n}\n//# sourceMappingURL=base-capacitor-user-manager.js.map","export const WEB_ONLY_SETTINGS = [\n 'checkSessionIntervalInSeconds',\n 'dpop',\n 'iframeNotifyParentOrigin',\n 'iframeScriptOrigin',\n 'includeIdTokenInSilentSignout',\n 'monitorAnonymousSession',\n 'monitorSession',\n 'popup_post_logout_redirect_uri',\n 'popup_redirect_uri',\n 'popupWindowFeatures',\n 'popupWindowTarget',\n 'query_status_response_type',\n 'redirectMethod',\n 'redirectTarget',\n 'silent_redirect_uri',\n 'silentRequestTimeoutInSeconds',\n 'stateStore',\n 'stopCheckSessionOnError',\n 'userStore',\n];\n//# sourceMappingURL=user-manager-settings-policy.js.map","import { CapacitorOidcError } from './errors.js';\nimport { WEB_ONLY_SETTINGS } from './user-manager-settings-policy.js';\nexport function resolveConfiguration(configuration, platform) {\n if (platform === 'web')\n return resolveWebConfiguration(configuration);\n return resolveNativeConfiguration(configuration, platform);\n}\nexport function resolveLegacyNativeConfiguration(settings, nativeOptions, platform) {\n if (platform === 'web') {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Legacy CapacitorUserManager settings are only supported on iOS and Android');\n }\n assertPublicClient(settings);\n if ('dpop' in settings) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Native configuration does not support dpop');\n }\n return resolvedNativeConfiguration(platform, settings, nativeOptions);\n}\nfunction resolveWebConfiguration(configuration) {\n const web = configuration.web;\n if (!web)\n unsupportedConfiguration('web');\n const signoutMode = web.signoutMode ?? 'redirect';\n const settings = { ...configuration.common, ...web.settings };\n assertPublicClient(settings);\n if (signoutMode === 'popup' && !settings.popup_post_logout_redirect_uri && !settings.post_logout_redirect_uri) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Web popup signout requires post_logout_redirect_uri or popup_post_logout_redirect_uri');\n }\n return {\n platform: 'web',\n settings,\n signinMode: web.signinMode ?? 'redirect',\n signoutMode,\n signinArgs: web.signinArgs ?? {},\n signoutArgs: web.signoutArgs ?? {},\n };\n}\nfunction resolveNativeConfiguration(configuration, platform) {\n const native = configuration.native;\n if (!native)\n unsupportedConfiguration(platform);\n const override = configuration[platform];\n const settings = { ...configuration.common, ...native.settings, ...override?.settings };\n assertPublicClient(settings);\n assertNativeSettings(settings);\n return resolvedNativeConfiguration(platform, settings, { ...native.options, ...override?.options }, { ...native.signinArgs, ...override?.signinArgs }, { ...native.signoutArgs, ...override?.signoutArgs });\n}\nfunction resolvedNativeConfiguration(platform, settings, nativeOptions, signinArgs = {}, signoutArgs = {}) {\n return {\n platform,\n settings: { ...settings, response_type: 'code', disablePKCE: false, monitorSession: false },\n nativeOptions,\n signinMode: 'popup',\n signoutMode: 'popup',\n signinArgs,\n signoutArgs,\n };\n}\nfunction assertPublicClient(settings) {\n const unsupported = ['client_authentication', 'client_secret', 'disablePKCE', 'response_type'].find((key) => key in settings);\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Public-client configuration does not support ${unsupported}`);\n }\n}\nfunction assertNativeSettings(settings) {\n const unsupported = WEB_ONLY_SETTINGS.find((key) => key in settings);\n if (unsupported) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `Native configuration does not support ${unsupported}`);\n }\n}\nfunction unsupportedConfiguration(platform) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', `No ${platform} configuration was provided`);\n}\n//# sourceMappingURL=configuration.js.map","import { Capacitor } from '@capacitor/core';\nimport { BaseCapacitorUserManager } from './base-capacitor-user-manager.js';\nimport { resolveConfiguration, resolveLegacyNativeConfiguration, } from './configuration.js';\nimport { CapacitorOidcError } from './errors.js';\nexport class CapacitorUserManager extends BaseCapacitorUserManager {\n static async create(configuration, nativeOptions = {}) {\n assertRuntime();\n const platform = currentPlatform();\n const resolved = 'redirect_uri' in configuration\n ? resolveLegacyNativeConfiguration(configuration, nativeOptions, platform)\n : resolveConfiguration(configuration, platform);\n const manager = await platformUserManagerFactory(resolved);\n await manager.initialize();\n return manager;\n }\n}\nlet platformUserManagerFactory;\nexport function setPlatformUserManagerFactory(factory) {\n platformUserManagerFactory = factory;\n}\nfunction currentPlatform() {\n const platform = Capacitor.getPlatform();\n return platform === 'ios' || platform === 'android' ? platform : 'web';\n}\nfunction assertRuntime() {\n if (!globalThis.crypto?.subtle || !globalThis.crypto.getRandomValues) {\n throw new CapacitorOidcError('UNSUPPORTED_RUNTIME', 'Web Crypto is required by oidc-client-ts');\n }\n}\n//# sourceMappingURL=capacitor-user-manager.js.map","import { registerPlugin } from '@capacitor/core';\nexport const NativeOidc = registerPlugin('CapacitorOidc');\n//# sourceMappingURL=native.js.map","import { CapacitorOidcError, unsupported } from './errors.js';\nimport { NativeOidc } from './native.js';\nexport class CapacitorNavigator {\n prefersEphemeralWebBrowserSession;\n constructor(prefersEphemeralWebBrowserSession) {\n this.prefersEphemeralWebBrowserSession = prefersEphemeralWebBrowserSession;\n }\n async prepare() {\n return new CapacitorWindow(this.prefersEphemeralWebBrowserSession);\n }\n async callback() {\n unsupported('Navigator callbacks');\n }\n}\nclass CapacitorWindow {\n prefersEphemeralWebBrowserSession;\n constructor(prefersEphemeralWebBrowserSession) {\n this.prefersEphemeralWebBrowserSession = prefersEphemeralWebBrowserSession;\n }\n async navigate({ url }) {\n assertSecureRequestUrl(url);\n const callbackUrl = callbackUrlFromRequest(url);\n const response = await NativeOidc.open({\n url,\n callbackUrl,\n prefersEphemeralWebBrowserSession: this.prefersEphemeralWebBrowserSession,\n });\n if (!isExpectedCallback(response.url, callbackUrl)) {\n throw new CapacitorOidcError('INVALID_CALLBACK', 'The authentication callback does not match the configured redirect URI');\n }\n return response;\n }\n close() {\n void NativeOidc.cancel();\n }\n}\nexport function assertSecureRequestUrl(requestUrl) {\n const url = new URL(requestUrl);\n const isHttpLoopback = url.protocol === 'http:' &&\n (url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]');\n if (url.protocol !== 'https:' && !isHttpLoopback) {\n throw new CapacitorOidcError('BROWSER_UNAVAILABLE', 'OIDC authorization and logout endpoints must use HTTPS');\n }\n}\nexport function callbackUrlFromRequest(requestUrl) {\n const url = new URL(requestUrl);\n const callback = url.searchParams.get('post_logout_redirect_uri') ??\n url.searchParams.get('logout_uri') ??\n url.searchParams.get('redirect_uri');\n if (!callback) {\n throw new CapacitorOidcError('INVALID_CALLBACK', 'The OIDC request does not contain a callback URI');\n }\n return callback;\n}\nexport function isExpectedCallback(actualValue, expectedValue) {\n const actual = new URL(actualValue);\n const expected = new URL(expectedValue);\n return (actual.protocol.toLowerCase() === expected.protocol.toLowerCase() &&\n actual.host.toLowerCase() === expected.host.toLowerCase() &&\n actual.pathname === expected.pathname);\n}\nexport class UnsupportedIframeNavigator {\n async prepare() {\n unsupported('Iframe navigation');\n }\n async callback() {\n unsupported('Iframe navigation');\n }\n}\n//# sourceMappingURL=capacitor-navigator.js.map","import { NativeOidc } from './native.js';\nexport class CapacitorSecureStateStore {\n namespace;\n constructor(namespace) {\n this.namespace = namespace;\n }\n async set(key, value) {\n await NativeOidc.storageSet({ namespace: this.namespace, key, value });\n }\n async get(key) {\n return (await NativeOidc.storageGet({ namespace: this.namespace, key })).value;\n }\n async remove(key) {\n return (await NativeOidc.storageRemove({ namespace: this.namespace, key })).value;\n }\n async getAllKeys() {\n return (await NativeOidc.storageGetAllKeys({ namespace: this.namespace })).keys;\n }\n}\n//# sourceMappingURL=capacitor-secure-state-store.js.map","import { App } from '@capacitor/app';\nimport { ErrorResponse, } from 'oidc-client-ts';\nimport { CapacitorNavigator, UnsupportedIframeNavigator } from './capacitor-navigator.js';\nimport { CapacitorSecureStateStore } from './capacitor-secure-state-store.js';\nimport { CapacitorUserManager } from './capacitor-user-manager.js';\nimport { unsupported } from './errors.js';\nimport { NativeOidc } from './native.js';\nexport class NativeCapacitorUserManager extends CapacitorUserManager {\n appStateListener;\n storageNamespace;\n constructor(configuration) {\n const storageNamespace = configuration.nativeOptions?.storageNamespace ?? 'default';\n const stateStore = new CapacitorSecureStateStore(`${storageNamespace}.transactions`);\n const userStore = new CapacitorSecureStateStore(`${storageNamespace}.session`);\n const navigator = new CapacitorNavigator(configuration.nativeOptions?.prefersEphemeralWebBrowserSession ?? false);\n super({\n ...configuration,\n settings: {\n ...configuration.settings,\n popup_redirect_uri: configuration.settings.redirect_uri,\n popup_post_logout_redirect_uri: configuration.settings.post_logout_redirect_uri,\n stateStore,\n userStore,\n },\n }, navigator, navigator, new UnsupportedIframeNavigator());\n this.storageNamespace = storageNamespace;\n }\n static async fromConfiguration(configuration) {\n await NativeOidc.configure(configuration.nativeOptions?.ios ?? {});\n return new NativeCapacitorUserManager(configuration);\n }\n async initialize() {\n await super.initialize();\n this.appStateListener = await App.addListener('appStateChange', ({ isActive }) => {\n if (isActive)\n this.checkForAutomaticRenewal();\n });\n this.checkForAutomaticRenewal();\n }\n async signinRedirect(_args = {}) {\n unsupported('Redirect navigation');\n }\n async signinRedirectCallback(_url) {\n unsupported('Redirect navigation');\n }\n async signinCallback(_url) {\n unsupported('Browser callback dispatch');\n }\n async signinSilentCallback(_url) {\n unsupported('Iframe navigation');\n }\n async signoutRedirect(_args = {}) {\n unsupported('Redirect navigation');\n }\n async signoutRedirectCallback(_url) {\n unsupported('Redirect navigation');\n }\n async signoutCallback(_url, _keepOpen) {\n unsupported('Browser callback dispatch');\n }\n async signoutSilent(_args = {}) {\n unsupported('Iframe logout');\n }\n async signoutSilentCallback(_url) {\n unsupported('Iframe logout');\n }\n async querySessionStatus(_args = {}) {\n unsupported('Browser session monitoring');\n }\n async storeUser(user) {\n await super.storeUser(user);\n await NativeOidc.setSessionSnapshot({\n namespace: this.storageNamespace,\n value: user\n ? JSON.stringify(toStoredSession(user, user.profile.iss ?? this.settings.metadata?.issuer ?? this.settings.authority, this.settings.client_id))\n : null,\n });\n }\n cancel() {\n return NativeOidc.cancel();\n }\n async disposePlatform() {\n await this.appStateListener?.remove();\n }\n async performSilentSignin(args) {\n const user = await this.getUser();\n if (!user?.refresh_token) {\n if (user?.expired)\n await this.removeUserWithoutWaiting();\n return null;\n }\n return super.performSilentSignin({ ...args, forceIframeAuth: false }).catch(async (error) => {\n if (error instanceof ErrorResponse && error.error === 'invalid_grant')\n await this.removeUserWithoutWaiting();\n throw error;\n });\n }\n}\nfunction toStoredSession(user, issuer, clientId) {\n return {\n version: 1,\n issuer,\n clientId,\n accessToken: user.access_token,\n refreshToken: user.refresh_token,\n idToken: user.id_token,\n tokenType: user.token_type,\n scope: user.scope,\n expiresAt: user.expires_at,\n };\n}\n//# sourceMappingURL=native-capacitor-user-manager.js.map","import { CapacitorUserManager } from './capacitor-user-manager.js';\nexport class WebCapacitorUserManager extends CapacitorUserManager {\n sessionMonitor;\n disposed = false;\n constructor(configuration) {\n super(configuration);\n this.sessionMonitor = this.captureSessionMonitor();\n }\n async querySessionStatus(args = {}) {\n if (this.disposed)\n return null;\n const session = await super.querySessionStatus(args);\n return this.disposed ? null : session;\n }\n disposePlatform() {\n this.disposed = true;\n if (this.sessionMonitor) {\n this.events.removeUserLoaded(this.sessionMonitor.start);\n this.events.removeUserUnloaded(this.sessionMonitor.stop);\n this.sessionMonitor.stop();\n }\n return Promise.resolve();\n }\n captureSessionMonitor() {\n // oidc-client-ts does not expose public session-monitor lifecycle hooks.\n const monitor = this._sessionMonitor;\n if (!monitor)\n return undefined;\n const originalStart = monitor._start;\n const stop = monitor._stop;\n const start = async (user) => {\n if (this.disposed)\n return;\n await originalStart(user);\n if (this.disposed)\n stop();\n };\n this.events.removeUserLoaded(originalStart);\n this.events.addUserLoaded(start);\n monitor._start = start;\n return { start, stop };\n }\n}\n//# sourceMappingURL=web-capacitor-user-manager.js.map","import { CapacitorUserManager, setPlatformUserManagerFactory } from './capacitor-user-manager.js';\nimport { NativeCapacitorUserManager } from './native-capacitor-user-manager.js';\nimport { WebCapacitorUserManager } from './web-capacitor-user-manager.js';\nsetPlatformUserManagerFactory((configuration) => configuration.platform === 'web'\n ? new WebCapacitorUserManager(configuration)\n : NativeCapacitorUserManager.fromConfiguration(configuration));\nexport { CapacitorUserManager };\nexport { CapacitorSecureStateStore } from './capacitor-secure-state-store.js';\nexport { CapacitorOidcError } from './errors.js';\nexport { User, WebStorageStateStore } from 'oidc-client-ts';\n//# sourceMappingURL=index.js.map"],"names":["UserManager","Capacitor","registerPlugin","App","ErrorResponse"],"mappings":";;;;;;AAAO,MAAM,kBAAkB,SAAS,KAAK,CAAC;AAC9C,IAAI,IAAI;AACR,IAAI,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE;AAC/B,QAAQ,KAAK,CAAC,OAAO,CAAC;AACtB,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI;AACxB,QAAQ,IAAI,CAAC,IAAI,GAAG,oBAAoB;AACxC,IAAI;AACJ;AACO,SAAS,WAAW,CAAC,OAAO,EAAE;AACrC,IAAI,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,CAAC,EAAE,OAAO,CAAC,+CAA+C,CAAC,CAAC;AACpH;;ACRO,MAAM,wBAAwB,SAASA,wBAAW,CAAC;AAC1D,IAAI,uBAAuB;AAC3B,IAAI,cAAc;AAClB,IAAI,UAAU;AACd,IAAI,WAAW;AACf,IAAI,iBAAiB;AACrB,IAAI,kBAAkB;AACtB,IAAI,WAAW,CAAC,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAE;AACnF,QAAQ,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,CAAC;AACzF,QAAQ,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC,UAAU;AAClD,QAAQ,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC,WAAW;AACpD,QAAQ,IAAI,CAAC,iBAAiB,GAAG,aAAa,CAAC,UAAU;AACzD,QAAQ,IAAI,CAAC,kBAAkB,GAAG,aAAa,CAAC,WAAW;AAC3D,IAAI;AACJ,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,MAAM,IAAI,CAAC,OAAO,EAAE;AAC5B,IAAI;AACJ,IAAI,MAAM,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE;AAC5B,QAAQ,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,GAAG,IAAI,EAAE;AACjE,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU;AAC1C,YAAY,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;AAClD,QAAQ,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;AAC1C,IAAI;AACJ,IAAI,MAAM,OAAO,CAAC,IAAI,GAAG,EAAE,EAAE;AAC7B,QAAQ,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC,kBAAkB,EAAE,GAAG,IAAI,EAAE;AAClE,QAAQ,IAAI,IAAI,CAAC,WAAW,KAAK,UAAU;AAC3C,YAAY,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC;AACnD,QAAQ,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;AAC3C,IAAI;AACJ,IAAI,MAAM,YAAY,CAAC,sBAAsB,GAAG,EAAE,EAAE;AACpD,QAAQ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;AACzC,QAAQ,IAAI,CAAC,IAAI;AACjB,YAAY,OAAO,IAAI;AACvB,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,GAAG,sBAAsB;AACrF,YAAY,OAAO,IAAI;AACvB,QAAQ,OAAO,IAAI,CAAC,YAAY,EAAE;AAClC,IAAI;AACJ,IAAI,MAAM,WAAW,CAAC,IAAI,GAAG,EAAE,EAAE;AACjC,QAAQ,MAAM,IAAI,CAAC,cAAc,EAAE;AACnC,QAAQ,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;AACtC,IAAI;AACJ,IAAI,MAAM,YAAY,CAAC,IAAI,GAAG,EAAE,EAAE;AAClC,QAAQ,MAAM,IAAI,CAAC,cAAc,EAAE;AACnC,QAAQ,MAAM,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC;AACtC,IAAI;AACJ,IAAI,MAAM,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE;AACpC,QAAQ,MAAM,IAAI,CAAC,cAAc,EAAE;AACnC,QAAQ,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC;AACxC,IAAI;AACJ,IAAI,MAAM,eAAe,CAAC,IAAI,GAAG,EAAE,EAAE;AACrC,QAAQ,MAAM,IAAI,CAAC,cAAc,EAAE;AACnC,QAAQ,MAAM,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC;AACzC,IAAI;AACJ,IAAI,YAAY,CAAC,IAAI,GAAG,EAAE,EAAE;AAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;AAClC,YAAY,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC;AAC1D,YAAY,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM;AACxD,gBAAgB,IAAI,CAAC,cAAc,GAAG,SAAS;AAC/C,YAAY,CAAC,CAAC;AACd,QAAQ;AACR,QAAQ,OAAO,IAAI,CAAC,cAAc;AAClC,IAAI;AACJ,IAAI,MAAM,8BAA8B,CAAC,KAAK,EAAE;AAChD,QAAQ,WAAW,CAAC,qCAAqC,CAAC;AAC1D,IAAI;AACJ,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,MAAM,IAAI,CAAC,cAAc,EAAE;AACnC,QAAQ,MAAM,IAAI,CAAC,wBAAwB,EAAE;AAC7C,IAAI;AACJ,IAAI,MAAM,GAAG;AACb,QAAQ,OAAO,OAAO,CAAC,OAAO,EAAE;AAChC,IAAI;AACJ,IAAI,MAAM,OAAO,GAAG;AACpB,QAAQ,IAAI,CAAC,eAAe,EAAE;AAC9B,QAAQ,MAAM,IAAI,CAAC,eAAe,EAAE;AACpC,QAAQ,MAAM,IAAI,CAAC,cAAc,EAAE;AACnC,QAAQ,MAAM,IAAI,CAAC,MAAM,EAAE;AAC3B,IAAI;AACJ,IAAI,mBAAmB,CAAC,IAAI,EAAE;AAC9B,QAAQ,OAAO,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC;AACvC,IAAI;AACJ,IAAI,wBAAwB,GAAG;AAC/B,QAAQ,OAAO,KAAK,CAAC,UAAU,EAAE;AACjC,IAAI;AACJ,IAAI,wBAAwB,GAAG;AAC/B,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,IAAI,IAAI,CAAC,uBAAuB;AAC/E,YAAY;AACZ,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE;AAC3C,QAAQ,IAAI,CAAC,uBAAuB,GAAG,OAAO;AAC9C,QAAQ,KAAK;AACb,aAAa,KAAK,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;AACrI,aAAa,OAAO,CAAC,MAAM;AAC3B,YAAY,IAAI,IAAI,CAAC,uBAAuB,KAAK,OAAO;AACxD,gBAAgB,IAAI,CAAC,uBAAuB,GAAG,SAAS;AACxD,QAAQ,CAAC,CAAC;AACV,IAAI;AACJ,IAAI,MAAM,cAAc,GAAG;AAC3B,QAAQ,MAAM,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC,MAAM,SAAS,CAAC;AAClE,QAAQ,MAAM,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,MAAM,SAAS,CAAC;AACzD,IAAI;AACJ;;ACtGO,MAAM,iBAAiB,GAAG;AACjC,IAAI,+BAA+B;AACnC,IAAI,MAAM;AACV,IAAI,0BAA0B;AAC9B,IAAI,oBAAoB;AACxB,IAAI,+BAA+B;AACnC,IAAI,yBAAyB;AAC7B,IAAI,gBAAgB;AACpB,IAAI,gCAAgC;AACpC,IAAI,oBAAoB;AACxB,IAAI,qBAAqB;AACzB,IAAI,mBAAmB;AACvB,IAAI,4BAA4B;AAChC,IAAI,gBAAgB;AACpB,IAAI,gBAAgB;AACpB,IAAI,qBAAqB;AACzB,IAAI,+BAA+B;AACnC,IAAI,YAAY;AAChB,IAAI,yBAAyB;AAC7B,IAAI,WAAW;AACf,CAAC;;AClBM,SAAS,oBAAoB,CAAC,aAAa,EAAE,QAAQ,EAAE;AAC9D,IAAI,IAAI,QAAQ,KAAK,KAAK;AAC1B,QAAQ,OAAO,uBAAuB,CAAC,aAAa,CAAC;AACrD,IAAI,OAAO,0BAA0B,CAAC,aAAa,EAAE,QAAQ,CAAC;AAC9D;AACO,SAAS,gCAAgC,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE;AACpF,IAAI,IAAI,QAAQ,KAAK,KAAK,EAAE;AAC5B,QAAQ,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,4EAA4E,CAAC;AACzI,IAAI;AACJ,IAAI,kBAAkB,CAAC,QAAQ,CAAC;AAChC,IAAI,IAAI,MAAM,IAAI,QAAQ,EAAE;AAC5B,QAAQ,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,4CAA4C,CAAC;AACzG,IAAI;AACJ,IAAI,OAAO,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC;AACzE;AACA,SAAS,uBAAuB,CAAC,aAAa,EAAE;AAChD,IAAI,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG;AACjC,IAAI,IAAI,CAAC,GAAG;AACZ,QAAQ,wBAAwB,CAAC,KAAK,CAAC;AACvC,IAAI,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,IAAI,UAAU;AACrD,IAAI,MAAM,QAAQ,GAAG,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE;AACjE,IAAI,kBAAkB,CAAC,QAAQ,CAAC;AAChC,IAAI,IAAI,WAAW,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,8BAA8B,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE;AACnH,QAAQ,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,uFAAuF,CAAC;AACpJ,IAAI;AACJ,IAAI,OAAO;AACX,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,QAAQ;AAChB,QAAQ,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,UAAU;AAChD,QAAQ,WAAW;AACnB,QAAQ,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE;AACxC,QAAQ,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE;AAC1C,KAAK;AACL;AACA,SAAS,0BAA0B,CAAC,aAAa,EAAE,QAAQ,EAAE;AAC7D,IAAI,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM;AACvC,IAAI,IAAI,CAAC,MAAM;AACf,QAAQ,wBAAwB,CAAC,QAAQ,CAAC;AAC1C,IAAI,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAC5C,IAAI,MAAM,QAAQ,GAAG,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE;AAC3F,IAAI,kBAAkB,CAAC,QAAQ,CAAC;AAChC,IAAI,oBAAoB,CAAC,QAAQ,CAAC;AAClC,IAAI,OAAO,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,CAAC;AAC/M;AACA,SAAS,2BAA2B,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,EAAE;AAC3G,IAAI,OAAO;AACX,QAAQ,QAAQ;AAChB,QAAQ,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE;AACnG,QAAQ,aAAa;AACrB,QAAQ,UAAU,EAAE,OAAO;AAC3B,QAAQ,WAAW,EAAE,OAAO;AAC5B,QAAQ,UAAU;AAClB,QAAQ,WAAW;AACnB,KAAK;AACL;AACA,SAAS,kBAAkB,CAAC,QAAQ,EAAE;AACtC,IAAI,MAAM,WAAW,GAAG,CAAC,uBAAuB,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,QAAQ,CAAC;AACjI,IAAI,IAAI,WAAW,EAAE;AACrB,QAAQ,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,CAAC,6CAA6C,EAAE,WAAW,CAAC,CAAC,CAAC;AAC1H,IAAI;AACJ;AACA,SAAS,oBAAoB,CAAC,QAAQ,EAAE;AACxC,IAAI,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,QAAQ,CAAC;AACxE,IAAI,IAAI,WAAW,EAAE;AACrB,QAAQ,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,CAAC,sCAAsC,EAAE,WAAW,CAAC,CAAC,CAAC;AACnH,IAAI;AACJ;AACA,SAAS,wBAAwB,CAAC,QAAQ,EAAE;AAC5C,IAAI,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,2BAA2B,CAAC,CAAC;AACpG;;ACnEO,MAAM,oBAAoB,SAAS,wBAAwB,CAAC;AACnE,IAAI,aAAa,MAAM,CAAC,aAAa,EAAE,aAAa,GAAG,EAAE,EAAE;AAC3D,QAAQ,aAAa,EAAE;AACvB,QAAQ,MAAM,QAAQ,GAAG,eAAe,EAAE;AAC1C,QAAQ,MAAM,QAAQ,GAAG,cAAc,IAAI;AAC3C,cAAc,gCAAgC,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ;AACrF,cAAc,oBAAoB,CAAC,aAAa,EAAE,QAAQ,CAAC;AAC3D,QAAQ,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC,QAAQ,CAAC;AAClE,QAAQ,MAAM,OAAO,CAAC,UAAU,EAAE;AAClC,QAAQ,OAAO,OAAO;AACtB,IAAI;AACJ;AACA,IAAI,0BAA0B;AACvB,SAAS,6BAA6B,CAAC,OAAO,EAAE;AACvD,IAAI,0BAA0B,GAAG,OAAO;AACxC;AACA,SAAS,eAAe,GAAG;AAC3B,IAAI,MAAM,QAAQ,GAAGC,cAAS,CAAC,WAAW,EAAE;AAC5C,IAAI,OAAO,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,SAAS,GAAG,QAAQ,GAAG,KAAK;AAC1E;AACA,SAAS,aAAa,GAAG;AACzB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,eAAe,EAAE;AAC1E,QAAQ,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,0CAA0C,CAAC;AACvG,IAAI;AACJ;;AC3BO,MAAM,UAAU,GAAGC,mBAAc,CAAC,eAAe,CAAC;;ACClD,MAAM,kBAAkB,CAAC;AAChC,IAAI,iCAAiC;AACrC,IAAI,WAAW,CAAC,iCAAiC,EAAE;AACnD,QAAQ,IAAI,CAAC,iCAAiC,GAAG,iCAAiC;AAClF,IAAI;AACJ,IAAI,MAAM,OAAO,GAAG;AACpB,QAAQ,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,iCAAiC,CAAC;AAC1E,IAAI;AACJ,IAAI,MAAM,QAAQ,GAAG;AACrB,QAAQ,WAAW,CAAC,qBAAqB,CAAC;AAC1C,IAAI;AACJ;AACA,MAAM,eAAe,CAAC;AACtB,IAAI,iCAAiC;AACrC,IAAI,WAAW,CAAC,iCAAiC,EAAE;AACnD,QAAQ,IAAI,CAAC,iCAAiC,GAAG,iCAAiC;AAClF,IAAI;AACJ,IAAI,MAAM,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE;AAC5B,QAAQ,sBAAsB,CAAC,GAAG,CAAC;AACnC,QAAQ,MAAM,WAAW,GAAG,sBAAsB,CAAC,GAAG,CAAC;AACvD,QAAQ,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC;AAC/C,YAAY,GAAG;AACf,YAAY,WAAW;AACvB,YAAY,iCAAiC,EAAE,IAAI,CAAC,iCAAiC;AACrF,SAAS,CAAC;AACV,QAAQ,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE;AAC5D,YAAY,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,wEAAwE,CAAC;AACtI,QAAQ;AACR,QAAQ,OAAO,QAAQ;AACvB,IAAI;AACJ,IAAI,KAAK,GAAG;AACZ,QAAQ,KAAK,UAAU,CAAC,MAAM,EAAE;AAChC,IAAI;AACJ;AACO,SAAS,sBAAsB,CAAC,UAAU,EAAE;AACnD,IAAI,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC;AACnC,IAAI,MAAM,cAAc,GAAG,GAAG,CAAC,QAAQ,KAAK,OAAO;AACnD,SAAS,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;AAClG,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,cAAc,EAAE;AACtD,QAAQ,MAAM,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,wDAAwD,CAAC;AACrH,IAAI;AACJ;AACO,SAAS,sBAAsB,CAAC,UAAU,EAAE;AACnD,IAAI,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC;AACnC,IAAI,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,0BAA0B,CAAC;AACrE,QAAQ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC;AAC1C,QAAQ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC;AAC5C,IAAI,IAAI,CAAC,QAAQ,EAAE;AACnB,QAAQ,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,kDAAkD,CAAC;AAC5G,IAAI;AACJ,IAAI,OAAO,QAAQ;AACnB;AACO,SAAS,kBAAkB,CAAC,WAAW,EAAE,aAAa,EAAE;AAC/D,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC;AACvC,IAAI,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC;AAC3C,IAAI,QAAQ,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE;AAC7E,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE;AACjE,QAAQ,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;AAC7C;AACO,MAAM,0BAA0B,CAAC;AACxC,IAAI,MAAM,OAAO,GAAG;AACpB,QAAQ,WAAW,CAAC,mBAAmB,CAAC;AACxC,IAAI;AACJ,IAAI,MAAM,QAAQ,GAAG;AACrB,QAAQ,WAAW,CAAC,mBAAmB,CAAC;AACxC,IAAI;AACJ;;ACnEO,MAAM,yBAAyB,CAAC;AACvC,IAAI,SAAS;AACb,IAAI,WAAW,CAAC,SAAS,EAAE;AAC3B,QAAQ,IAAI,CAAC,SAAS,GAAG,SAAS;AAClC,IAAI;AACJ,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE;AAC1B,QAAQ,MAAM,UAAU,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAC9E,IAAI;AACJ,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACnB,QAAQ,OAAO,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK;AACtF,IAAI;AACJ,IAAI,MAAM,MAAM,CAAC,GAAG,EAAE;AACtB,QAAQ,OAAO,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK;AACzF,IAAI;AACJ,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,OAAO,CAAC,MAAM,UAAU,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI;AACvF,IAAI;AACJ;;ACXO,MAAM,0BAA0B,SAAS,oBAAoB,CAAC;AACrE,IAAI,gBAAgB;AACpB,IAAI,gBAAgB;AACpB,IAAI,WAAW,CAAC,aAAa,EAAE;AAC/B,QAAQ,MAAM,gBAAgB,GAAG,aAAa,CAAC,aAAa,EAAE,gBAAgB,IAAI,SAAS;AAC3F,QAAQ,MAAM,UAAU,GAAG,IAAI,yBAAyB,CAAC,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;AAC5F,QAAQ,MAAM,SAAS,GAAG,IAAI,yBAAyB,CAAC,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACtF,QAAQ,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,aAAa,CAAC,aAAa,EAAE,iCAAiC,IAAI,KAAK,CAAC;AACzH,QAAQ,KAAK,CAAC;AACd,YAAY,GAAG,aAAa;AAC5B,YAAY,QAAQ,EAAE;AACtB,gBAAgB,GAAG,aAAa,CAAC,QAAQ;AACzC,gBAAgB,kBAAkB,EAAE,aAAa,CAAC,QAAQ,CAAC,YAAY;AACvE,gBAAgB,8BAA8B,EAAE,aAAa,CAAC,QAAQ,CAAC,wBAAwB;AAC/F,gBAAgB,UAAU;AAC1B,gBAAgB,SAAS;AACzB,aAAa;AACb,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,0BAA0B,EAAE,CAAC;AAClE,QAAQ,IAAI,CAAC,gBAAgB,GAAG,gBAAgB;AAChD,IAAI;AACJ,IAAI,aAAa,iBAAiB,CAAC,aAAa,EAAE;AAClD,QAAQ,MAAM,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,aAAa,EAAE,GAAG,IAAI,EAAE,CAAC;AAC1E,QAAQ,OAAO,IAAI,0BAA0B,CAAC,aAAa,CAAC;AAC5D,IAAI;AACJ,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,MAAM,KAAK,CAAC,UAAU,EAAE;AAChC,QAAQ,IAAI,CAAC,gBAAgB,GAAG,MAAMC,OAAG,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK;AAC1F,YAAY,IAAI,QAAQ;AACxB,gBAAgB,IAAI,CAAC,wBAAwB,EAAE;AAC/C,QAAQ,CAAC,CAAC;AACV,QAAQ,IAAI,CAAC,wBAAwB,EAAE;AACvC,IAAI;AACJ,IAAI,MAAM,cAAc,CAAC,KAAK,GAAG,EAAE,EAAE;AACrC,QAAQ,WAAW,CAAC,qBAAqB,CAAC;AAC1C,IAAI;AACJ,IAAI,MAAM,sBAAsB,CAAC,IAAI,EAAE;AACvC,QAAQ,WAAW,CAAC,qBAAqB,CAAC;AAC1C,IAAI;AACJ,IAAI,MAAM,cAAc,CAAC,IAAI,EAAE;AAC/B,QAAQ,WAAW,CAAC,2BAA2B,CAAC;AAChD,IAAI;AACJ,IAAI,MAAM,oBAAoB,CAAC,IAAI,EAAE;AACrC,QAAQ,WAAW,CAAC,mBAAmB,CAAC;AACxC,IAAI;AACJ,IAAI,MAAM,eAAe,CAAC,KAAK,GAAG,EAAE,EAAE;AACtC,QAAQ,WAAW,CAAC,qBAAqB,CAAC;AAC1C,IAAI;AACJ,IAAI,MAAM,uBAAuB,CAAC,IAAI,EAAE;AACxC,QAAQ,WAAW,CAAC,qBAAqB,CAAC;AAC1C,IAAI;AACJ,IAAI,MAAM,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE;AAC3C,QAAQ,WAAW,CAAC,2BAA2B,CAAC;AAChD,IAAI;AACJ,IAAI,MAAM,aAAa,CAAC,KAAK,GAAG,EAAE,EAAE;AACpC,QAAQ,WAAW,CAAC,eAAe,CAAC;AACpC,IAAI;AACJ,IAAI,MAAM,qBAAqB,CAAC,IAAI,EAAE;AACtC,QAAQ,WAAW,CAAC,eAAe,CAAC;AACpC,IAAI;AACJ,IAAI,MAAM,kBAAkB,CAAC,KAAK,GAAG,EAAE,EAAE;AACzC,QAAQ,WAAW,CAAC,4BAA4B,CAAC;AACjD,IAAI;AACJ,IAAI,MAAM,SAAS,CAAC,IAAI,EAAE;AAC1B,QAAQ,MAAM,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;AACnC,QAAQ,MAAM,UAAU,CAAC,kBAAkB,CAAC;AAC5C,YAAY,SAAS,EAAE,IAAI,CAAC,gBAAgB;AAC5C,YAAY,KAAK,EAAE;AACnB,kBAAkB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;AAC9J,kBAAkB,IAAI;AACtB,SAAS,CAAC;AACV,IAAI;AACJ,IAAI,MAAM,GAAG;AACb,QAAQ,OAAO,UAAU,CAAC,MAAM,EAAE;AAClC,IAAI;AACJ,IAAI,MAAM,eAAe,GAAG;AAC5B,QAAQ,MAAM,IAAI,CAAC,gBAAgB,EAAE,MAAM,EAAE;AAC7C,IAAI;AACJ,IAAI,MAAM,mBAAmB,CAAC,IAAI,EAAE;AACpC,QAAQ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;AACzC,QAAQ,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE;AAClC,YAAY,IAAI,IAAI,EAAE,OAAO;AAC7B,gBAAgB,MAAM,IAAI,CAAC,wBAAwB,EAAE;AACrD,YAAY,OAAO,IAAI;AACvB,QAAQ;AACR,QAAQ,OAAO,KAAK,CAAC,mBAAmB,CAAC,EAAE,GAAG,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,KAAK;AACrG,YAAY,IAAI,KAAK,YAAYC,0BAAa,IAAI,KAAK,CAAC,KAAK,KAAK,eAAe;AACjF,gBAAgB,MAAM,IAAI,CAAC,wBAAwB,EAAE;AACrD,YAAY,MAAM,KAAK;AACvB,QAAQ,CAAC,CAAC;AACV,IAAI;AACJ;AACA,SAAS,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE;AACjD,IAAI,OAAO;AACX,QAAQ,OAAO,EAAE,CAAC;AAClB,QAAQ,MAAM;AACd,QAAQ,QAAQ;AAChB,QAAQ,WAAW,EAAE,IAAI,CAAC,YAAY;AACtC,QAAQ,YAAY,EAAE,IAAI,CAAC,aAAa;AACxC,QAAQ,OAAO,EAAE,IAAI,CAAC,QAAQ;AAC9B,QAAQ,SAAS,EAAE,IAAI,CAAC,UAAU;AAClC,QAAQ,KAAK,EAAE,IAAI,CAAC,KAAK;AACzB,QAAQ,SAAS,EAAE,IAAI,CAAC,UAAU;AAClC,KAAK;AACL;;AC7GO,MAAM,uBAAuB,SAAS,oBAAoB,CAAC;AAClE,IAAI,cAAc;AAClB,IAAI,QAAQ,GAAG,KAAK;AACpB,IAAI,WAAW,CAAC,aAAa,EAAE;AAC/B,QAAQ,KAAK,CAAC,aAAa,CAAC;AAC5B,QAAQ,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,qBAAqB,EAAE;AAC1D,IAAI;AACJ,IAAI,MAAM,kBAAkB,CAAC,IAAI,GAAG,EAAE,EAAE;AACxC,QAAQ,IAAI,IAAI,CAAC,QAAQ;AACzB,YAAY,OAAO,IAAI;AACvB,QAAQ,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC;AAC5D,QAAQ,OAAO,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,OAAO;AAC7C,IAAI;AACJ,IAAI,eAAe,GAAG;AACtB,QAAQ,IAAI,CAAC,QAAQ,GAAG,IAAI;AAC5B,QAAQ,IAAI,IAAI,CAAC,cAAc,EAAE;AACjC,YAAY,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;AACnE,YAAY,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;AACpE,YAAY,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;AACtC,QAAQ;AACR,QAAQ,OAAO,OAAO,CAAC,OAAO,EAAE;AAChC,IAAI;AACJ,IAAI,qBAAqB,GAAG;AAC5B;AACA,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe;AAC5C,QAAQ,IAAI,CAAC,OAAO;AACpB,YAAY,OAAO,SAAS;AAC5B,QAAQ,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM;AAC5C,QAAQ,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK;AAClC,QAAQ,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK;AACtC,YAAY,IAAI,IAAI,CAAC,QAAQ;AAC7B,gBAAgB;AAChB,YAAY,MAAM,aAAa,CAAC,IAAI,CAAC;AACrC,YAAY,IAAI,IAAI,CAAC,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,QAAQ,CAAC;AACT,QAAQ,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC;AACnD,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;AACxC,QAAQ,OAAO,CAAC,MAAM,GAAG,KAAK;AAC9B,QAAQ,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;AAC9B,IAAI;AACJ;;ACvCA,6BAA6B,CAAC,CAAC,aAAa,KAAK,aAAa,CAAC,QAAQ,KAAK;AAC5E,MAAM,IAAI,uBAAuB,CAAC,aAAa;AAC/C,MAAM,0BAA0B,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;;;;;;;;;;;;;;"}
package/docs/PROVIDERS.md CHANGED
@@ -1,33 +1,27 @@
1
1
  # Provider configuration
2
2
 
3
- `capacitor-oidc` works with providers that support Authorization Code Flow with
4
- PKCE for public clients and permit token-related requests from the configured
5
- Capacitor origin.
6
-
7
- ## Provider checklist
8
-
9
- For every provider:
10
-
11
- 1. Create a native, mobile, SPA, or other public client. Do not create or embed a
12
- client secret.
13
- 2. Enable Authorization Code Flow and PKCE with `S256`.
14
- 3. Register every web and native redirect and post-logout redirect URI exactly.
15
- 4. Enable refresh tokens and request the provider's offline-access scope if the
16
- app must renew sessions.
17
- 5. Allow the app's Capacitor origin through CORS for discovery, token, refresh,
18
- UserInfo, and revocation endpoints used by your configuration.
19
- 6. Use HTTPS for provider endpoints.
20
-
21
- The recipes below identify the relevant authority and provider-console choices.
22
- They do not replace the provider's own security guidance.
23
-
24
- | Provider | Current package validation |
25
- | ------------------ | --------------------------------------------------------------- |
26
- | Amazon Cognito | Basic login tested on a physical iOS device; edge cases remain. |
27
- | Auth0 | Configuration guidance only. |
28
- | Keycloak | Configuration guidance only. |
29
- | Okta | Configuration guidance only. |
30
- | Microsoft Entra ID | Configuration guidance only. |
3
+ The recipes below cover the settings that differ between providers.
4
+ `capacitor-oidc` does not contain provider-specific protocol code; it passes the
5
+ configured OpenID Connect settings to `oidc-client-ts`.
6
+
7
+ ## Requirements
8
+
9
+ Use a public client that supports Authorization Code Flow with `S256` PKCE.
10
+ Register every web and native redirect URI and post-logout redirect URI exactly,
11
+ and configure the provider application without a client secret. A secret cannot
12
+ be kept in a Capacitor app.
13
+
14
+ If the app refreshes or revokes tokens, or loads UserInfo from the Capacitor
15
+ runtime, the provider must allow the configured Capacitor origin to call those
16
+ endpoints. Request `offline_access`, or the provider's equivalent, when the app
17
+ needs refresh tokens. Use HTTPS outside local test environments.
18
+
19
+ ## Test status
20
+
21
+ The basic Amazon Cognito sign-in flow has been tested on a physical iOS device.
22
+ The Auth0, Keycloak, Okta, and Microsoft Entra ID sections document expected
23
+ configuration, but those recipes are not yet covered by the package's provider
24
+ integration tests.
31
25
 
32
26
  ## Amazon Cognito
33
27
 
@@ -188,7 +182,7 @@ and [redirect URI restrictions](https://learn.microsoft.com/en-us/entra/identity
188
182
 
189
183
  ## Other providers
190
184
 
191
- Start with the generic checklist and the provider's OpenID Connect discovery
185
+ Start with the requirements above and the provider's OpenID Connect discovery
192
186
  document. If discovery does not describe a usable native flow, pass explicit
193
187
  `metadata` through the upstream `UserManagerSettings` rather than adding
194
188
  provider-specific code to this package.
package/docs/README.md CHANGED
@@ -20,4 +20,4 @@ setup for each native platform and your identity provider.
20
20
  - [Requirements and acceptance criteria](../REQUIREMENTS.md)
21
21
  - [Testing](TESTING.md)
22
22
  - [Publishing](PUBLISHING.md)
23
- - [Architecture decisions](adr)
23
+ - [Architecture decisions](adr/)
@@ -0,0 +1,6 @@
1
+ # Architecture decisions
2
+
3
+ - [Use `oidc-client-ts`](0001-use-oidc-client-ts.md)
4
+ - [Keep the native boundary small](0002-keep-the-native-boundary-small.md)
5
+ - [Share session storage with widgets](0003-share-session-storage-with-widgets.md)
6
+ - [Use one manager across platforms](0004-use-one-manager-across-platforms.md)
@@ -0,0 +1,129 @@
1
+ # Angular integration
2
+
3
+ The [Angular example](/examples/angular/) keeps one OIDC manager in a root
4
+ service. The service completes browser callbacks, restores the current user,
5
+ and exposes signals for templates.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install capacitor-oidc @capacitor/app
11
+ npx cap sync
12
+ ```
13
+
14
+ ## Configure the provider
15
+
16
+ Keep deploy-specific values in an Angular environment file:
17
+
18
+ ```ts
19
+ // src/environments/environment.ts
20
+ export const environment = {
21
+ authority: 'https://identity.example.com',
22
+ clientId: 'public-app',
23
+ };
24
+ ```
25
+
26
+ ## Create a root service
27
+
28
+ `providedIn: 'root'` gives the application one manager, independent of route
29
+ and component lifetimes:
30
+
31
+ ```ts
32
+ @Injectable({ providedIn: 'root' })
33
+ export class OidcService {
34
+ readonly user = signal<User | null>(null);
35
+
36
+ private readonly manager = CapacitorUserManager.create({
37
+ common: {
38
+ authority: environment.authority,
39
+ client_id: environment.clientId,
40
+ scope: 'openid profile offline_access',
41
+ automaticSilentRenew: false,
42
+ },
43
+ web: {
44
+ settings: {
45
+ redirect_uri: `${window.location.origin}/callback`,
46
+ post_logout_redirect_uri: `${window.location.origin}/logout-callback`,
47
+ },
48
+ },
49
+ native: {
50
+ settings: {
51
+ redirect_uri: 'capacitor-oidc-example:/callback',
52
+ post_logout_redirect_uri: 'capacitor-oidc-example:/logout-callback',
53
+ },
54
+ options: { storageNamespace: 'angular-example' },
55
+ },
56
+ });
57
+ }
58
+ ```
59
+
60
+ The runnable example keeps automatic renewal off so the bundled realm's
61
+ 30-second test tokens can be renewed with the example's button. For a normal
62
+ provider, enable automatic renewal and keep its expiry-notification threshold
63
+ below the provider's access-token lifetime.
64
+
65
+ ## Initialize from the root component
66
+
67
+ The service handles browser callbacks before exposing the restored user:
68
+
69
+ ```ts
70
+ async initialize() {
71
+ const auth = await this.manager;
72
+
73
+ auth.events.addUserLoaded((user) => this.user.set(user));
74
+ auth.events.addUserUnloaded(() => this.user.set(null));
75
+
76
+ if (window.location.pathname === '/callback') {
77
+ await auth.signinCallback();
78
+ window.history.replaceState({}, '', '/');
79
+ } else if (window.location.pathname === '/logout-callback') {
80
+ await auth.signoutCallback();
81
+ window.history.replaceState({}, '', '/');
82
+ }
83
+
84
+ this.user.set(await auth.getUser());
85
+ }
86
+ ```
87
+
88
+ Call it once from the root component:
89
+
90
+ ```ts
91
+ export class AppComponent implements OnInit {
92
+ readonly oidc = inject(OidcService);
93
+
94
+ ngOnInit() {
95
+ void this.oidc.initialize();
96
+ }
97
+ }
98
+ ```
99
+
100
+ Native callbacks finish inside the plugin and do not need Angular Router
101
+ routes.
102
+
103
+ ## Bind actions
104
+
105
+ The root service can expose `signin()`, `getValidUser(60)`, and `signout()` as
106
+ methods. Components read the current `user` signal and do not hold their own
107
+ manager.
108
+
109
+ Call `dispose()` only when the Angular application is shutting down.
110
+
111
+ ## Run the example
112
+
113
+ ```sh
114
+ npm ci
115
+ npm run build
116
+ npm run e2e:keycloak:up
117
+ npm --prefix examples/angular install
118
+ npm --prefix examples/angular run dev
119
+ ```
120
+
121
+ Sign in with the disposable `demo` / `demo` account. Stop the local realm with
122
+ `npm run e2e:keycloak:down` when finished.
123
+
124
+ This local realm workflow is for the browser example. Android resolves
125
+ `localhost` inside the device or emulator, and native platforms should not use
126
+ the example's cleartext HTTP authority. Before building for iOS or Android,
127
+ replace `environment.authority` with an HTTPS authority reachable from that
128
+ device and register the configured native callback scheme at the provider. See
129
+ [iOS and Android setup](../PLATFORM_SETUP.md).
@@ -0,0 +1,134 @@
1
+ # React integration
2
+
3
+ The [React example](/examples/react/) creates its OIDC manager outside the
4
+ component tree, restores the user when the application mounts, and keeps React
5
+ state aligned with the manager's user events.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install capacitor-oidc @capacitor/app
11
+ npx cap sync
12
+ ```
13
+
14
+ ## Create the manager outside React
15
+
16
+ A module-level promise prevents component renders from constructing multiple
17
+ managers:
18
+
19
+ ```ts
20
+ // src/auth.ts
21
+ import { CapacitorUserManager } from 'capacitor-oidc';
22
+
23
+ const manager = CapacitorUserManager.create({
24
+ common: {
25
+ authority: import.meta.env.VITE_OIDC_AUTHORITY,
26
+ client_id: import.meta.env.VITE_OIDC_CLIENT_ID,
27
+ scope: 'openid profile offline_access',
28
+ automaticSilentRenew: false,
29
+ },
30
+ web: {
31
+ settings: {
32
+ redirect_uri: `${window.location.origin}/callback`,
33
+ post_logout_redirect_uri: `${window.location.origin}/logout-callback`,
34
+ },
35
+ },
36
+ native: {
37
+ settings: {
38
+ redirect_uri: 'capacitor-oidc-example:/callback',
39
+ post_logout_redirect_uri: 'capacitor-oidc-example:/logout-callback',
40
+ },
41
+ options: { storageNamespace: 'react-example' },
42
+ },
43
+ });
44
+
45
+ export function getUserManager() {
46
+ return manager;
47
+ }
48
+
49
+ let callback: Promise<void> | undefined;
50
+
51
+ export function completeWebCallback(auth: CapacitorUserManager) {
52
+ callback ??= (async () => {
53
+ if (window.location.pathname === '/callback') {
54
+ await auth.signinCallback();
55
+ window.history.replaceState({}, '', '/');
56
+ } else if (window.location.pathname === '/logout-callback') {
57
+ await auth.signoutCallback();
58
+ window.history.replaceState({}, '', '/');
59
+ }
60
+ })();
61
+
62
+ return callback;
63
+ }
64
+ ```
65
+
66
+ The runnable example supplies local Keycloak defaults and keeps automatic
67
+ renewal off so its 30-second test tokens can be renewed with the example's
68
+ button. For a normal provider, enable automatic renewal and keep its
69
+ expiry-notification threshold below the provider's access-token lifetime. Set
70
+ the two Vite environment variables for your provider.
71
+
72
+ ## Initialize from the application root
73
+
74
+ Complete browser callbacks, subscribe to user events, and restore the stored
75
+ user from the root component:
76
+
77
+ ```tsx
78
+ useEffect(() => {
79
+ let active = true;
80
+ let auth: CapacitorUserManager | undefined;
81
+ const userLoaded = (user: User) => active && setUser(user);
82
+ const userUnloaded = () => active && setUser(null);
83
+
84
+ void getUserManager().then(async (manager) => {
85
+ if (!active) return;
86
+ auth = manager;
87
+ manager.events.addUserLoaded(userLoaded);
88
+ manager.events.addUserUnloaded(userUnloaded);
89
+ await completeWebCallback(manager);
90
+ const storedUser = await manager.getUser();
91
+ if (active) setUser(storedUser);
92
+ });
93
+
94
+ return () => {
95
+ active = false;
96
+ auth?.events.removeUserLoaded(userLoaded);
97
+ auth?.events.removeUserUnloaded(userUnloaded);
98
+ };
99
+ }, []);
100
+ ```
101
+
102
+ Native callbacks complete inside the plugin and do not require React Router
103
+ routes.
104
+
105
+ ## Bind actions
106
+
107
+ ```ts
108
+ await auth.signin();
109
+ setUser(await auth.getValidUser(60));
110
+ await auth.signout();
111
+ ```
112
+
113
+ Retain the manager when React routes change. Call `dispose()` only when the
114
+ whole application is shutting down.
115
+
116
+ ## Run the example
117
+
118
+ ```sh
119
+ npm ci
120
+ npm run build
121
+ npm run e2e:keycloak:up
122
+ npm --prefix examples/react install
123
+ npm --prefix examples/react run dev
124
+ ```
125
+
126
+ Sign in with the disposable `demo` / `demo` account. Stop the local realm with
127
+ `npm run e2e:keycloak:down` when finished.
128
+
129
+ This local realm workflow is for the browser example. Android resolves
130
+ `localhost` inside the device or emulator, and native platforms should not use
131
+ the example's cleartext HTTP authority. Before building for iOS or Android, set
132
+ `VITE_OIDC_AUTHORITY` to an HTTPS authority reachable from that device and
133
+ register the configured native callback scheme at the provider. See
134
+ [iOS and Android setup](../PLATFORM_SETUP.md).
@@ -0,0 +1,118 @@
1
+ # Vue integration
2
+
3
+ The [Vue example](/examples/vue/) is a small Capacitor application with one
4
+ OIDC manager for the application lifetime. It restores the stored user when
5
+ Vue mounts, completes browser callbacks, and exposes sign-in, renewal, and
6
+ sign-out actions.
7
+
8
+ ## Install
9
+
10
+ ```sh
11
+ npm install capacitor-oidc @capacitor/app
12
+ npx cap sync
13
+ ```
14
+
15
+ ## Create the manager once
16
+
17
+ Keep manager creation outside Vue components so route changes cannot create a
18
+ second manager:
19
+
20
+ ```ts
21
+ // src/auth.ts
22
+ import { CapacitorUserManager } from 'capacitor-oidc';
23
+
24
+ const manager = CapacitorUserManager.create({
25
+ common: {
26
+ authority: import.meta.env.VITE_OIDC_AUTHORITY,
27
+ client_id: import.meta.env.VITE_OIDC_CLIENT_ID,
28
+ scope: 'openid profile offline_access',
29
+ automaticSilentRenew: false,
30
+ },
31
+ web: {
32
+ settings: {
33
+ redirect_uri: `${window.location.origin}/callback`,
34
+ post_logout_redirect_uri: `${window.location.origin}/logout-callback`,
35
+ },
36
+ },
37
+ native: {
38
+ settings: {
39
+ redirect_uri: 'capacitor-oidc-example:/callback',
40
+ post_logout_redirect_uri: 'capacitor-oidc-example:/logout-callback',
41
+ },
42
+ options: { storageNamespace: 'vue-example' },
43
+ },
44
+ });
45
+
46
+ export function getUserManager() {
47
+ return manager;
48
+ }
49
+ ```
50
+
51
+ The runnable example supplies local Keycloak defaults as a convenience and
52
+ keeps automatic renewal off so its 30-second test tokens can be renewed with
53
+ the example's button. For a normal provider, enable automatic renewal and keep
54
+ its expiry-notification threshold below the provider's access-token lifetime.
55
+ Use environment variables for your provider in an application.
56
+
57
+ ## Restore state and handle callbacks
58
+
59
+ Initialize authentication from the root component. Browser callback routes
60
+ must be handled before rendering the restored user:
61
+
62
+ ```ts
63
+ const auth = await getUserManager();
64
+
65
+ if (window.location.pathname === '/callback') {
66
+ await auth.signinCallback();
67
+ window.history.replaceState({}, '', '/');
68
+ } else if (window.location.pathname === '/logout-callback') {
69
+ await auth.signoutCallback();
70
+ window.history.replaceState({}, '', '/');
71
+ }
72
+
73
+ user.value = await auth.getUser();
74
+
75
+ auth.events.addUserLoaded((loadedUser) => {
76
+ user.value = loadedUser;
77
+ });
78
+
79
+ auth.events.addUserUnloaded(() => {
80
+ user.value = null;
81
+ });
82
+ ```
83
+
84
+ Native callbacks are completed by the plugin and do not need Vue Router
85
+ routes.
86
+
87
+ ## Bind actions
88
+
89
+ ```ts
90
+ await auth.signin();
91
+ user.value = await auth.getValidUser(60);
92
+ await auth.signout();
93
+ ```
94
+
95
+ Call `dispose()` only when the application is shutting down, not whenever a
96
+ route component unmounts.
97
+
98
+ ## Run the example
99
+
100
+ Start the repository's local Keycloak realm, then start the Vue app:
101
+
102
+ ```sh
103
+ npm ci
104
+ npm run build
105
+ npm run e2e:keycloak:up
106
+ npm --prefix examples/vue install
107
+ npm --prefix examples/vue run dev
108
+ ```
109
+
110
+ Sign in with the disposable `demo` / `demo` account. Stop the local realm with
111
+ `npm run e2e:keycloak:down` when finished.
112
+
113
+ This local realm workflow is for the browser example. Android resolves
114
+ `localhost` inside the device or emulator, and native platforms should not use
115
+ the example's cleartext HTTP authority. Before building for iOS or Android, set
116
+ `VITE_OIDC_AUTHORITY` to an HTTPS authority reachable from that device and
117
+ register the configured native callback scheme at the provider. See
118
+ [iOS and Android setup](../PLATFORM_SETUP.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-oidc",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "OAuth 2.0 and OpenID Connect authentication for Capacitor web, iOS, and Android, powered by oidc-client-ts.",
5
5
  "keywords": [
6
6
  "capacitor",
@@ -43,12 +43,15 @@
43
43
  "bugs": {
44
44
  "url": "https://github.com/jojopirker/capacitor-oidc/issues"
45
45
  },
46
- "homepage": "https://github.com/jojopirker/capacitor-oidc#readme",
46
+ "homepage": "https://jojopirker.github.io/capacitor-oidc/",
47
47
  "type": "module",
48
48
  "scripts": {
49
49
  "build": "npm run clean && tsc && rollup -c rollup.config.mjs",
50
50
  "check:package": "node -e \"import('./dist/esm/index.js')\"",
51
51
  "clean": "rimraf dist",
52
+ "docs:build": "vitepress build . && cp LICENSE .vitepress/dist/LICENSE",
53
+ "docs:dev": "vitepress dev .",
54
+ "docs:preview": "vitepress preview .",
52
55
  "e2e:keycloak:down": "docker compose -f test/e2e/keycloak/compose.yml down",
53
56
  "e2e:keycloak:up": "test/e2e/keycloak/create-certificate.sh test/e2e/keycloak/.certificates && docker compose -f test/e2e/keycloak/compose.yml up -d",
54
57
  "example:build": "npm --prefix example run build",
@@ -79,6 +82,8 @@
79
82
  "rimraf": "6.1.0",
80
83
  "rollup": "4.62.5",
81
84
  "typescript": "5.9.3",
85
+ "vite": "7.3.6",
86
+ "vitepress": "2.0.0-alpha.19",
82
87
  "vitest": "3.2.7"
83
88
  },
84
89
  "prettier": "@ionic/prettier-config",