capacitor-oidc 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -23
- package/SECURITY.md +4 -3
- package/dist/esm/base-capacitor-user-manager.d.ts +30 -0
- package/dist/esm/base-capacitor-user-manager.js +104 -0
- package/dist/esm/base-capacitor-user-manager.js.map +1 -0
- package/dist/esm/capacitor-user-manager.d.ts +9 -32
- package/dist/esm/capacitor-user-manager.js +20 -174
- package/dist/esm/capacitor-user-manager.js.map +1 -1
- package/dist/esm/configuration.d.ts +14 -0
- package/dist/esm/configuration.js +72 -0
- package/dist/esm/configuration.js.map +1 -0
- package/dist/esm/definitions.d.ts +53 -3
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +5 -4
- package/dist/esm/index.js +8 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/native-capacitor-user-manager.d.ts +24 -0
- package/dist/esm/native-capacitor-user-manager.js +112 -0
- package/dist/esm/native-capacitor-user-manager.js.map +1 -0
- package/dist/esm/web-capacitor-user-manager.d.ts +11 -0
- package/dist/esm/web-capacitor-user-manager.js +44 -0
- package/dist/esm/web-capacitor-user-manager.js.map +1 -0
- package/dist/plugin.cjs +303 -126
- package/dist/plugin.cjs.map +1 -1
- package/docs/API.md +106 -60
- package/docs/GETTING_STARTED.md +85 -62
- package/docs/PLATFORM_SETUP.md +15 -4
- package/docs/PROVIDERS.md +30 -17
- package/docs/README.md +3 -3
- package/docs/TESTING.md +3 -1
- package/docs/TROUBLESHOOTING.md +23 -13
- package/docs/adr/0004-use-one-manager-across-platforms.md +64 -0
- package/package.json +3 -2
package/docs/API.md
CHANGED
|
@@ -1,63 +1,62 @@
|
|
|
1
1
|
# API and `oidc-client-ts` compatibility
|
|
2
2
|
|
|
3
|
-
`CapacitorUserManager` extends `UserManager` from `oidc-client-ts`.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
a native public client.
|
|
3
|
+
`CapacitorUserManager` extends `UserManager` from `oidc-client-ts`. Applications
|
|
4
|
+
use the package's manager on web, iOS, and Android; the package selects browser or
|
|
5
|
+
native navigation, storage, renewal, and lifecycle behavior.
|
|
7
6
|
|
|
8
|
-
##
|
|
7
|
+
## Portable API
|
|
9
8
|
|
|
10
|
-
| API
|
|
11
|
-
|
|
|
12
|
-
| `CapacitorUserManager.create(
|
|
13
|
-
| `signin(args?)`
|
|
14
|
-
| `signout(args?)`
|
|
15
|
-
| `getValidUser(minimumValiditySeconds?)`
|
|
16
|
-
| `cancel()`
|
|
17
|
-
| `dispose()`
|
|
9
|
+
| API | Purpose |
|
|
10
|
+
| -------------------------------------------- | ------------------------------------------------------------- |
|
|
11
|
+
| `CapacitorUserManager.create(configuration)` | Resolves the current platform and restores its stored user. |
|
|
12
|
+
| `signin(args?)` | Starts the configured redirect, popup, or native interaction. |
|
|
13
|
+
| `signout(args?)` | Starts the configured provider logout interaction. |
|
|
14
|
+
| `getValidUser(minimumValiditySeconds?)` | Returns the user or performs one serialized renewal. |
|
|
15
|
+
| `cancel()` | Cancels pending native navigation; it is a no-op on web. |
|
|
16
|
+
| `dispose()` | Stops renewal and disposes platform lifecycle work. |
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
`signin()` and `signout()` return `Promise<void>` consistently. Read user state
|
|
19
|
+
through `getUser()`, `getValidUser()`, or `events`. Configuration-level arguments
|
|
20
|
+
are shallowly merged with call-level arguments, with call values taking
|
|
21
|
+
precedence.
|
|
21
22
|
|
|
22
|
-
##
|
|
23
|
+
## Configuration
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
types.
|
|
34
|
-
|
|
35
|
-
`signinPopup()` and `signoutPopup()` are inherited and use the native navigator,
|
|
36
|
-
but applications should prefer `signin()` and `signout()`.
|
|
37
|
-
|
|
38
|
-
## Unsupported browser API
|
|
39
|
-
|
|
40
|
-
These inherited browser-oriented methods reject with `UNSUPPORTED_RUNTIME`:
|
|
25
|
+
```ts
|
|
26
|
+
interface CapacitorUserManagerConfiguration {
|
|
27
|
+
common: CapacitorUserManagerCommonSettings;
|
|
28
|
+
web?: CapacitorWebUserManagerConfiguration;
|
|
29
|
+
native?: CapacitorNativeUserManagerConfiguration;
|
|
30
|
+
ios?: CapacitorNativeUserManagerOverride;
|
|
31
|
+
android?: CapacitorNativeUserManagerOverride;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- `signoutRedirect()`, `signoutRedirectCallback()`, and `signoutCallback()`;
|
|
45
|
-
- `signoutSilent()` and `signoutSilentCallback()`;
|
|
46
|
-
- `querySessionStatus()`;
|
|
47
|
-
- Resource Owner Password Credentials.
|
|
35
|
+
Resolution is `common -> web` in a browser and
|
|
36
|
+
`common -> native -> ios|android` on native platforms. All merges are shallow.
|
|
48
37
|
|
|
49
|
-
The
|
|
38
|
+
The web section accepts public-client `UserManagerSettings`, including custom
|
|
39
|
+
`stateStore` and `userStore`, DPoP, silent iframe settings, and session
|
|
40
|
+
monitoring. It also accepts:
|
|
50
41
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
42
|
+
```ts
|
|
43
|
+
interface CapacitorWebUserManagerConfiguration {
|
|
44
|
+
settings: CapacitorWebUserManagerSettings;
|
|
45
|
+
signinMode?: 'redirect' | 'popup';
|
|
46
|
+
signoutMode?: 'redirect' | 'popup';
|
|
47
|
+
signinArgs?: CapacitorSigninArgs;
|
|
48
|
+
signoutArgs?: CapacitorSignoutArgs;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
56
51
|
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
`oidc-client-ts` defaults popup sign-in and sign-out callbacks from
|
|
53
|
+
`settings.redirect_uri` and `settings.post_logout_redirect_uri`. Popup sign-out
|
|
54
|
+
requires either `settings.post_logout_redirect_uri` or
|
|
55
|
+
`settings.popup_post_logout_redirect_uri`. Set the popup-specific URI only when
|
|
56
|
+
it needs to differ.
|
|
59
57
|
|
|
60
|
-
|
|
58
|
+
The native section and platform overrides accept native-compatible settings,
|
|
59
|
+
default arguments, and these options:
|
|
61
60
|
|
|
62
61
|
```ts
|
|
63
62
|
interface CapacitorOidcNativeOptions {
|
|
@@ -70,22 +69,69 @@ interface CapacitorOidcNativeOptions {
|
|
|
70
69
|
}
|
|
71
70
|
```
|
|
72
71
|
|
|
73
|
-
`storageNamespace` defaults to `default`. Use a stable
|
|
72
|
+
`storageNamespace` defaults to `default`. Use a stable application-specific
|
|
74
73
|
value and do not change it between releases unless intentionally starting a new
|
|
75
74
|
session store.
|
|
76
75
|
|
|
76
|
+
All platforms reject `client_secret`, `client_authentication`, `disablePKCE`,
|
|
77
|
+
and `response_type`. The manager forces Authorization Code Flow with PKCE.
|
|
78
|
+
Native settings additionally exclude browser stores, DPoP, iframe callbacks,
|
|
79
|
+
and browser session monitoring.
|
|
80
|
+
|
|
81
|
+
### Legacy native configuration
|
|
82
|
+
|
|
83
|
+
The native-only factory signature from earlier releases remains available so an
|
|
84
|
+
application can upgrade before moving its configuration:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const manager = await CapacitorUserManager.create(
|
|
88
|
+
{
|
|
89
|
+
authority: 'https://identity.example.com',
|
|
90
|
+
client_id: 'mobile-app',
|
|
91
|
+
redirect_uri: 'com.example.app:/callback',
|
|
92
|
+
scope: 'openid profile offline_access',
|
|
93
|
+
},
|
|
94
|
+
{ storageNamespace: 'primary' },
|
|
95
|
+
);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This signature and `CapacitorUserManagerSettings` are deprecated. They remain
|
|
99
|
+
native-only and do not infer browser settings. New code should use the layered
|
|
100
|
+
configuration above. `signin()` now returns `Promise<void>` for every factory
|
|
101
|
+
signature; use `getUser()`, `getValidUser()`, or events to read the signed-in
|
|
102
|
+
user.
|
|
103
|
+
|
|
104
|
+
## Inherited API by platform
|
|
105
|
+
|
|
106
|
+
| Upstream capability | Web | iOS and Android |
|
|
107
|
+
| ------------------------------------------ | ------------------------- | ------------------------------- |
|
|
108
|
+
| `getUser()`, `storeUser()`, `removeUser()` | Browser stores | Secure native stores |
|
|
109
|
+
| `signinRedirect()` and callback | Supported | `UNSUPPORTED_RUNTIME` |
|
|
110
|
+
| `signinPopup()` | Browser popup | Native system authentication UI |
|
|
111
|
+
| `signinSilent()` | Refresh token or iframe | Refresh token only |
|
|
112
|
+
| `signoutRedirect()` and callback | Supported | `UNSUPPORTED_RUNTIME` |
|
|
113
|
+
| `signoutPopup()` | Browser popup | Native system authentication UI |
|
|
114
|
+
| Silent logout and session monitoring | Supported when configured | `UNSUPPORTED_RUNTIME` |
|
|
115
|
+
| `revokeTokens()`, UserInfo, and events | Supported | Supported |
|
|
116
|
+
| Resource Owner Password Credentials | Unsupported | Unsupported |
|
|
117
|
+
|
|
118
|
+
Browser callback dispatch through `signinCallback()` and `signoutCallback()` is
|
|
119
|
+
supported on web. Native callbacks complete inside the system authentication
|
|
120
|
+
session.
|
|
121
|
+
|
|
122
|
+
The package re-exports `User`, `WebStorageStateStore`, `StateStore`, and
|
|
123
|
+
`UserManagerEvents`, so normal application code does not need to import
|
|
124
|
+
`oidc-client-ts` directly.
|
|
125
|
+
|
|
77
126
|
## Adapter error codes
|
|
78
127
|
|
|
79
|
-
| Code | Meaning
|
|
80
|
-
| -------------------------- |
|
|
81
|
-
| `AUTH_SESSION_IN_PROGRESS` | Another native login or logout is active.
|
|
82
|
-
| `USER_CANCELLED` | The user or application cancelled the system session.
|
|
83
|
-
| `BROWSER_UNAVAILABLE` | No compatible browser exists or the request endpoint is insecure.
|
|
84
|
-
| `INVALID_CALLBACK` |
|
|
85
|
-
| `SECURE_STORAGE_ERROR` | Keychain or Keystore-backed storage failed.
|
|
86
|
-
| `UNSUPPORTED_RUNTIME` |
|
|
128
|
+
| Code | Meaning |
|
|
129
|
+
| -------------------------- | ----------------------------------------------------------------------------- |
|
|
130
|
+
| `AUTH_SESSION_IN_PROGRESS` | Another native login or logout is active. |
|
|
131
|
+
| `USER_CANCELLED` | The user or application cancelled the native system session. |
|
|
132
|
+
| `BROWSER_UNAVAILABLE` | No compatible native browser exists or the request endpoint is insecure. |
|
|
133
|
+
| `INVALID_CALLBACK` | A native callback is absent, malformed, or does not match the configured URI. |
|
|
134
|
+
| `SECURE_STORAGE_ERROR` | Keychain or Keystore-backed storage failed. |
|
|
135
|
+
| `UNSUPPORTED_RUNTIME` | Required platform configuration or capability is unavailable. |
|
|
87
136
|
|
|
88
137
|
OAuth and OIDC server errors remain upstream `oidc-client-ts` errors.
|
|
89
|
-
|
|
90
|
-
For the complete upstream model and event API, use the
|
|
91
|
-
[`oidc-client-ts` documentation](https://authts.github.io/oidc-client-ts/).
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## 1. Configure a public client
|
|
4
4
|
|
|
5
|
-
Create a
|
|
5
|
+
Create a public client at your identity provider with:
|
|
6
6
|
|
|
7
7
|
- Authorization Code Flow enabled;
|
|
8
8
|
- PKCE with the `S256` challenge method;
|
|
9
9
|
- no client secret;
|
|
10
|
-
-
|
|
11
|
-
-
|
|
10
|
+
- every web, iOS, and Android redirect URI registered exactly;
|
|
11
|
+
- every post-logout redirect URI registered exactly;
|
|
12
12
|
- the `openid` scope and any application scopes you need;
|
|
13
|
-
-
|
|
13
|
+
- refresh tokens or offline access when the app must renew sessions.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
the callback from completing.
|
|
15
|
+
A minor difference in scheme, host, path, casing, or slash placement can prevent
|
|
16
|
+
a callback from completing.
|
|
18
17
|
|
|
19
18
|
## 2. Install the package
|
|
20
19
|
|
|
@@ -23,57 +22,95 @@ npm install capacitor-oidc @capacitor/app
|
|
|
23
22
|
npx cap sync
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
Complete the [iOS or Android setup](PLATFORM_SETUP.md) before running
|
|
25
|
+
Complete the [iOS or Android setup](PLATFORM_SETUP.md) before running a native
|
|
26
|
+
build.
|
|
27
27
|
|
|
28
28
|
## 3. Create one manager
|
|
29
29
|
|
|
30
|
-
Create and retain one manager for the application session.
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
Create and retain one manager for the application session. The package detects
|
|
31
|
+
the current platform and resolves settings in this order:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
web: common -> web
|
|
35
|
+
iOS: common -> native -> ios
|
|
36
|
+
Android: common -> native -> android
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Every merge is shallow, including configured sign-in and sign-out arguments.
|
|
33
40
|
|
|
34
41
|
```ts
|
|
35
|
-
import { CapacitorUserManager } from 'capacitor-oidc';
|
|
42
|
+
import { CapacitorUserManager, WebStorageStateStore } from 'capacitor-oidc';
|
|
36
43
|
|
|
37
|
-
export const auth = await CapacitorUserManager.create(
|
|
38
|
-
{
|
|
44
|
+
export const auth = await CapacitorUserManager.create({
|
|
45
|
+
common: {
|
|
39
46
|
authority: 'https://identity.example.com',
|
|
40
|
-
client_id: '
|
|
41
|
-
redirect_uri: 'com.example.app:/callback',
|
|
42
|
-
post_logout_redirect_uri: 'com.example.app:/logout-callback',
|
|
47
|
+
client_id: 'public-app',
|
|
43
48
|
scope: 'openid profile offline_access',
|
|
44
49
|
automaticSilentRenew: true,
|
|
45
50
|
loadUserInfo: true,
|
|
46
51
|
revokeTokensOnSignout: true,
|
|
47
52
|
},
|
|
48
|
-
{
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
web: {
|
|
54
|
+
settings: {
|
|
55
|
+
redirect_uri: `${window.location.origin}/callback`,
|
|
56
|
+
post_logout_redirect_uri: `${window.location.origin}/logout-callback`,
|
|
57
|
+
stateStore: new WebStorageStateStore({ store: window.sessionStorage }),
|
|
58
|
+
userStore: new WebStorageStateStore({ store: window.localStorage }),
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
native: {
|
|
62
|
+
settings: {
|
|
63
|
+
redirect_uri: 'com.example.app:/callback',
|
|
64
|
+
post_logout_redirect_uri: 'com.example.app:/logout-callback',
|
|
65
|
+
},
|
|
66
|
+
options: {
|
|
67
|
+
prefersEphemeralWebBrowserSession: false,
|
|
68
|
+
storageNamespace: 'primary',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
ios: {
|
|
72
|
+
settings: { redirect_uri: 'com.example.ios:/callback' },
|
|
73
|
+
},
|
|
74
|
+
android: {
|
|
75
|
+
settings: { redirect_uri: 'com.example.android:/callback' },
|
|
51
76
|
},
|
|
52
|
-
);
|
|
77
|
+
});
|
|
53
78
|
```
|
|
54
79
|
|
|
55
|
-
`
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
the preference.
|
|
80
|
+
The `web` and `native` sections are optional so a single-platform application
|
|
81
|
+
does not need unused settings. Creation fails clearly if the running platform has
|
|
82
|
+
no matching configuration.
|
|
59
83
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
Browser-only settings such as custom stores, DPoP, silent iframe callbacks, and
|
|
85
|
+
session monitoring belong in `web.settings`. Native stores and navigation are
|
|
86
|
+
owned by the package and cannot be replaced. Public clients cannot configure a
|
|
87
|
+
secret, disable PKCE, or change the response type on any platform.
|
|
64
88
|
|
|
65
|
-
## 4.
|
|
89
|
+
## 4. Handle web callbacks
|
|
66
90
|
|
|
67
|
-
|
|
68
|
-
const user = await auth.signin();
|
|
91
|
+
Call the matching callback method on the configured browser route:
|
|
69
92
|
|
|
70
|
-
|
|
93
|
+
```ts
|
|
94
|
+
if (window.location.pathname === '/callback') {
|
|
95
|
+
await auth.signinCallback();
|
|
96
|
+
} else if (window.location.pathname === '/logout-callback') {
|
|
97
|
+
await auth.signoutCallback();
|
|
98
|
+
}
|
|
71
99
|
```
|
|
72
100
|
|
|
73
|
-
|
|
74
|
-
|
|
101
|
+
Native callbacks are completed by the system authentication session and do not
|
|
102
|
+
need application routing.
|
|
75
103
|
|
|
76
|
-
|
|
104
|
+
## 5. Sign in
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
await auth.signin();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
On web, `signin()` uses redirect navigation by default. Set `signinMode: 'popup'`
|
|
111
|
+
in the web section to use a popup. On native platforms it uses the system
|
|
112
|
+
authentication UI. The portable method returns no user because a browser redirect
|
|
113
|
+
leaves the page; read the user after the callback or subscribe to events:
|
|
77
114
|
|
|
78
115
|
```ts
|
|
79
116
|
auth.events.addUserLoaded((user) => {
|
|
@@ -85,14 +122,12 @@ auth.events.addSilentRenewError((error) => {
|
|
|
85
122
|
});
|
|
86
123
|
```
|
|
87
124
|
|
|
88
|
-
##
|
|
125
|
+
## 6. Get a usable access token
|
|
89
126
|
|
|
90
127
|
```ts
|
|
91
128
|
const user = await auth.getValidUser(30);
|
|
92
129
|
|
|
93
|
-
if (
|
|
94
|
-
// No signed-in session is available.
|
|
95
|
-
} else {
|
|
130
|
+
if (user) {
|
|
96
131
|
await fetch('https://api.example.com/profile', {
|
|
97
132
|
headers: { Authorization: `Bearer ${user.access_token}` },
|
|
98
133
|
});
|
|
@@ -100,33 +135,21 @@ if (!user) {
|
|
|
100
135
|
```
|
|
101
136
|
|
|
102
137
|
`getValidUser(30)` returns the current user when its access token is valid for at
|
|
103
|
-
least 30 more seconds. Otherwise it performs one
|
|
104
|
-
|
|
138
|
+
least 30 more seconds. Otherwise it performs one renewal. Concurrent renewal
|
|
139
|
+
triggers share the same request. Native renewal requires a refresh token and
|
|
140
|
+
never falls back to an iframe; web renewal retains the normal browser behavior.
|
|
105
141
|
|
|
106
|
-
##
|
|
142
|
+
## 7. Sign out and dispose
|
|
107
143
|
|
|
108
144
|
```ts
|
|
109
145
|
await auth.signout();
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
`signout()` opens the provider's end-session endpoint in the same native system
|
|
113
|
-
authentication UI. Provider-specific parameters can be passed through
|
|
114
|
-
`extraQueryParams`; see [Provider configuration](PROVIDERS.md).
|
|
115
|
-
|
|
116
|
-
Use `removeUser()` when the application intentionally needs local-only logout.
|
|
117
|
-
|
|
118
|
-
## 7. Dispose application listeners
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
146
|
await auth.dispose();
|
|
122
147
|
```
|
|
123
148
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
## Browser builds
|
|
149
|
+
Web sign-out uses redirects by default and supports `signoutMode: 'popup'`.
|
|
150
|
+
Native sign-out uses the system authentication UI. Use `removeUser()` when the
|
|
151
|
+
application intentionally needs local-only logout.
|
|
128
152
|
|
|
129
|
-
`
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
`CapacitorUserManager` for the native branch.
|
|
153
|
+
Call `dispose()` when the manager will no longer be used. It stops renewal and,
|
|
154
|
+
on native platforms, removes the app-state listener and cancels pending native
|
|
155
|
+
navigation.
|
package/docs/PLATFORM_SETUP.md
CHANGED
|
@@ -39,12 +39,23 @@ entitlement to the application and extension, then configure the expanded access
|
|
|
39
39
|
group:
|
|
40
40
|
|
|
41
41
|
```ts
|
|
42
|
-
const manager = await CapacitorUserManager.create(
|
|
42
|
+
const manager = await CapacitorUserManager.create({
|
|
43
|
+
common: {
|
|
44
|
+
authority: 'https://identity.example.com',
|
|
45
|
+
client_id: 'public-app',
|
|
46
|
+
},
|
|
47
|
+
native: {
|
|
48
|
+
settings: { redirect_uri: 'com.example.app:/callback' },
|
|
49
|
+
options: { storageNamespace: 'primary' },
|
|
50
|
+
},
|
|
43
51
|
ios: {
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
options: {
|
|
53
|
+
ios: {
|
|
54
|
+
keychainAccessGroup: 'TEAMID.group.com.example.app',
|
|
55
|
+
keychainAccessibility: 'afterFirstUnlockThisDeviceOnly',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
46
58
|
},
|
|
47
|
-
storageNamespace: 'primary',
|
|
48
59
|
});
|
|
49
60
|
```
|
|
50
61
|
|
package/docs/PROVIDERS.md
CHANGED
|
@@ -11,7 +11,7 @@ For every provider:
|
|
|
11
11
|
1. Create a native, mobile, SPA, or other public client. Do not create or embed a
|
|
12
12
|
client secret.
|
|
13
13
|
2. Enable Authorization Code Flow and PKCE with `S256`.
|
|
14
|
-
3. Register
|
|
14
|
+
3. Register every web and native redirect and post-logout redirect URI exactly.
|
|
15
15
|
4. Enable refresh tokens and request the provider's offline-access scope if the
|
|
16
16
|
app must renew sessions.
|
|
17
17
|
5. Allow the app's Capacitor origin through CORS for discovery, token, refresh,
|
|
@@ -43,20 +43,33 @@ const domain = 'https://example.auth.eu-central-1.amazoncognito.com';
|
|
|
43
43
|
const issuer = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}`;
|
|
44
44
|
|
|
45
45
|
const manager = await CapacitorUserManager.create({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
46
|
+
common: {
|
|
47
|
+
authority: issuer,
|
|
48
|
+
client_id: clientId,
|
|
49
|
+
scope: 'openid email profile aws.cognito.signin.user.admin',
|
|
50
|
+
automaticSilentRenew: true,
|
|
51
|
+
revokeTokensOnSignout: true,
|
|
52
|
+
metadata: {
|
|
53
|
+
issuer,
|
|
54
|
+
authorization_endpoint: `${domain}/oauth2/authorize`,
|
|
55
|
+
token_endpoint: `${domain}/oauth2/token`,
|
|
56
|
+
userinfo_endpoint: `${domain}/oauth2/userInfo`,
|
|
57
|
+
revocation_endpoint: `${domain}/oauth2/revoke`,
|
|
58
|
+
end_session_endpoint: `${domain}/logout`,
|
|
59
|
+
jwks_uri: `${issuer}/.well-known/jwks.json`,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
web: {
|
|
63
|
+
settings: { redirect_uri: 'https://app.example.com/oauth' },
|
|
64
|
+
signoutArgs: {
|
|
65
|
+
extraQueryParams: { client_id: clientId, logout_uri: 'https://app.example.com' },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
native: {
|
|
69
|
+
settings: { redirect_uri: 'com.example.app://oauth' },
|
|
70
|
+
signoutArgs: {
|
|
71
|
+
extraQueryParams: { client_id: clientId, logout_uri: 'com.example.app://oauth' },
|
|
72
|
+
},
|
|
60
73
|
},
|
|
61
74
|
});
|
|
62
75
|
```
|
|
@@ -65,8 +78,8 @@ Configure the Cognito app client without a secret and register
|
|
|
65
78
|
`com.example.app://oauth` as an allowed callback and sign-out URL.
|
|
66
79
|
|
|
67
80
|
Cognito logout uses `logout_uri` instead of the standard
|
|
68
|
-
`post_logout_redirect_uri`. Leave `post_logout_redirect_uri` unset
|
|
69
|
-
|
|
81
|
+
`post_logout_redirect_uri`. Leave `post_logout_redirect_uri` unset and configure
|
|
82
|
+
the platform-specific default arguments as above, or pass them for one call:
|
|
70
83
|
|
|
71
84
|
```ts
|
|
72
85
|
await manager.signout({
|
package/docs/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Documentation
|
|
2
2
|
|
|
3
|
-
`capacitor-oidc`
|
|
4
|
-
[Getting started](GETTING_STARTED.md), then complete the
|
|
5
|
-
native platform and identity provider.
|
|
3
|
+
`capacitor-oidc` provides one `oidc-client-ts`-based manager for web, iOS, and
|
|
4
|
+
Android. Start with [Getting started](GETTING_STARTED.md), then complete the
|
|
5
|
+
setup for each native platform and your identity provider.
|
|
6
6
|
|
|
7
7
|
## Use the package
|
|
8
8
|
|
package/docs/TESTING.md
CHANGED
|
@@ -18,6 +18,7 @@ npm run verify:android
|
|
|
18
18
|
CI currently runs:
|
|
19
19
|
|
|
20
20
|
- TypeScript linting, Vitest, package builds, and `npm pack --dry-run`;
|
|
21
|
+
- unit coverage for web/native configuration resolution and navigation dispatch;
|
|
21
22
|
- iOS XCTest in an iOS 18.5 simulator;
|
|
22
23
|
- Android unit tests, assembly, and lint with SDK 36;
|
|
23
24
|
- packaged iOS and Android consumer builds with Capacitor 7 and 8;
|
|
@@ -35,7 +36,8 @@ also remain incomplete.
|
|
|
35
36
|
|
|
36
37
|
## Required physical-device coverage
|
|
37
38
|
|
|
38
|
-
Before a stable release, verify
|
|
39
|
+
Before a stable release, verify browser redirects, callbacks, popup navigation,
|
|
40
|
+
renewal, and logout, plus these flows on physical iOS and Android devices:
|
|
39
41
|
|
|
40
42
|
- system login and logout UI, provider-consent UI, cancellation, and callbacks;
|
|
41
43
|
- Web Crypto availability in the packaged Capacitor WebView;
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -15,6 +15,12 @@ The authorization request's `redirect_uri` must exactly match a callback
|
|
|
15
15
|
registered for the provider client. Check scheme, host, port, path, case, and
|
|
16
16
|
trailing slashes. Wildcard callback hosts are commonly unsupported.
|
|
17
17
|
|
|
18
|
+
## Web login returns without a user
|
|
19
|
+
|
|
20
|
+
Make the configured web callback route call `signinCallback()`. A logout callback
|
|
21
|
+
route must call `signoutCallback()` instead. Both routes must use exactly the URI
|
|
22
|
+
registered with the provider.
|
|
23
|
+
|
|
18
24
|
## Android does not return to the app
|
|
19
25
|
|
|
20
26
|
- Keep `MainActivity` in `singleTask` launch mode.
|
|
@@ -33,9 +39,10 @@ and that the callback scheme is registered in the target.
|
|
|
33
39
|
|
|
34
40
|
## Token, UserInfo, refresh, or revocation fails with a network error
|
|
35
41
|
|
|
36
|
-
These requests use the
|
|
37
|
-
to allow
|
|
38
|
-
not remove CORS requirements from token, UserInfo, refresh, or
|
|
42
|
+
These requests use the runtime's normal `fetch`. Configure the provider endpoint
|
|
43
|
+
to allow both web application and Capacitor origins through CORS. Static discovery
|
|
44
|
+
metadata does not remove CORS requirements from token, UserInfo, refresh, or
|
|
45
|
+
revocation calls.
|
|
39
46
|
|
|
40
47
|
## No refresh token is available
|
|
41
48
|
|
|
@@ -43,22 +50,25 @@ not remove CORS requirements from token, UserInfo, refresh, or revocation calls.
|
|
|
43
50
|
- Enable the refresh-token grant for the public client.
|
|
44
51
|
- Check provider-specific consent and rotation settings.
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
On native platforms, an expired user without a refresh token is removed and
|
|
54
|
+
`getValidUser()` returns `null`. Web behavior follows the configured upstream
|
|
55
|
+
silent-renew settings and may use an iframe.
|
|
48
56
|
|
|
49
57
|
## Startup renewal fails
|
|
50
58
|
|
|
51
|
-
`CapacitorUserManager.create()` restores secure local state
|
|
52
|
-
token renewal. When `automaticSilentRenew` is enabled, a
|
|
53
|
-
runs asynchronously and reports failures through
|
|
54
|
-
token-endpoint failures preserve the stored
|
|
55
|
-
removes it.
|
|
59
|
+
On native platforms, `CapacitorUserManager.create()` restores secure local state
|
|
60
|
+
but does not wait for token renewal. When `automaticSilentRenew` is enabled, a
|
|
61
|
+
required startup renewal runs asynchronously and reports failures through
|
|
62
|
+
`silentRenewError`. Temporary token-endpoint failures preserve the stored
|
|
63
|
+
session; a terminal `invalid_grant` removes it. Web automatic renewal follows
|
|
64
|
+
`oidc-client-ts` behavior.
|
|
56
65
|
|
|
57
66
|
## Logout does not return to the app
|
|
58
67
|
|
|
59
|
-
Register the post-logout URI at the provider
|
|
60
|
-
|
|
61
|
-
[Provider
|
|
68
|
+
Register the post-logout URI at the provider, add the browser callback route, and
|
|
69
|
+
register native schemes in each native application. Some providers use
|
|
70
|
+
non-standard parameters. Amazon Cognito uses `logout_uri`; see [Provider
|
|
71
|
+
configuration](PROVIDERS.md#amazon-cognito).
|
|
62
72
|
|
|
63
73
|
## `USER_CANCELLED` appears but Android UI remains visible
|
|
64
74
|
|