@chipmobilesdk/rn-auth 0.4.0 → 0.6.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.
Files changed (180) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +74 -14
  3. package/lib/commonjs/access/accessTier.js +111 -0
  4. package/lib/commonjs/access/accessTier.js.map +1 -0
  5. package/lib/commonjs/app-auth.js +13 -0
  6. package/lib/commonjs/app-auth.js.map +1 -0
  7. package/lib/commonjs/config/types.js +50 -0
  8. package/lib/commonjs/config/types.js.map +1 -0
  9. package/lib/commonjs/config/validateConfig.js +114 -0
  10. package/lib/commonjs/config/validateConfig.js.map +1 -0
  11. package/lib/commonjs/core/authMachine.js +406 -0
  12. package/lib/commonjs/core/authMachine.js.map +1 -0
  13. package/lib/commonjs/core/profile.js +59 -0
  14. package/lib/commonjs/core/profile.js.map +1 -0
  15. package/lib/commonjs/core/session.js +125 -0
  16. package/lib/commonjs/core/session.js.map +1 -0
  17. package/lib/commonjs/diagnostics/errors.js +83 -0
  18. package/lib/commonjs/diagnostics/errors.js.map +1 -0
  19. package/lib/commonjs/diagnostics/messageKeys.js +51 -0
  20. package/lib/commonjs/diagnostics/messageKeys.js.map +1 -0
  21. package/lib/commonjs/index.js +175 -0
  22. package/lib/commonjs/index.js.map +1 -0
  23. package/lib/commonjs/keychain.js +13 -0
  24. package/lib/commonjs/keychain.js.map +1 -0
  25. package/lib/commonjs/oidc/authClient.js +157 -0
  26. package/lib/commonjs/oidc/authClient.js.map +1 -0
  27. package/lib/commonjs/oidc/classifyError.js +65 -0
  28. package/lib/commonjs/oidc/classifyError.js.map +1 -0
  29. package/lib/commonjs/oidc/socialRouting.js +58 -0
  30. package/lib/commonjs/oidc/socialRouting.js.map +1 -0
  31. package/lib/commonjs/package.json +1 -0
  32. package/lib/commonjs/react/AuthProvider.js +37 -0
  33. package/lib/commonjs/react/AuthProvider.js.map +1 -0
  34. package/lib/commonjs/react/hooks.js +122 -0
  35. package/lib/commonjs/react/hooks.js.map +1 -0
  36. package/lib/commonjs/testing/conformance.js +148 -0
  37. package/lib/commonjs/testing/conformance.js.map +1 -0
  38. package/lib/commonjs/testing/index.js +53 -0
  39. package/lib/commonjs/testing/index.js.map +1 -0
  40. package/lib/commonjs/tokens/accessToken.js +165 -0
  41. package/lib/commonjs/tokens/accessToken.js.map +1 -0
  42. package/lib/commonjs/tokens/secureStore.js +60 -0
  43. package/lib/commonjs/tokens/secureStore.js.map +1 -0
  44. package/lib/module/access/accessTier.js +106 -0
  45. package/lib/module/access/accessTier.js.map +1 -0
  46. package/lib/module/app-auth.js +9 -0
  47. package/lib/module/app-auth.js.map +1 -0
  48. package/lib/module/config/types.js +46 -0
  49. package/lib/module/config/types.js.map +1 -0
  50. package/lib/module/config/validateConfig.js +110 -0
  51. package/lib/module/config/validateConfig.js.map +1 -0
  52. package/lib/module/core/authMachine.js +402 -0
  53. package/lib/module/core/authMachine.js.map +1 -0
  54. package/lib/module/core/profile.js +54 -0
  55. package/lib/module/core/profile.js.map +1 -0
  56. package/lib/module/core/session.js +118 -0
  57. package/lib/module/core/session.js.map +1 -0
  58. package/lib/module/diagnostics/errors.js +74 -0
  59. package/lib/module/diagnostics/errors.js.map +1 -0
  60. package/lib/module/diagnostics/messageKeys.js +46 -0
  61. package/lib/module/diagnostics/messageKeys.js.map +1 -0
  62. package/lib/module/index.js +33 -0
  63. package/lib/module/index.js.map +1 -0
  64. package/lib/module/keychain.js +9 -0
  65. package/lib/module/keychain.js.map +1 -0
  66. package/lib/module/oidc/authClient.js +152 -0
  67. package/lib/module/oidc/authClient.js.map +1 -0
  68. package/lib/module/oidc/classifyError.js +60 -0
  69. package/lib/module/oidc/classifyError.js.map +1 -0
  70. package/lib/module/oidc/socialRouting.js +52 -0
  71. package/lib/module/oidc/socialRouting.js.map +1 -0
  72. package/lib/module/package.json +1 -0
  73. package/lib/module/react/AuthProvider.js +31 -0
  74. package/lib/module/react/AuthProvider.js.map +1 -0
  75. package/lib/module/react/hooks.js +111 -0
  76. package/lib/module/react/hooks.js.map +1 -0
  77. package/lib/module/testing/conformance.js +140 -0
  78. package/lib/module/testing/conformance.js.map +1 -0
  79. package/lib/module/testing/index.js +25 -0
  80. package/lib/module/testing/index.js.map +1 -0
  81. package/lib/module/tokens/accessToken.js +161 -0
  82. package/lib/module/tokens/accessToken.js.map +1 -0
  83. package/lib/module/tokens/secureStore.js +56 -0
  84. package/lib/module/tokens/secureStore.js.map +1 -0
  85. package/lib/typescript/commonjs/access/accessTier.d.ts +14 -0
  86. package/lib/typescript/commonjs/access/accessTier.d.ts.map +1 -0
  87. package/lib/typescript/commonjs/app-auth.d.ts +7 -0
  88. package/lib/typescript/commonjs/app-auth.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/config/types.d.ts +171 -0
  90. package/lib/typescript/commonjs/config/types.d.ts.map +1 -0
  91. package/lib/typescript/commonjs/config/validateConfig.d.ts +8 -0
  92. package/lib/typescript/commonjs/config/validateConfig.d.ts.map +1 -0
  93. package/lib/typescript/commonjs/core/authMachine.d.ts +14 -0
  94. package/lib/typescript/commonjs/core/authMachine.d.ts.map +1 -0
  95. package/lib/typescript/commonjs/core/profile.d.ts +15 -0
  96. package/lib/typescript/commonjs/core/profile.d.ts.map +1 -0
  97. package/lib/typescript/commonjs/core/session.d.ts +60 -0
  98. package/lib/typescript/commonjs/core/session.d.ts.map +1 -0
  99. package/lib/typescript/commonjs/diagnostics/errors.d.ts +37 -0
  100. package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
  101. package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts +57 -0
  102. package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts.map +1 -0
  103. package/lib/typescript/commonjs/index.d.ts +27 -0
  104. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  105. package/lib/typescript/commonjs/keychain.d.ts +7 -0
  106. package/lib/typescript/commonjs/keychain.d.ts.map +1 -0
  107. package/lib/typescript/commonjs/oidc/authClient.d.ts +75 -0
  108. package/lib/typescript/commonjs/oidc/authClient.d.ts.map +1 -0
  109. package/lib/typescript/commonjs/oidc/classifyError.d.ts +28 -0
  110. package/lib/typescript/commonjs/oidc/classifyError.d.ts.map +1 -0
  111. package/lib/typescript/commonjs/oidc/socialRouting.d.ts +22 -0
  112. package/lib/typescript/commonjs/oidc/socialRouting.d.ts.map +1 -0
  113. package/lib/typescript/commonjs/package.json +1 -0
  114. package/lib/typescript/commonjs/react/AuthProvider.d.ts +17 -0
  115. package/lib/typescript/commonjs/react/AuthProvider.d.ts.map +1 -0
  116. package/lib/typescript/commonjs/react/hooks.d.ts +42 -0
  117. package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
  118. package/lib/typescript/commonjs/testing/conformance.d.ts +32 -0
  119. package/lib/typescript/commonjs/testing/conformance.d.ts.map +1 -0
  120. package/lib/typescript/commonjs/testing/index.d.ts +11 -0
  121. package/lib/typescript/commonjs/testing/index.d.ts.map +1 -0
  122. package/lib/typescript/commonjs/tokens/accessToken.d.ts +45 -0
  123. package/lib/typescript/commonjs/tokens/accessToken.d.ts.map +1 -0
  124. package/lib/typescript/commonjs/tokens/secureStore.d.ts +26 -0
  125. package/lib/typescript/commonjs/tokens/secureStore.d.ts.map +1 -0
  126. package/lib/typescript/module/access/accessTier.d.ts +14 -0
  127. package/lib/typescript/module/access/accessTier.d.ts.map +1 -0
  128. package/lib/typescript/module/app-auth.d.ts +7 -0
  129. package/lib/typescript/module/app-auth.d.ts.map +1 -0
  130. package/lib/typescript/module/config/types.d.ts +171 -0
  131. package/lib/typescript/module/config/types.d.ts.map +1 -0
  132. package/lib/typescript/module/config/validateConfig.d.ts +8 -0
  133. package/lib/typescript/module/config/validateConfig.d.ts.map +1 -0
  134. package/lib/typescript/module/core/authMachine.d.ts +14 -0
  135. package/lib/typescript/module/core/authMachine.d.ts.map +1 -0
  136. package/lib/typescript/module/core/profile.d.ts +15 -0
  137. package/lib/typescript/module/core/profile.d.ts.map +1 -0
  138. package/lib/typescript/module/core/session.d.ts +60 -0
  139. package/lib/typescript/module/core/session.d.ts.map +1 -0
  140. package/lib/typescript/module/diagnostics/errors.d.ts +37 -0
  141. package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
  142. package/lib/typescript/module/diagnostics/messageKeys.d.ts +57 -0
  143. package/lib/typescript/module/diagnostics/messageKeys.d.ts.map +1 -0
  144. package/lib/typescript/module/index.d.ts +27 -0
  145. package/lib/typescript/module/index.d.ts.map +1 -0
  146. package/lib/typescript/module/keychain.d.ts +7 -0
  147. package/lib/typescript/module/keychain.d.ts.map +1 -0
  148. package/lib/typescript/module/oidc/authClient.d.ts +75 -0
  149. package/lib/typescript/module/oidc/authClient.d.ts.map +1 -0
  150. package/lib/typescript/module/oidc/classifyError.d.ts +28 -0
  151. package/lib/typescript/module/oidc/classifyError.d.ts.map +1 -0
  152. package/lib/typescript/module/oidc/socialRouting.d.ts +22 -0
  153. package/lib/typescript/module/oidc/socialRouting.d.ts.map +1 -0
  154. package/lib/typescript/module/package.json +1 -0
  155. package/lib/typescript/module/react/AuthProvider.d.ts +17 -0
  156. package/lib/typescript/module/react/AuthProvider.d.ts.map +1 -0
  157. package/lib/typescript/module/react/hooks.d.ts +42 -0
  158. package/lib/typescript/module/react/hooks.d.ts.map +1 -0
  159. package/lib/typescript/module/testing/conformance.d.ts +32 -0
  160. package/lib/typescript/module/testing/conformance.d.ts.map +1 -0
  161. package/lib/typescript/module/testing/index.d.ts +11 -0
  162. package/lib/typescript/module/testing/index.d.ts.map +1 -0
  163. package/lib/typescript/module/tokens/accessToken.d.ts +45 -0
  164. package/lib/typescript/module/tokens/accessToken.d.ts.map +1 -0
  165. package/lib/typescript/module/tokens/secureStore.d.ts +26 -0
  166. package/lib/typescript/module/tokens/secureStore.d.ts.map +1 -0
  167. package/package.json +68 -21
  168. package/skills/sdk-rn-auth/SKILL.md +35 -2
  169. package/src/config/types.ts +53 -5
  170. package/src/config/validateConfig.ts +32 -1
  171. package/src/core/authMachine.ts +40 -6
  172. package/src/core/profile.ts +6 -1
  173. package/src/core/session.ts +49 -3
  174. package/src/diagnostics/errors.ts +7 -5
  175. package/src/index.ts +7 -0
  176. package/src/oidc/authClient.ts +19 -1
  177. package/src/oidc/classifyError.ts +2 -1
  178. package/src/oidc/socialRouting.ts +3 -1
  179. package/src/react/hooks.ts +53 -14
  180. package/src/tokens/accessToken.ts +20 -9
