capacitor-oidc 0.0.6 → 0.1.1
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 +32 -25
- package/SECURITY.md +27 -30
- 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 +52 -45
- package/docs/README.md +4 -4
- 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/docs/adr/index.md +6 -0
- package/docs/frameworks/ANGULAR.md +129 -0
- package/docs/frameworks/REACT.md +134 -0
- package/docs/frameworks/VUE.md +118 -0
- package/package.json +8 -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
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
# Provider configuration
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
The
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
|
@@ -43,20 +37,33 @@ const domain = 'https://example.auth.eu-central-1.amazoncognito.com';
|
|
|
43
37
|
const issuer = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}`;
|
|
44
38
|
|
|
45
39
|
const manager = await CapacitorUserManager.create({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
40
|
+
common: {
|
|
41
|
+
authority: issuer,
|
|
42
|
+
client_id: clientId,
|
|
43
|
+
scope: 'openid email profile aws.cognito.signin.user.admin',
|
|
44
|
+
automaticSilentRenew: true,
|
|
45
|
+
revokeTokensOnSignout: true,
|
|
46
|
+
metadata: {
|
|
47
|
+
issuer,
|
|
48
|
+
authorization_endpoint: `${domain}/oauth2/authorize`,
|
|
49
|
+
token_endpoint: `${domain}/oauth2/token`,
|
|
50
|
+
userinfo_endpoint: `${domain}/oauth2/userInfo`,
|
|
51
|
+
revocation_endpoint: `${domain}/oauth2/revoke`,
|
|
52
|
+
end_session_endpoint: `${domain}/logout`,
|
|
53
|
+
jwks_uri: `${issuer}/.well-known/jwks.json`,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
web: {
|
|
57
|
+
settings: { redirect_uri: 'https://app.example.com/oauth' },
|
|
58
|
+
signoutArgs: {
|
|
59
|
+
extraQueryParams: { client_id: clientId, logout_uri: 'https://app.example.com' },
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
native: {
|
|
63
|
+
settings: { redirect_uri: 'com.example.app://oauth' },
|
|
64
|
+
signoutArgs: {
|
|
65
|
+
extraQueryParams: { client_id: clientId, logout_uri: 'com.example.app://oauth' },
|
|
66
|
+
},
|
|
60
67
|
},
|
|
61
68
|
});
|
|
62
69
|
```
|
|
@@ -65,8 +72,8 @@ Configure the Cognito app client without a secret and register
|
|
|
65
72
|
`com.example.app://oauth` as an allowed callback and sign-out URL.
|
|
66
73
|
|
|
67
74
|
Cognito logout uses `logout_uri` instead of the standard
|
|
68
|
-
`post_logout_redirect_uri`. Leave `post_logout_redirect_uri` unset
|
|
69
|
-
|
|
75
|
+
`post_logout_redirect_uri`. Leave `post_logout_redirect_uri` unset and configure
|
|
76
|
+
the platform-specific default arguments as above, or pass them for one call:
|
|
70
77
|
|
|
71
78
|
```ts
|
|
72
79
|
await manager.signout({
|
|
@@ -175,7 +182,7 @@ and [redirect URI restrictions](https://learn.microsoft.com/en-us/entra/identity
|
|
|
175
182
|
|
|
176
183
|
## Other providers
|
|
177
184
|
|
|
178
|
-
Start with the
|
|
185
|
+
Start with the requirements above and the provider's OpenID Connect discovery
|
|
179
186
|
document. If discovery does not describe a usable native flow, pass explicit
|
|
180
187
|
`metadata` through the upstream `UserManagerSettings` rather than adding
|
|
181
188
|
provider-specific code to this package.
|
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
|
|
|
@@ -20,4 +20,4 @@ native platform and 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/)
|
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;
|