@chipmobilesdk/rn-auth 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +239 -113
- package/README.md +221 -190
- package/package.json +72 -54
- package/skills/sdk-rn-auth/SKILL.md +65 -63
- package/src/access/accessTier.ts +88 -88
- package/src/app-auth.ts +6 -0
- package/src/config/types.ts +154 -154
- package/src/config/validateConfig.ts +114 -108
- package/src/core/authMachine.ts +380 -364
- package/src/core/profile.ts +57 -60
- package/src/core/session.ts +105 -112
- package/src/diagnostics/errors.ts +99 -85
- package/src/diagnostics/messageKeys.ts +72 -61
- package/src/index.ts +72 -83
- package/src/keychain.ts +6 -0
- package/src/oidc/authClient.ts +236 -199
- package/src/oidc/classifyError.ts +76 -76
- package/src/oidc/socialRouting.ts +66 -73
- package/src/react/AuthProvider.tsx +30 -47
- package/src/react/hooks.ts +103 -91
- package/src/testing/conformance.ts +177 -0
- package/src/testing/index.ts +30 -0
- package/src/tokens/accessToken.ts +159 -164
- package/src/tokens/secureStore.ts +85 -52
package/CHANGELOG.md
CHANGED
|
@@ -1,113 +1,239 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
[
|
|
1
|
+
# @chipmobilesdk/rn-auth
|
|
2
|
+
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- One diagnostic stream: install a sink with `installSdkSink` from
|
|
8
|
+
`@chipmobilesdk/rn-core` and it receives what every package observes (events,
|
|
9
|
+
failures, warnings) as `SdkDiagnostic`s, redacted. Listeners are notified through
|
|
10
|
+
rn-core, so a listener that throws no longer stops the others nor fails the call that
|
|
11
|
+
notified, and its error is reported rather than swallowed. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
12
|
+
|
|
13
|
+
- rn-ads: a banner's auto-refresh is a new cycle, so its `loaded` and `impression`
|
|
14
|
+
events are no longer deduplicated away; the dedupe memory is bounded. A throwing
|
|
15
|
+
status, consent or placement listener is reported as an `internal_error` event.
|
|
16
|
+
- rn-i18n: new `onDiagnostic` config receives every diagnostic (`I18nDiagnostic`,
|
|
17
|
+
with a stable `code`); without it, warnings go to `console.warn` in development
|
|
18
|
+
builds only. The warn-once memory is bounded.
|
|
19
|
+
- rn-chart: now depends on rn-core for its diagnostics.
|
|
20
|
+
- rn-payment: status, entitlement and pending listeners report a throw to the logger
|
|
21
|
+
instead of swallowing it.
|
|
22
|
+
|
|
23
|
+
- The package's errors extend `SdkError` from the new `@chipmobilesdk/rn-core`
|
|
24
|
+
dependency: `isSdkError` recognises them alongside every other package's, and each
|
|
25
|
+
carries `pkg`, `code` and `retryable`. Names and codes are unchanged. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
26
|
+
|
|
27
|
+
- rn-ai and rn-camera: `retryable` is the new name of `recoverable`, which stays as a
|
|
28
|
+
deprecated alias.
|
|
29
|
+
- rn-auth: `retryable` is true for `network-unavailable`. `redact` also removes URLs,
|
|
30
|
+
e-mail addresses and UUIDs.
|
|
31
|
+
- rn-ads: `redact` also removes JWTs and e-mail addresses, and reduces an `AdsError`
|
|
32
|
+
to its code.
|
|
33
|
+
- rn-ai: an error message quoted from the gateway is pattern-redacted.
|
|
34
|
+
- rn-camera: `redact` also removes JWTs, e-mail addresses and UUIDs.
|
|
35
|
+
- rn-theme: `ThemeConfigError` has `code: 'invalid_config'` and `ThemeContrastError`
|
|
36
|
+
`code: 'contrast'` (new `ThemeErrorCode` type).
|
|
37
|
+
- rn-i18n: `I18nConfigError` has `code: 'invalid_config'` and `UnitConversionError`
|
|
38
|
+
`code: 'unit_conversion'` (new `I18nErrorCode` type).
|
|
39
|
+
|
|
40
|
+
- Native peers load through `lazyPeer` from `@chipmobilesdk/rn-core`, on first use,
|
|
41
|
+
and a missing one is each package's own typed error. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
42
|
+
|
|
43
|
+
- rn-auth: creating `auth` no longer loads react-native-app-auth or
|
|
44
|
+
react-native-keychain; each loads on first use. New entrypoints
|
|
45
|
+
`@chipmobilesdk/rn-auth/app-auth` and `/keychain`. The default platform comes from
|
|
46
|
+
rn-core.
|
|
47
|
+
- rn-camera: a preview whose VisionCamera feed cannot load fails the session with
|
|
48
|
+
`cameraUnavailable` (new `controller.reportSurfaceUnavailable()`), instead of
|
|
49
|
+
showing black with no error. A missing VisionCamera module is `cameraUnavailable`.
|
|
50
|
+
- rn-notification: `createMmkvStore` reports a fallback to memory as
|
|
51
|
+
`STATE_STORE_DEGRADED` (to the SDK sinks and a new `onDegraded` option) and
|
|
52
|
+
exposes `durable`.
|
|
53
|
+
- rn-payment: an iOS app validates its catalog against the iOS product ids; the
|
|
54
|
+
default platform used to be Android everywhere. A missing react-native-iap is
|
|
55
|
+
`PAYMENT_UNAVAILABLE`.
|
|
56
|
+
- rn-theme: `buildThemes` runs without React Native (new `hairlineWidth` option) and
|
|
57
|
+
importing the package no longer loads Unistyles; `applyThemeMode` loads it on
|
|
58
|
+
first use.
|
|
59
|
+
- rn-ads, rn-local-db: the same loading, with the same error codes as before.
|
|
60
|
+
|
|
61
|
+
- Hooks read through `useSyncExternalStore` (rn-core's `useExternalStore`) and
|
|
62
|
+
re-render only when what they return changes. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
63
|
+
|
|
64
|
+
- rn-auth: `useProfile` and `useAccessTier` no longer re-render for a status change,
|
|
65
|
+
and the provider's context no longer changes on every transition. New
|
|
66
|
+
`useAuthSelector`. `auth.getState()` returns the same frozen object until the state
|
|
67
|
+
changes, instead of a copy per call.
|
|
68
|
+
- rn-payment: `useEntitlement` re-renders only when its own entitlement changes; the
|
|
69
|
+
engine keeps unchanged entitlement objects across syncs and does not notify for a
|
|
70
|
+
sync that changed nothing.
|
|
71
|
+
- rn-ads: `usePlacementState` and `useAdsStatus` read tear-free; `useAdsEvents` keeps
|
|
72
|
+
one subscription when given an inline listener.
|
|
73
|
+
- rn-i18n: `useTranslation` returns the same `t` until the locale changes, and
|
|
74
|
+
`useLocale`'s `setLocale` is stable.
|
|
75
|
+
- rn-ai: new `useAiBehaviorState`, with `client.subscribe` and a stable
|
|
76
|
+
`client.getBehaviorState()`.
|
|
77
|
+
|
|
78
|
+
- Every package's own copy is an rn-core message catalog that an app can translate. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
79
|
+
|
|
80
|
+
- rn-i18n: new `runtimeEntriesFromCatalog(catalog)` registers any SDK catalog in one
|
|
81
|
+
line, converting `{name}` variables to `{{name}}`.
|
|
82
|
+
- rn-ai: new `messageKeyForError(error)` gives the copy for every error code, and
|
|
83
|
+
`aiMessageSet`. The input placeholder default is neutral ("Type a message…"), and
|
|
84
|
+
two keys were added for errors that had none (`ai.error.signIn`, `ai.error.generic`).
|
|
85
|
+
- rn-auth: new `authMessages`, the catalog split into user and developer copy.
|
|
86
|
+
- rn-payment: new `paymentMessages`.
|
|
87
|
+
- rn-chart: summaries, announcements, adjustable-action labels, built-in state text
|
|
88
|
+
and legend hints come from `chartStrings`; pass `strings` to translate them. The
|
|
89
|
+
`accessibility.summaryFormatter` prop, declared before, now replaces the summary.
|
|
90
|
+
|
|
91
|
+
- Port conformance suites: one list of checks that a package's fake and its real adapter
|
|
92
|
+
both pass, so a test written against the fake proves something about the device. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
93
|
+
|
|
94
|
+
- rn-core: `@chipmobilesdk/rn-core/testing` adds `runChecks`, `expectConformance`,
|
|
95
|
+
`ensure` and `createFaultRegistry` (deterministic fault injection by named point).
|
|
96
|
+
- rn-camera: a `./testing` entrypoint with `runPermissionPortConformance`,
|
|
97
|
+
`runCameraEngineConformance` and the test adapter, which stays on the main
|
|
98
|
+
entrypoint too until the next major. `createTestCamera(...).prompts()` counts system
|
|
99
|
+
prompts.
|
|
100
|
+
- rn-payment: `runProviderPortConformance` in `./testing`, passed by the fake store and
|
|
101
|
+
the Play adapter.
|
|
102
|
+
- rn-ads: `runAdsEngineConformance` in `./testing`, passed by the fake engine and the
|
|
103
|
+
AdMob adapter.
|
|
104
|
+
- rn-auth: a `./testing` entrypoint with `createMemorySecureStore`,
|
|
105
|
+
`runSecureTokenStoreConformance` and `runOidcAuthClientConformance`, passed by the
|
|
106
|
+
in-memory doubles and the keychain and app-auth adapters.
|
|
107
|
+
|
|
108
|
+
### Patch Changes
|
|
109
|
+
|
|
110
|
+
- Optional properties in the public types (`AuthState`, `Profile`, `UseAccessTokenResult`
|
|
111
|
+
and others) now accept an explicit `undefined`, so apps compiling with
|
|
112
|
+
`exactOptionalPropertyTypes` type-check against the package. No runtime change. ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17))
|
|
113
|
+
- Updated dependencies ([#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17), [#17](https://github.com/operationd8979/chip-mobile-sdk/pull/17)):
|
|
114
|
+
- @chipmobilesdk/rn-core@0.1.0
|
|
115
|
+
|
|
116
|
+
## 0.3.1
|
|
117
|
+
|
|
118
|
+
### Patch Changes
|
|
119
|
+
|
|
120
|
+
- Packaging only; no code change. The package no longer declares `engines.node`: a
|
|
121
|
+
React Native package does not run on Node, so the field only produced install
|
|
122
|
+
warnings in apps on another Node version. rn-i18n's command-line tooling does run
|
|
123
|
+
on Node; its README's compatibility table states the version it needs. ([#14](https://github.com/operationd8979/chip-mobile-sdk/pull/14))
|
|
124
|
+
|
|
125
|
+
## [0.3.0] - 2026-11-01
|
|
126
|
+
|
|
127
|
+
Minor release fixing session integrity. Two type changes can need a one-line code
|
|
128
|
+
change (see Changed): `signOutGlobal()` resolves to a result instead of `void`, and
|
|
129
|
+
`OidcTokens.refreshToken` / `idToken` are optional.
|
|
130
|
+
|
|
131
|
+
### Fixed
|
|
132
|
+
|
|
133
|
+
- **A sign-out during a token refresh no longer revives the session.** The refresh
|
|
134
|
+
wrote its refresh token back into memory and set the state to `authenticated`
|
|
135
|
+
after the sign-out. Every session start and end now bumps a session generation,
|
|
136
|
+
and work that crossed one is discarded.
|
|
137
|
+
- **Rotated refresh tokens are persisted.** A rotation only reached memory, so a
|
|
138
|
+
restart came back with a token the provider may already have retired. Concurrent
|
|
139
|
+
`requestAccessToken` calls for one resource now share one network refresh, and a
|
|
140
|
+
cache hit no longer flashes `token-refreshing`.
|
|
141
|
+
- **Restore deletes the stored session only on an `invalid_grant` verdict.** Any
|
|
142
|
+
error other than a recognised network failure used to delete it, so a timeout or a
|
|
143
|
+
5xx signed users out. Errors are classified by OAuth and AADSTS codes in an ordered
|
|
144
|
+
table (`oidc/classifyError.ts`) instead of loose substrings; unclassified errors
|
|
145
|
+
restore `offline`.
|
|
146
|
+
- **Restore no longer stays `loading`** when the Keychain write fails, and keeps the
|
|
147
|
+
stored profile when a refresh returns no id token.
|
|
148
|
+
- **Sign-in commits only what it stored.** A failed Keychain write left a refresh
|
|
149
|
+
token in memory under an `error` state; an authorize without a refresh token now
|
|
150
|
+
reports a developer-facing `configuration-error` instead of a session that never
|
|
151
|
+
survives a restart.
|
|
152
|
+
- **`signOutGlobal()` sends the id token hint** and reports a failed end-session
|
|
153
|
+
instead of swallowing it.
|
|
154
|
+
- **A throwing state listener no longer turns a completed sign-in into an error.**
|
|
155
|
+
- **The development-only `console.warn` of the raw native error is removed.** It
|
|
156
|
+
bypassed redaction.
|
|
157
|
+
|
|
158
|
+
### Changed
|
|
159
|
+
|
|
160
|
+
- `signOutGlobal()` resolves to `GlobalSignOutResult` (`{ global: 'ended' | 'failed',
|
|
161
|
+
error? }`) instead of `void`.
|
|
162
|
+
- `OidcTokens.refreshToken` and `OidcTokens.idToken` are optional; a provider that
|
|
163
|
+
omits them is reported as absent rather than as an empty string. The persisted
|
|
164
|
+
session artifact gains an optional `idToken`; artifacts written by 0.2.1 still
|
|
165
|
+
restore.
|
|
166
|
+
|
|
167
|
+
## [0.2.1] - 2026-08-01
|
|
168
|
+
|
|
169
|
+
### Changed
|
|
170
|
+
|
|
171
|
+
- The package now ships its agent skill (`skills/`), which consuming apps
|
|
172
|
+
copy in with `scripts/sync-sdk-skills.mjs`. No code change.
|
|
173
|
+
|
|
174
|
+
## [0.2.0] - 2026-06-30
|
|
175
|
+
|
|
176
|
+
Add Facebook as a social sign-in provider (additive, backward compatible).
|
|
177
|
+
|
|
178
|
+
### Added
|
|
179
|
+
|
|
180
|
+
- `'facebook'` is now a valid `ProviderId`. Facebook is federated inside the
|
|
181
|
+
Entra External ID tenant like Google/Apple and routed with `domain_hint`
|
|
182
|
+
(`facebook.com`) — no native Facebook SDK and no new dependency.
|
|
183
|
+
- `auth.action.continueFacebook` message key with English default
|
|
184
|
+
`'Continue with Facebook'`.
|
|
185
|
+
- `Auth.getPlatformProviders()` and the `useSignInProviders()` hook return all
|
|
186
|
+
available providers for the current platform in configuration order, so a
|
|
187
|
+
platform can present multiple sign-in buttons (e.g. Google + Facebook).
|
|
188
|
+
|
|
189
|
+
### Changed
|
|
190
|
+
|
|
191
|
+
- `defaultProviderForPlatform` / `getPlatformProvider()` / `useSignInProvider()`
|
|
192
|
+
now return the first available provider in configuration order. Behavior is
|
|
193
|
+
unchanged for existing single-provider (Google/Apple-only) configurations.
|
|
194
|
+
|
|
195
|
+
### Notes
|
|
196
|
+
|
|
197
|
+
- Backward compatible: apps that do not configure Facebook observe no change.
|
|
198
|
+
- Adoption: add `{ id: 'facebook', platforms: ['ios','android'], domainHint:
|
|
199
|
+
'facebook.com', labelKey: 'auth.action.continueFacebook' }` to `providers`,
|
|
200
|
+
federate Facebook in the tenant, and render `useSignInProviders()` for the
|
|
201
|
+
multi-button experience. See the README and
|
|
202
|
+
`specs/004-facebook-auth-provider/`.
|
|
203
|
+
- iOS: offering Facebook (a third-party login) requires Sign in with Apple to
|
|
204
|
+
remain available (Apple guideline 4.8) — it does. Update Apple App Privacy and
|
|
205
|
+
Google Play Data Safety to add Facebook before release.
|
|
206
|
+
|
|
207
|
+
## [0.1.0] - 2026-06-24
|
|
208
|
+
|
|
209
|
+
Initial release of the reusable Microsoft Entra External ID auth library.
|
|
210
|
+
|
|
211
|
+
### Added
|
|
212
|
+
|
|
213
|
+
- `createAuth(config, options?)` controller with a single active account: sign-in,
|
|
214
|
+
session restore, local `signOut()` and global `signOutGlobal()`, per-resource
|
|
215
|
+
`requestAccessToken()`, `getAccessTier()`, and a `requirePremium()` gate.
|
|
216
|
+
- `AuthProvider` plus `useAuth`, `useProfile`, `useAccessTier`, `useAccessToken`,
|
|
217
|
+
and `useSignInProvider` hooks.
|
|
218
|
+
- Injectable ports `OidcAuthClient` and `SecureTokenStore`, with default adapters
|
|
219
|
+
`createAppAuthClient()` (react-native-app-auth, PKCE public client) and
|
|
220
|
+
`createKeychainSecureStore()` (react-native-keychain).
|
|
221
|
+
- Social routing via per-provider `domain_hint` (Google on Android, Apple on iOS),
|
|
222
|
+
with Google/Apple federated inside the tenant — no native social SDK required.
|
|
223
|
+
- Access-tier evaluation (`evaluateAccessTier`) that prefers stable group object
|
|
224
|
+
ids, ignores display names, and fails closed on missing/stale/overage claims.
|
|
225
|
+
- Token + refresh persistence restricted to platform secure storage; access
|
|
226
|
+
tokens cached in memory with silent refresh.
|
|
227
|
+
- Stable user-facing message keys with English defaults (`DEFAULT_MESSAGES`),
|
|
228
|
+
no i18n runtime dependency.
|
|
229
|
+
- Diagnostics (`AuthError`/`AuthConfigError`) with secret/token redaction.
|
|
230
|
+
|
|
231
|
+
### Notes
|
|
232
|
+
|
|
233
|
+
- New package; no migration required. Adoption notes and the tenant/provider
|
|
234
|
+
prerequisite checklist are in the README.
|
|
235
|
+
- Native redirect configuration and on-device provider flows must be validated
|
|
236
|
+
per `specs/003-mobile-entra-auth/contracts/native-setup.md` (the R8 spike).
|
|
237
|
+
|
|
238
|
+
[0.2.0]: #
|
|
239
|
+
[0.1.0]: #
|