@@ -0,0 +1,406 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createAuthMachine = createAuthMachine;
7
+ var _rnCore = require("@chipmobilesdk/rn-core");
8
+ var _messageKeys = require("../diagnostics/messageKeys.js");
9
+ var _validateConfig = require("../config/validateConfig.js");
10
+ var _authClient = require("../oidc/authClient.js");
11
+ var _socialRouting = require("../oidc/socialRouting.js");
12
+ var _profile = require("./profile.js");
13
+ var _accessTier = require("../access/accessTier.js");
14
+ var _session = require("./session.js");
15
+ var _secureStore = require("../tokens/secureStore.js");
16
+ var _accessToken = require("../tokens/accessToken.js");
17
+ var _errors = require("../diagnostics/errors.js");
18
+ /**
19
+ * Auth state machine / orchestrator (FR-005, FR-022, R5, R7). Holds the single
20
+ * active session, wires the OidcAuthClient + SecureTokenStore ports, profile
21
+ * mapping, access-tier evaluation, per-resource tokens, restore, and sign-out.
22
+ *
23
+ * Every operation that starts or ends a session bumps `sessionEpoch`. Work that
24
+ * awaited across such a change — a token refresh, a restore, an authorize —
25
+ * compares the epoch it started with before writing anything back, so a sign-out
26
+ * can never be undone by a request that was already in flight.
27
+ */
28
+
29
+ const SIGNED_OUT = {
30
+ status: 'signed-out',
31
+ profile: undefined,
32
+ accessTier: undefined,
33
+ restore: 'unavailable',
34
+ error: undefined
35
+ };
36
+ function createAuthMachine(config, options = {}) {
37
+ // Throws AuthConfigError before anything else (FR-005, US4 scenario 2).
38
+ (0, _validateConfig.validateConfig)(config);
39
+
40
+ // rn-core's one platform source (CORE-09). Outside Android and iOS (tests on
41
+ // Node, web) the providers are resolved as for iOS, as before.
42
+ const detected = (0, _rnCore.currentPlatform)();
43
+ const platform = options.platform ?? (detected === 'unsupported' ? 'ios' : detected);
44
+ const secureStore = config.secureStore;
45
+ const authClient = config.authClient ?? (0, _authClient.createAppAuthClient)();
46
+ const resources = config.resources ?? [];
47
+ // Declared since 0.1.0 and read by nothing until now (AUTH-15).
48
+ const messages = (0, _messageKeys.resolveMessages)(config.messages);
49
+ let state = Object.freeze({
50
+ status: 'loading',
51
+ restore: 'pending'
52
+ });
53
+ let refreshToken = null;
54
+ /** Kept for the end-session `id_token_hint`; without it a global sign-out is a no-op. */
55
+ let idToken = null;
56
+ let sessionEpoch = 0;
57
+ const listeners = (0, _rnCore.createListenerSet)();
58
+ /**
59
+ * Every Keychain write and delete, in order. A rotation persisted while a
60
+ * sign-out runs must not land after the sign-out's delete and resurrect the
61
+ * session on the next launch.
62
+ */
63
+ let storeQueue = Promise.resolve();
64
+ const enqueueStoreOp = op => {
65
+ const next = storeQueue.then(op);
66
+ // The queue itself never rejects, so one failed write does not poison the
67
+ // writes after it; the caller still sees its own failure through `next`.
68
+ storeQueue = next.catch(() => undefined);
69
+ return next;
70
+ };
71
+
72
+ /** The artifact as last written or read, so an identical write is skipped. */
73
+ let storedSession = null;
74
+ const writeSession = (session, epoch) => enqueueStoreOp(async () => {
75
+ if (epoch !== sessionEpoch) {
76
+ return; // The session this belonged to has already ended.
77
+ }
78
+ const artifact = {
79
+ refreshToken: session.refreshToken,
80
+ profile: (0, _session.storedProfileFrom)(session.profile),
81
+ idToken: session.idToken
82
+ };
83
+ // A restore that rotated nothing used to write the Keychain again on
84
+ // every launch, on the startup path (AUTH-23).
85
+ if (storedSession && (0, _session.sameSession)(storedSession, artifact)) {
86
+ return;
87
+ }
88
+ await secureStore.setItem(_secureStore.AUTH_STORAGE_KEY, JSON.stringify(artifact));
89
+ storedSession = artifact;
90
+ });
91
+ const tokenManager = (0, _accessToken.createAccessTokenManager)({
92
+ authority: config.authority,
93
+ clientId: config.clientId,
94
+ redirectUrl: config.redirectUrl,
95
+ resources,
96
+ authClient,
97
+ getRefreshToken: () => refreshToken,
98
+ sessionEpoch: () => sessionEpoch,
99
+ async onRefreshTokenRotated(token, epoch) {
100
+ if (epoch !== sessionEpoch) {
101
+ return;
102
+ }
103
+ // Live immediately whatever happens to the write: the provider may
104
+ // already have retired the old token, so memory must not keep using it.
105
+ refreshToken = token;
106
+ if (!state.profile) {
107
+ return;
108
+ }
109
+ try {
110
+ await writeSession({
111
+ refreshToken: token,
112
+ profile: state.profile,
113
+ idToken: idToken ?? undefined
114
+ }, epoch);
115
+ } catch {
116
+ // The session stays usable in memory. The stored artifact keeps the
117
+ // previous token until the next successful write; a restart before
118
+ // then restores through it if the provider still accepts it, and
119
+ // otherwise lands on sign-in — never on a corrupted state.
120
+ }
121
+ }
122
+ });
123
+
124
+ /**
125
+ * The current snapshot, the same object until the state changes, so React reads
126
+ * it through `useSyncExternalStore` without re-rendering for nothing (PERF-02).
127
+ * Frozen: a consumer cannot change the machine's state by mutating it.
128
+ */
129
+ function getState() {
130
+ return state;
131
+ }
132
+ function setState(patch) {
133
+ const next = {
134
+ ...state,
135
+ ...patch
136
+ };
137
+ // No change, no new snapshot and no notification.
138
+ if ((0, _rnCore.shallowEqual)(state, next)) return;
139
+ state = Object.freeze(next);
140
+ if (patch.error) {
141
+ // The code and audience only; `detail` is already redacted but stays local.
142
+ channel.emit(patch.error.code, patch.error.audience === 'user' ? 'info' : 'warn', {
143
+ status: state.status,
144
+ retryable: patch.error.retryable
145
+ });
146
+ }
147
+ // Isolated: a subscriber that throws neither stops the others nor turns a
148
+ // completed sign-in into an error; rn-core reports it instead (CORE-03).
149
+ listeners.notify(getState());
150
+ }
151
+
152
+ /** Ends the local session: memory, cached access tokens, and the stored artifact. */
153
+ async function clearPersisted() {
154
+ sessionEpoch += 1;
155
+ refreshToken = null;
156
+ idToken = null;
157
+ storedSession = null;
158
+ tokenManager.clear();
159
+ await enqueueStoreOp(() => secureStore.removeItem(_secureStore.AUTH_STORAGE_KEY));
160
+ }
161
+ return {
162
+ getState,
163
+ subscribe: listener => listeners.add(listener),
164
+ async restore() {
165
+ sessionEpoch += 1;
166
+ const epoch = sessionEpoch;
167
+ setState({
168
+ status: 'loading',
169
+ restore: 'pending',
170
+ error: undefined
171
+ });
172
+ let result;
173
+ try {
174
+ result = await (0, _session.restoreSession)({
175
+ secureStore,
176
+ authority: config.authority,
177
+ clientId: config.clientId,
178
+ redirectUrl: config.redirectUrl,
179
+ scopes: config.scopes,
180
+ authClient,
181
+ mapping: config.accessTierMapping
182
+ });
183
+ } catch (error) {
184
+ // The store could not be read. Nothing is known, nothing is deleted.
185
+ if (epoch === sessionEpoch) {
186
+ setState({
187
+ ...SIGNED_OUT,
188
+ status: 'error',
189
+ error: (0, _errors.toAuthError)(error)
190
+ });
191
+ }
192
+ return getState();
193
+ }
194
+ if (epoch !== sessionEpoch) {
195
+ // A sign-in or sign-out ran meanwhile; its outcome stands.
196
+ return getState();
197
+ }
198
+ storedSession = result.persisted ?? null;
199
+ if (result.outcome === 'restored' && result.profile && result.refreshToken) {
200
+ refreshToken = result.refreshToken;
201
+ idToken = result.idToken ?? null;
202
+ try {
203
+ await writeSession({
204
+ refreshToken: result.refreshToken,
205
+ profile: result.profile,
206
+ idToken: result.idToken
207
+ }, epoch);
208
+ } catch {
209
+ // The refresh succeeded, so the user is signed in for this run. Only
210
+ // the next launch is affected, and it falls back to sign-in.
211
+ }
212
+ if (epoch !== sessionEpoch) {
213
+ return getState();
214
+ }
215
+ setState({
216
+ status: 'authenticated',
217
+ profile: result.profile,
218
+ accessTier: result.accessTier,
219
+ restore: 'restored',
220
+ error: undefined
221
+ });
222
+ } else if (result.outcome === 'offline' && result.profile) {
223
+ refreshToken = result.refreshToken ?? null;
224
+ idToken = result.idToken ?? null;
225
+ setState({
226
+ status: 'authenticated',
227
+ profile: result.profile,
228
+ accessTier: result.accessTier ?? (0, _accessTier.failClosedTier)(),
229
+ restore: 'offline',
230
+ error: undefined
231
+ });
232
+ } else {
233
+ await clearPersisted();
234
+ setState(SIGNED_OUT);
235
+ }
236
+ return getState();
237
+ },
238
+ async signIn(providerId) {
239
+ sessionEpoch += 1;
240
+ const epoch = sessionEpoch;
241
+ setState({
242
+ status: 'authenticating',
243
+ error: undefined
244
+ });
245
+ let provider;
246
+ try {
247
+ provider = (0, _socialRouting.resolveProvider)(config, providerId, platform);
248
+ } catch (error) {
249
+ setState({
250
+ status: 'error',
251
+ error: (0, _errors.toAuthError)(error, 'configuration-error', 'auth.error.configuration')
252
+ });
253
+ return getState();
254
+ }
255
+ try {
256
+ const tokens = await authClient.authorize({
257
+ authority: config.authority,
258
+ clientId: config.clientId,
259
+ redirectUrl: config.redirectUrl,
260
+ scopes: config.scopes,
261
+ additionalParameters: (0, _socialRouting.buildAdditionalParameters)(provider)
262
+ });
263
+ if (epoch !== sessionEpoch) {
264
+ return getState();
265
+ }
266
+ if (!tokens.refreshToken) {
267
+ // `offline_access` is required by configuration, so its absence is the
268
+ // tenant's doing. Signing in anyway would give a session that silently
269
+ // never survives a restart.
270
+ setState({
271
+ status: 'error',
272
+ error: new _errors.AuthError({
273
+ code: 'configuration-error',
274
+ messageKey: 'auth.error.configuration',
275
+ audience: 'developer',
276
+ detail: 'authorize returned no refresh token; check that the app registration grants offline_access'
277
+ })
278
+ });
279
+ return getState();
280
+ }
281
+ const profile = (0, _profile.mapClaimsToProfile)(tokens.claims, providerId);
282
+ const accessTier = (0, _accessTier.evaluateAccessTier)(tokens.claims, config.accessTierMapping);
283
+ // Written first, committed to memory second: a failed write leaves no
284
+ // half-signed-in session holding a refresh token that was never stored.
285
+ await writeSession({
286
+ refreshToken: tokens.refreshToken,
287
+ profile,
288
+ idToken: tokens.idToken
289
+ }, epoch);
290
+ if (epoch !== sessionEpoch) {
291
+ return getState();
292
+ }
293
+ // Single active account: a new sign-in replaces any prior session.
294
+ refreshToken = tokens.refreshToken;
295
+ idToken = tokens.idToken ?? null;
296
+ tokenManager.clear();
297
+ setState({
298
+ status: 'authenticated',
299
+ profile,
300
+ accessTier,
301
+ restore: 'restored',
302
+ error: undefined
303
+ });
304
+ } catch (error) {
305
+ if (epoch !== sessionEpoch) {
306
+ return getState();
307
+ }
308
+ const authError = (0, _errors.toAuthError)(error);
309
+ if (authError.code === 'provider-cancelled') {
310
+ setState({
311
+ status: 'cancelled',
312
+ error: authError
313
+ });
314
+ } else {
315
+ setState({
316
+ status: 'error',
317
+ error: authError
318
+ });
319
+ }
320
+ }
321
+ return getState();
322
+ },
323
+ async signOut() {
324
+ await clearPersisted();
325
+ setState(SIGNED_OUT);
326
+ },
327
+ async signOutGlobal() {
328
+ let result = {
329
+ global: 'ended'
330
+ };
331
+ try {
332
+ await authClient.endSession({
333
+ authority: config.authority,
334
+ clientId: config.clientId,
335
+ redirectUrl: config.redirectUrl,
336
+ idToken: idToken ?? undefined
337
+ });
338
+ } catch (error) {
339
+ // Reported, not swallowed: the tenant session may still be alive. It
340
+ // still must not block clearing local state.
341
+ result = {
342
+ global: 'failed',
343
+ error: (0, _errors.toAuthError)(error)
344
+ };
345
+ }
346
+ await clearPersisted();
347
+ setState(SIGNED_OUT);
348
+ return result;
349
+ },
350
+ async requestAccessToken(resourceKey, tokenOptions) {
351
+ const epoch = sessionEpoch;
352
+ // Only a real network refresh is a `token-refreshing` phase; a cache hit
353
+ // would otherwise flash every subscriber twice for nothing.
354
+ const refreshing = state.status === 'authenticated' && (tokenOptions?.forceRefresh === true || !tokenManager.hasFreshToken(resourceKey));
355
+ if (refreshing) {
356
+ setState({
357
+ status: 'token-refreshing'
358
+ });
359
+ }
360
+ const result = await tokenManager.request(resourceKey, tokenOptions);
361
+ // Restored only if nothing else moved the session meanwhile: a sign-out
362
+ // during the refresh used to be overwritten back to `authenticated`.
363
+ if (refreshing && epoch === sessionEpoch && state.status === 'token-refreshing') {
364
+ setState({
365
+ status: 'authenticated'
366
+ });
367
+ }
368
+ return result;
369
+ },
370
+ getAccessTier() {
371
+ return state.accessTier ?? (0, _accessTier.failClosedTier)();
372
+ },
373
+ canAccessPremium() {
374
+ const tier = state.accessTier ?? (0, _accessTier.failClosedTier)();
375
+ return {
376
+ allowed: tier.tier === 'premium' && tier.verification === 'verified',
377
+ tier
378
+ };
379
+ },
380
+ requirePremium() {
381
+ const tier = state.accessTier ?? (0, _accessTier.failClosedTier)();
382
+ const allowed = tier.tier === 'premium' && tier.verification === 'verified';
383
+ if (!allowed) {
384
+ setState({
385
+ status: 'access-denied'
386
+ });
387
+ }
388
+ return {
389
+ allowed,
390
+ tier
391
+ };
392
+ },
393
+ getMessages() {
394
+ return messages;
395
+ },
396
+ getPlatformProvider() {
397
+ return (0, _socialRouting.defaultProviderForPlatform)(config, platform);
398
+ },
399
+ getPlatformProviders() {
400
+ return (0, _socialRouting.availableProvidersForPlatform)(config, platform);
401
+ }
402
+ };
403
+ }
404
+ /** Every error the machine lands in also goes to the app's SDK sinks (CORE-08). */
405
+ const channel = (0, _rnCore.createDiagnosticChannel)('rn-auth');
406
+ //# sourceMappingURL=authMachine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_rnCore","require","_messageKeys","_validateConfig","_authClient","_socialRouting","_profile","_accessTier","_session","_secureStore","_accessToken","_errors","SIGNED_OUT","status","profile","undefined","accessTier","restore","error","createAuthMachine","config","options","validateConfig","detected","currentPlatform","platform","secureStore","authClient","createAppAuthClient","resources","messages","resolveMessages","state","Object","freeze","refreshToken","idToken","sessionEpoch","listeners","createListenerSet","storeQueue","Promise","resolve","enqueueStoreOp","op","next","then","catch","storedSession","writeSession","session","epoch","artifact","storedProfileFrom","sameSession","setItem","AUTH_STORAGE_KEY","JSON","stringify","tokenManager","createAccessTokenManager","authority","clientId","redirectUrl","getRefreshToken","onRefreshTokenRotated","token","getState","setState","patch","shallowEqual","channel","emit","code","audience","retryable","notify","clearPersisted","clear","removeItem","subscribe","listener","add","result","restoreSession","scopes","mapping","accessTierMapping","toAuthError","persisted","outcome","failClosedTier","signIn","providerId","provider","resolveProvider","tokens","authorize","additionalParameters","buildAdditionalParameters","AuthError","messageKey","detail","mapClaimsToProfile","claims","evaluateAccessTier","authError","signOut","signOutGlobal","global","endSession","requestAccessToken","resourceKey","tokenOptions","refreshing","forceRefresh","hasFreshToken","request","getAccessTier","canAccessPremium","tier","allowed","verification","requirePremium","getMessages","getPlatformProvider","defaultProviderForPlatform","getPlatformProviders","availableProvidersForPlatform","createDiagnosticChannel"],"sourceRoot":"../../../src","sources":["core/authMachine.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.describeProviderIdentity = describeProviderIdentity;
7
+ exports.mapClaimsToProfile = mapClaimsToProfile;
8
+ /**
9
+ * Claims → Profile mapping (FR-006). Tolerant of Apple private-relay emails and
10
+ * missing display name / given name (edge cases).
11
+ */
12
+
13
+ function asString(value) {
14
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
15
+ }
16
+ function looksLikeEmail(value) {
17
+ return !!value && /.+@.+\..+/.test(value);
18
+ }
19
+
20
+ /** Map id-token claims to the app-visible Profile. */
21
+ function mapClaimsToProfile(claims, providerId) {
22
+ const tenantUserId = asString(claims.oid) ?? asString(claims.sub) ?? asString(claims.unique_name) ?? 'unknown';
23
+ const givenName = asString(claims.given_name);
24
+ const familyName = asString(claims.family_name);
25
+ const composedName = [givenName, familyName].filter(Boolean).join(' ') || undefined;
26
+ const displayName = asString(claims.name) ?? composedName;
27
+ const preferred = asString(claims.preferred_username);
28
+ const email = asString(claims.email) ?? (looksLikeEmail(preferred) ? preferred : undefined);
29
+ const provider = providerId ?? asString(claims.idp) ?? asString(claims.identityProvider) ?? 'unknown';
30
+ return {
31
+ tenantUserId,
32
+ displayName,
33
+ email,
34
+ provider,
35
+ claims
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Describe the external provider identity behind the profile (FR-004 edge
41
+ * cases). `emailBehavior` is what a screen needs to explain an address the user
42
+ * did not choose: Apple's private relay forwards mail and is not the address
43
+ * they type anywhere else.
44
+ */
45
+ function describeProviderIdentity(claims, providerId) {
46
+ const provider = providerId ?? asString(claims.idp) ?? 'unknown';
47
+ const subject = asString(claims.sub) ?? asString(claims.oid) ?? 'unknown';
48
+ const email = asString(claims.email);
49
+ let emailBehavior = 'none';
50
+ if (email) {
51
+ emailBehavior = email.endsWith('@privaterelay.appleid.com') ? 'private-relay' : 'direct';
52
+ }
53
+ return {
54
+ provider,
55
+ subject,
56
+ emailBehavior
57
+ };
58
+ }
59
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["asString","value","length","undefined","looksLikeEmail","test","mapClaimsToProfile","claims","providerId","tenantUserId","oid","sub","unique_name","givenName","given_name","familyName","family_name","composedName","filter","Boolean","join","displayName","name","preferred","preferred_username","email","provider","idp","identityProvider","describeProviderIdentity","subject","emailBehavior","endsWith"],"sourceRoot":"../../../src","sources":["core/profile.ts"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;;AAIA,SAASA,QAAQA,CAACC,KAAc,EAAsB;EACrD,OAAO,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACC,MAAM,GAAG,CAAC,GAAGD,KAAK,GAAGE,SAAS;AACzE;AAEA,SAASC,cAAcA,CAACH,KAAyB,EAAW;EAC3D,OAAO,CAAC,CAACA,KAAK,IAAI,WAAW,CAACI,IAAI,CAACJ,KAAK,CAAC;AAC1C;;AAEA;AACO,SAASK,kBAAkBA,CACjCC,MAA+B,EAC/BC,UAAuB,EACb;EACV,MAAMC,YAAY,GACjBT,QAAQ,CAACO,MAAM,CAACG,GAAG,CAAC,IAAIV,QAAQ,CAACO,MAAM,CAACI,GAAG,CAAC,IAAIX,QAAQ,CAACO,MAAM,CAACK,WAAW,CAAC,IAAI,SAAS;EAE1F,MAAMC,SAAS,GAAGb,QAAQ,CAACO,MAAM,CAACO,UAAU,CAAC;EAC7C,MAAMC,UAAU,GAAGf,QAAQ,CAACO,MAAM,CAACS,WAAW,CAAC;EAC/C,MAAMC,YAAY,GAAG,CAACJ,SAAS,EAAEE,UAAU,CAAC,CAACG,MAAM,CAACC,OAAO,CAAC,CAACC,IAAI,CAAC,GAAG,CAAC,IAAIjB,SAAS;EACnF,MAAMkB,WAAW,GAAGrB,QAAQ,CAACO,MAAM,CAACe,IAAI,CAAC,IAAIL,YAAY;EAEzD,MAAMM,SAAS,GAAGvB,QAAQ,CAACO,MAAM,CAACiB,kBAAkB,CAAC;EACrD,MAAMC,KAAK,GAAGzB,QAAQ,CAACO,MAAM,CAACkB,KAAK,CAAC,KAAKrB,cAAc,CAACmB,SAAS,CAAC,GAAGA,SAAS,GAAGpB,SAAS,CAAC;EAE3F,MAAMuB,QAAQ,GACblB,UAAU,IAAIR,QAAQ,CAACO,MAAM,CAACoB,GAAG,CAAC,IAAI3B,QAAQ,CAACO,MAAM,CAACqB,gBAAgB,CAAC,IAAI,SAAS;EAErF,OAAO;IACNnB,YAAY;IACZY,WAAW;IACXI,KAAK;IACLC,QAAQ;IACRnB;EACD,CAAC;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASsB,wBAAwBA,CACvCtB,MAA+B,EAC/BC,UAAuB,EACJ;EACnB,MAAMkB,QAAQ,GAAGlB,UAAU,IAAIR,QAAQ,CAACO,MAAM,CAACoB,GAAG,CAAC,IAAI,SAAS;EAChE,MAAMG,OAAO,GAAG9B,QAAQ,CAACO,MAAM,CAACI,GAAG,CAAC,IAAIX,QAAQ,CAACO,MAAM,CAACG,GAAG,CAAC,IAAI,SAAS;EACzE,MAAMe,KAAK,GAAGzB,QAAQ,CAACO,MAAM,CAACkB,KAAK,CAAC;EACpC,IAAIM,aAAgD,GAAG,MAAM;EAC7D,IAAIN,KAAK,EAAE;IACVM,aAAa,GAAGN,KAAK,CAACO,QAAQ,CAAC,2BAA2B,CAAC,GAAG,eAAe,GAAG,QAAQ;EACzF;EACA,OAAO;IAAEN,QAAQ;IAAEI,OAAO;IAAEC;EAAc,CAAC;AAC5C","ignoreList":[]}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parsePersistedSession = parsePersistedSession;
7
+ exports.profileFromStored = profileFromStored;
8
+ exports.restoreSession = restoreSession;
9
+ exports.sameSession = sameSession;
10
+ exports.storedProfileFrom = storedProfileFrom;
11
+ var _secureStore = require("../tokens/secureStore.js");
12
+ var _profile = require("./profile.js");
13
+ var _accessTier = require("../access/accessTier.js");
14
+ var _errors = require("../diagnostics/errors.js");
15
+ /**
16
+ * Session restoration (FR-008, R5). Reads the persisted artifact, attempts a
17
+ * silent refresh, and classifies the outcome:
18
+ * - restored: fresh tokens + claims → authenticated
19
+ * - offline: the refresh could not complete for any reason other than the
20
+ * session being invalid — no network, a timeout, a 5xx, an error we
21
+ * cannot classify → cached profile read-only, tier unverified (fail
22
+ * closed) — clarify Q3
23
+ * - unavailable: no artifact, or the provider said the refresh token is no
24
+ * longer valid → signed-out reauth
25
+ *
26
+ * Only `unavailable` deletes the stored session, so it is reserved for a verdict
27
+ * the provider actually gave. Treating every unclassified error as expiry signed
28
+ * users out whenever the token endpoint had a bad moment.
29
+ */
30
+
31
+ /**
32
+ * The identity in the stored artifact: who, not what the token said.
33
+ *
34
+ * The whole claim set used to be written to the Keychain on every launch — all
35
+ * of it, groups included — for a value nothing reads back: the access tier is
36
+ * recomputed from fresh claims, and a restore that cannot reach the provider
37
+ * fails closed anyway (AUTH-23).
38
+ */
39
+
40
+ /** The artifact's identity as a profile. Artifacts written before 0.4.0 carry claims; they are kept. */
41
+ function profileFromStored(stored) {
42
+ return {
43
+ ...stored,
44
+ claims: 'claims' in stored ? stored.claims ?? {} : {}
45
+ };
46
+ }
47
+
48
+ /** What goes to the store: everything but the claims. */
49
+ function storedProfileFrom(profile) {
50
+ return {
51
+ tenantUserId: profile.tenantUserId,
52
+ displayName: profile.displayName,
53
+ email: profile.email,
54
+ provider: profile.provider
55
+ };
56
+ }
57
+
58
+ /** True when the artifact would be byte-identical, so the write can be skipped. */
59
+ function sameSession(a, b) {
60
+ return a.refreshToken === b.refreshToken && a.idToken === b.idToken && a.profile.tenantUserId === b.profile.tenantUserId && a.profile.displayName === b.profile.displayName && a.profile.email === b.profile.email && a.profile.provider === b.profile.provider;
61
+ }
62
+ function parsePersistedSession(raw) {
63
+ if (!raw) {
64
+ return null;
65
+ }
66
+ try {
67
+ const parsed = JSON.parse(raw);
68
+ if (parsed && typeof parsed.refreshToken === 'string' && parsed.profile) {
69
+ return parsed;
70
+ }
71
+ return null;
72
+ } catch {
73
+ return null;
74
+ }
75
+ }
76
+ async function restoreSession(deps) {
77
+ const raw = await deps.secureStore.getItem(_secureStore.AUTH_STORAGE_KEY);
78
+ const persisted = parsePersistedSession(raw);
79
+ if (!persisted) {
80
+ return {
81
+ outcome: 'unavailable'
82
+ };
83
+ }
84
+ try {
85
+ const tokens = await deps.authClient.refresh({
86
+ authority: deps.authority,
87
+ clientId: deps.clientId,
88
+ redirectUrl: deps.redirectUrl,
89
+ refreshToken: persisted.refreshToken,
90
+ scopes: deps.scopes
91
+ });
92
+ // A refresh response may carry no id token, and so no claims. The stored
93
+ // profile is then still the best identity there is; an empty one is not.
94
+ const hasClaims = Object.keys(tokens.claims).length > 0;
95
+ return {
96
+ outcome: 'restored',
97
+ persisted,
98
+ // The provider id came from the sign-in and is not in the claims: a
99
+ // refresh answered `idp: 'google.com'`, so a restored profile used to
100
+ // report a different provider than the same session did before (AUTH-10).
101
+ profile: hasClaims ? (0, _profile.mapClaimsToProfile)(tokens.claims, persisted.profile.provider) : profileFromStored(persisted.profile),
102
+ accessTier: hasClaims ? (0, _accessTier.evaluateAccessTier)(tokens.claims, deps.mapping) : (0, _accessTier.failClosedTier)(),
103
+ refreshToken: tokens.refreshToken || persisted.refreshToken,
104
+ idToken: tokens.idToken || persisted.idToken
105
+ };
106
+ } catch (error) {
107
+ if ((0, _errors.isAuthError)(error) && error.code === 'session-expired') {
108
+ // The provider rejected the refresh token: reauthentication is required.
109
+ return {
110
+ outcome: 'unavailable'
111
+ };
112
+ }
113
+ // Anything else is no verdict on the session. Keep the cached identity
114
+ // read-only and fail closed on entitlement; the next restore tries again.
115
+ return {
116
+ outcome: 'offline',
117
+ persisted,
118
+ profile: profileFromStored(persisted.profile),
119
+ accessTier: (0, _accessTier.failClosedTier)(),
120
+ refreshToken: persisted.refreshToken,
121
+ idToken: persisted.idToken
122
+ };
123
+ }
124
+ }
125
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_secureStore","require","_profile","_accessTier","_errors","profileFromStored","stored","claims","storedProfileFrom","profile","tenantUserId","displayName","email","provider","sameSession","a","b","refreshToken","idToken","parsePersistedSession","raw","parsed","JSON","parse","restoreSession","deps","secureStore","getItem","AUTH_STORAGE_KEY","persisted","outcome","tokens","authClient","refresh","authority","clientId","redirectUrl","scopes","hasClaims","Object","keys","length","mapClaimsToProfile","accessTier","evaluateAccessTier","mapping","failClosedTier","error","isAuthError","code"],"sourceRoot":"../../../src","sources":["core/session.ts"],"mappings":"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","ignoreList":[]}