@molecule/app-auth 1.2.2 → 1.3.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 CHANGED
@@ -3,15 +3,11 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-10-16T21:58:38.432Z
6
+ Generated: 2026-10-17T07:07:31.667Z
7
7
  -->
8
8
 
9
9
  # @molecule/app-auth
10
10
 
11
- > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
12
- > It is written to be read by coding agents as much as by people, and is generated from this
13
- > package's source — edit `src/index.ts` JSDoc, not this file.
14
-
15
11
  Client-side authentication interface for molecule.dev.
16
12
 
17
13
  Provides a unified auth API that works across different auth strategies
@@ -21,6 +17,10 @@ client; `setClient`/`getClient` bond it; `login`/`logout`/`register`/
21
17
  bindings (e.g. `AuthProvider`/`useAuth` in `@molecule/app-react`) wrap the
22
18
  same client.
23
19
 
20
+ > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
21
+ > It is written to be read by coding agents as much as by people, and is generated from this
22
+ > package's source — edit `src/index.ts` JSDoc, not this file.
23
+
24
24
  ## Quick Start
25
25
 
26
26
  ```typescript
@@ -50,6 +50,30 @@ npm install @molecule/app-auth @molecule/app-bond @molecule/app-i18n @molecule/a
50
50
 
51
51
  ### Interfaces
52
52
 
53
+ #### `BrowserStorageAdapterOptions`
54
+
55
+ How {@link createBrowserStorageAdapter} picks the store it writes to.
56
+
57
+ ```typescript
58
+ interface BrowserStorageAdapterOptions {
59
+ /**
60
+ * The Web Storage area to persist to (default `'local'`).
61
+ *
62
+ * `'session'` is the narrower choice: a reload keeps the session, closing the
63
+ * tab ends it. Pick it when the app only has to survive navigations within one
64
+ * session — which is all a `page.reload()` asks for.
65
+ */
66
+ kind?: BrowserStorageKind
67
+ /**
68
+ * A store to use instead of resolving `window.localStorage` /
69
+ * `window.sessionStorage` (a test double, a namespaced wrapper, or the
70
+ * `Storage` object another library exposes). Anything with `getItem`/
71
+ * `setItem`/`removeItem` does.
72
+ */
73
+ storage?: StorageAdapter
74
+ }
75
+ ```
76
+
53
77
  #### `UserProfile`
54
78
 
55
79
  User profile information.
@@ -355,6 +379,12 @@ interface AuthClient<T = UserProfile> {
355
379
  *
356
380
  * Optional: a provider that restores no session has nothing to wait for. Without it, an
357
381
  * HTTP client bonded to that provider sends first-paint requests unauthenticated.
382
+ *
383
+ * A provider whose restore sends a request THROUGH the gated HTTP client must send that
384
+ * request with `skipAuthGate: true` (`RequestConfig` in `@molecule/app-http`): the gate
385
+ * waits on this promise, so holding the restore's own request makes the gate wait on
386
+ * itself and stalls every request it holds until it times out. `createJWTAuthClient`'s
387
+ * restore does not need it — it uses `fetch`, not the bonded client.
358
388
  */
359
389
  whenRestored?(): Promise<void>
360
390
 
@@ -437,10 +467,10 @@ interface AuthClientConfig {
437
467
 
438
468
  /**
439
469
  * Current-user endpoint for session restore (default `/users/me`). Called by
440
- * `initialize()` with credentials to re-establish the session from the
441
- * httpOnly cookie after a full page load — the only way to stay logged in when
442
- * the bearer token is held in memory (the secure default; a localStorage copy
443
- * is XSS-exfiltratable). Must return the user (as `user` or `props`).
470
+ * `initialize()` with credentials to re-establish the session after a full page
471
+ * load when the token did not survive the reload itself — i.e. when `storage` is
472
+ * `'memory'` and the API sets an httpOnly session cookie. Must return the user
473
+ * (as `user` or `props`).
444
474
  */
445
475
  currentUserEndpoint?: string
446
476
 
@@ -476,23 +506,36 @@ interface AuthClientConfig {
476
506
  mapAuthResponse?: (data: unknown) => AuthResult<UserProfile>
477
507
 
478
508
  /**
479
- * Token storage type or custom storage adapter.
480
- * - 'memory': In-memory storage (lost on page refresh)
481
- * - StorageAdapter: Custom storage implementation (e.g., from `@molecule/app-storage`)
509
+ * Where the access/refresh token and the cached user are kept — the field that
510
+ * decides whether a page reload keeps the user signed in.
511
+ *
512
+ * - `'memory'` (the client's default): a process-local store, lost on reload.
513
+ * Correct when the API sets an httpOnly session cookie, which `initialize()`
514
+ * then restores through {@link AuthClientConfig.currentUserEndpoint} — the
515
+ * strongest configuration, because no script can read the cookie.
516
+ * - a `StorageAdapter`: the token survives the reload itself. The browser
517
+ * adapter is `createBrowserStorageAdapter()` (from `@molecule/app-auth`), and
518
+ * the scaffold's generated auth bond (`src/bonds/auth-default.ts`) passes it;
519
+ * `src/config.ts` leaves `storage` out on purpose. A bearer token in Web
520
+ * Storage is readable by any script on the origin, so an XSS can steal it; see
521
+ * that function's `@remarks` for the trade and for the cookie alternative.
522
+ *
523
+ * Any adapter with `getItem`/`setItem`/`removeItem` works — the methods are
524
+ * SYNCHRONOUS, so the async `@molecule/app-storage` provider
525
+ * (`getProvider()`, whose `get()` returns a Promise) is NOT one: wrap the
526
+ * `Storage` object it was built on (`createBrowserStorageAdapter({ storage })`),
527
+ * or store a different way.
482
528
  *
483
529
  * @example
484
530
  * ```typescript
485
- * // Use in-memory storage
486
- * storage: 'memory'
531
+ * import { createBrowserStorageAdapter } from '@molecule/app-auth'
487
532
  *
488
- * // Use custom storage from `@molecule/app-storage`
489
- * import { getProvider } from '@molecule/app-storage'
490
- * const storageProvider = getProvider()
491
- * storage: {
492
- * getItem: (key) => storageProvider.get(key),
493
- * setItem: (key, value) => storageProvider.set(key, value),
494
- * removeItem: (key) => storageProvider.remove(key),
495
- * }
533
+ * // A reload keeps the session (the scaffold's own default):
534
+ * storage: createBrowserStorageAdapter()
535
+ * // Only this tab's lifetime, at a narrower exposure than localStorage:
536
+ * storage: createBrowserStorageAdapter({ kind: 'session' })
537
+ * // An httpOnly cookie session instead — memory only, the stronger route:
538
+ * storage: 'memory'
496
539
  * ```
497
540
  */
498
541
  storage?: 'memory' | StorageAdapter
@@ -568,6 +611,16 @@ interface TokenStorage {
568
611
 
569
612
  ### Types
570
613
 
614
+ #### `BrowserStorageKind`
615
+
616
+ Which Web Storage area {@link createBrowserStorageAdapter} persists to:
617
+ `'local'` is `window.localStorage` (survives a reload AND the tab closing),
618
+ `'session'` is `window.sessionStorage` (survives a reload, dies with the tab).
619
+
620
+ ```typescript
621
+ type BrowserStorageKind = 'local' | 'session'
622
+ ```
623
+
571
624
  #### `AuthEvent`
572
625
 
573
626
  Auth event types.
@@ -591,6 +644,41 @@ type AuthEventListener = (event: AuthEvent) => void
591
644
 
592
645
  ### Functions
593
646
 
647
+ #### `createBrowserStorageAdapter(options)`
648
+
649
+ The auth client's `StorageAdapter` over the browser's Web Storage.
650
+
651
+ Pass it as `AuthClientConfig.storage` to keep the session across a page reload:
652
+ the client's default (`'memory'`) is lost on reload, and re-establishing the
653
+ session then needs a credential that survived — this adapter, or an httpOnly
654
+ session cookie the API sets (see the security note below).
655
+
656
+ ```ts
657
+ import { createJWTAuthClient, createBrowserStorageAdapter } from '@molecule/app-auth'
658
+
659
+ const authClient = createJWTAuthClient({
660
+ baseURL: '/api',
661
+ storage: createBrowserStorageAdapter(), // a reload keeps the user signed in
662
+ })
663
+ ```
664
+
665
+ The scaffold's `authConfig` already passes it, so a scaffolded app survives a
666
+ reload out of the box; each of these replaces that default:
667
+
668
+ ```ts
669
+ storage: 'memory' // memory only: pair it with an httpOnly cookie session
670
+ storage: createBrowserStorageAdapter({ kind: 'session' }) // survives a reload, dies with the tab
671
+ storage: { getItem: (k) => …, setItem: (k, v) => …, removeItem: (k) => … } // your own
672
+ ```
673
+
674
+ ```typescript
675
+ function createBrowserStorageAdapter(options?: BrowserStorageAdapterOptions): StorageAdapter
676
+ ```
677
+
678
+ - `options` — Which Web Storage area to use, or a store to use directly.
679
+
680
+ **Returns:** A synchronous `StorageAdapter` bound to that store.
681
+
594
682
  #### `createJWTAuthClient(config)`
595
683
 
596
684
  Creates a simple JWT-based auth client.
@@ -643,7 +731,7 @@ Creates a token storage implementation backed by either in-memory
643
731
  storage or a custom `StorageAdapter`.
644
732
 
645
733
  ```typescript
646
- function createTokenStorage(storage?: 'memory' | StorageAdapter, prefix?: string): TokenStorage
734
+ function createTokenStorage(storage?: StorageAdapter | 'memory', prefix?: string): TokenStorage
647
735
  ```
648
736
 
649
737
  - `storage` — `'memory'` for in-memory storage (lost on refresh), or a `StorageAdapter` for persistent storage.
@@ -762,15 +850,23 @@ Peer dependencies:
762
850
  - **An API with its own auth envelope keeps this client.** `requestBody` wraps the
763
851
  login/register payload (`(kind, p) => ({ user: p })`), `mapAuthResponse` reads the
764
852
  token and user out of the answer (`(d) => ({ accessToken: d.user.token, user: d.user })`),
765
- and `authScheme: 'Token'` sends `Authorization: Token <jwt>`. Do not hand-write an
766
- auth client for a spec like RealWorld.
767
- - **A page reload "logging the user out" is the config default, not a bug.**
768
- Token storage defaults to `'memory'` (the secure default — a localStorage
769
- bearer token is XSS-exfiltratable). Staying signed in across reloads works
770
- by calling `client.initialize()` once at startup: it re-fetches
771
- `currentUserEndpoint` (default `/users/me`) with the httpOnly cookie the
772
- API set at login. Wire `initialize()`; do NOT "fix" reload-logout by
773
- copying tokens into localStorage.
853
+ and `authScheme: 'Token'` sends `Authorization: Token <jwt>` — both are fields of the
854
+ `AuthClientConfig` the client is CONSTRUCTED with
855
+ (`setClient(createJWTAuthClient({ authScheme: 'Token', … }))` in the auth bond), not
856
+ properties of a client that already exists. Do not hand-write an auth client for a spec
857
+ like RealWorld.
858
+ - **Whether a reload keeps the user signed in is `AuthClientConfig.storage`,
859
+ and one of the two routes must be wired.** The client's own default is
860
+ `'memory'`, which is lost on reload, so a session survives one only by
861
+ having a credential that survived: (1) `storage: createBrowserStorageAdapter()`
862
+ — the browser's `localStorage`, what a scaffolded app's `authConfig` passes
863
+ (see `@molecule/app-auth`'s `createBrowserStorageAdapter` for the trade: Web
864
+ Storage is script-readable, so an XSS can steal the token), or (2) an
865
+ httpOnly session cookie the API sets at login, which `initialize()` restores
866
+ through `currentUserEndpoint` (default `/users/me`) — the stronger option
867
+ wherever the API supports it, and what `@molecule/api-resource-user` issues.
868
+ Wire `initialize()` once at startup either way. Do NOT hand-roll a token
869
+ store beside the client for this: it is a config field.
774
870
  - **Endpoint defaults must match your API's real routes** (`/auth/login`,
775
871
  `/auth/register`, `/auth/refresh`, `/users/logout`, `/users/me`, …).
776
872
  Align them via `createJWTAuthClient({ baseURL, ...endpoints })` — never by
@@ -784,6 +880,13 @@ Peer dependencies:
784
880
  state being settled (`state.initialized`), or let the HTTP client do it — bond the
785
881
  auth client through `@molecule/app-bonds-default-react`, which registers
786
882
  `whenRestored()` as the http gate so every request waits for the restore.
883
+ - **Your own session store's gate must exempt its restore's own request.** This client
884
+ restores with `fetch`, so the gate registered over it never holds the restore. A store
885
+ that restores THROUGH the bonded HTTP client and registers that restore as the gate
886
+ (`setAuthGate(() => store.whenSettled())`) waits on itself unless the restore's request
887
+ passes `skipAuthGate: true` — otherwise the gate holds the very request it is waiting
888
+ for, and every request it holds stalls until the gate times out. See
889
+ `RequestConfig.skipAuthGate` in `@molecule/app-http`.
787
890
  - Client-side auth state is UX only — the server enforces authorization on
788
891
  every request; hiding a screen is not protection.
789
892
 
@@ -813,22 +916,27 @@ by one. A box you can't check is an integration bug to fix — not a skip:
813
916
  - [ ] Visiting a protected route while logged OUT redirects to login (the
814
917
  guard reads `isAuthenticated()`), and after authenticating you land back on
815
918
  the originally-requested screen rather than a generic home.
816
- - [ ] The session survives a FULL page reload: after login, hard-reload →
817
- `initialize()` restores it from the httpOnly cookie (via
818
- `currentUserEndpoint`, default `/users/me`) and you stay signed in — you are
819
- NOT bounced to login. (The in-memory bearer token is dropped by design; the
820
- cookie restore is what keeps you in — do not "fix" this by writing the token
821
- to localStorage.)
919
+ - [ ] The session survives a FULL page reload: after login, hard-reload → you
920
+ stay signed in (the profile/sign-out UI a signed-in visitor sees is still
921
+ there), and you are NOT bounced to login. Which route does it is the app's
922
+ `AuthClientConfig.storage`: the scaffold's `createBrowserStorageAdapter()` keeps
923
+ the token in the browser, an httpOnly session cookie is restored by
924
+ `initialize()` through `currentUserEndpoint` (default `/users/me`). If the
925
+ app has neither — `storage` left at `'memory'` against an API that sets no
926
+ cookie — this box cannot be checked, and the fix is the config, not a token
927
+ store written beside the client.
822
928
  - [ ] Password reset round-trips: `requestPasswordReset({ email })` then
823
929
  `confirmPasswordReset({ token, password })` with the emailed token, after
824
930
  which `login()` with the NEW password succeeds and the OLD password no
825
931
  longer works.
826
932
  - [ ] Authorization holds: a signed-in user only ever reads/edits their OWN
827
933
  record (`getUser()` is the caller's profile, never another user's); the
828
- bearer token lives in memory only — it is never written to
829
- localStorage / sessionStorage where another script could read it; and an
830
- expired/invalid token fails closed — the app re-authenticates (`refresh()`
831
- or `logout()`), never silently serving another user's data.
934
+ token's storage is the deliberate choice `AuthClientConfig.storage` names —
935
+ if it is Web Storage (the scaffold default, which a reload requires when the
936
+ API sets no cookie), say so in the app's own words rather than leaving a
937
+ second, undocumented store beside it; and an expired/invalid token fails
938
+ closed — the app re-authenticates (`refresh()` or `logout()`), never
939
+ silently serving another user's data.
832
940
 
833
941
  ## Translations
834
942
 
@@ -0,0 +1,89 @@
1
+ /**
2
+ * The browser `StorageAdapter` for the auth client's token storage.
3
+ *
4
+ * @module
5
+ */
6
+ import type { StorageAdapter } from './types.js';
7
+ /**
8
+ * Which Web Storage area {@link createBrowserStorageAdapter} persists to:
9
+ * `'local'` is `window.localStorage` (survives a reload AND the tab closing),
10
+ * `'session'` is `window.sessionStorage` (survives a reload, dies with the tab).
11
+ */
12
+ export type BrowserStorageKind = 'local' | 'session';
13
+ /** How {@link createBrowserStorageAdapter} picks the store it writes to. */
14
+ export interface BrowserStorageAdapterOptions {
15
+ /**
16
+ * The Web Storage area to persist to (default `'local'`).
17
+ *
18
+ * `'session'` is the narrower choice: a reload keeps the session, closing the
19
+ * tab ends it. Pick it when the app only has to survive navigations within one
20
+ * session — which is all a `page.reload()` asks for.
21
+ */
22
+ kind?: BrowserStorageKind;
23
+ /**
24
+ * A store to use instead of resolving `window.localStorage` /
25
+ * `window.sessionStorage` (a test double, a namespaced wrapper, or the
26
+ * `Storage` object another library exposes). Anything with `getItem`/
27
+ * `setItem`/`removeItem` does.
28
+ */
29
+ storage?: StorageAdapter;
30
+ }
31
+ /**
32
+ * The auth client's `StorageAdapter` over the browser's Web Storage.
33
+ *
34
+ * Pass it as `AuthClientConfig.storage` to keep the session across a page reload:
35
+ * the client's default (`'memory'`) is lost on reload, and re-establishing the
36
+ * session then needs a credential that survived — this adapter, or an httpOnly
37
+ * session cookie the API sets (see the security note below).
38
+ *
39
+ * ```ts
40
+ * import { createJWTAuthClient, createBrowserStorageAdapter } from '@molecule/app-auth'
41
+ *
42
+ * const authClient = createJWTAuthClient({
43
+ * baseURL: '/api',
44
+ * storage: createBrowserStorageAdapter(), // a reload keeps the user signed in
45
+ * })
46
+ * ```
47
+ *
48
+ * The scaffold's `authConfig` already passes it, so a scaffolded app survives a
49
+ * reload out of the box; each of these replaces that default:
50
+ *
51
+ * ```ts
52
+ * storage: 'memory' // memory only: pair it with an httpOnly cookie session
53
+ * storage: createBrowserStorageAdapter({ kind: 'session' }) // survives a reload, dies with the tab
54
+ * storage: { getItem: (k) => …, setItem: (k, v) => …, removeItem: (k) => … } // your own
55
+ * ```
56
+ *
57
+ * @remarks
58
+ * - **The trade, stated plainly.** A bearer token in Web Storage is readable by
59
+ * any script on the origin, so one XSS is one token theft — an account takeover
60
+ * for the token's whole lifetime, and `localStorage` keeps the copy after the
61
+ * tab closes. This is the model the RealWorld suite's own specs write
62
+ * (`localStorage.setItem('jwtToken', …)` before a reload) and the reason this
63
+ * adapter exists.
64
+ * - **An httpOnly cookie session is STRONGER, and is the first choice wherever
65
+ * your API supports it.** Script cannot read an httpOnly cookie, so an XSS
66
+ * cannot exfiltrate the credential; the token stays in memory and
67
+ * `initialize()` restores the session through `currentUserEndpoint`
68
+ * (`@molecule/api-resource-user` issues exactly this cookie — that is why the
69
+ * client's default is `'memory'`). If the API sets one, `storage: 'memory'` is
70
+ * the strongest configuration. If it does not and you cannot change it, keep
71
+ * the token's lifetime short and rotate it on refresh.
72
+ * - **`kind: 'session'` narrows the window** to the tab's lifetime at the cost of
73
+ * losing the session in a new tab; `'local'` is the default because a reload is
74
+ * the requirement it exists for, and a fresh tab is the same person.
75
+ * - **Unavailable storage degrades to memory; it never throws.** SSR (`window`
76
+ * undefined), a private/blocked store and a full quota all fall back to a
77
+ * process-local store — so a login still succeeds and the session simply does
78
+ * not survive the next page load. A warning names the failure. Do not read a
79
+ * successful `setItem` as a guarantee of persistence; a caller that needs one
80
+ * must probe the store itself.
81
+ * - **The keys are the client's own** (`storagePrefix`, default
82
+ * `molecule:auth:`, plus `accessToken` / `refreshToken` / `user`); this adapter
83
+ * adds no prefix and stores nothing of its own.
84
+ *
85
+ * @param options - Which Web Storage area to use, or a store to use directly.
86
+ * @returns A synchronous `StorageAdapter` bound to that store.
87
+ */
88
+ export declare const createBrowserStorageAdapter: (options?: BrowserStorageAdapterOptions) => StorageAdapter;
89
+ //# sourceMappingURL=browser-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-storage.d.ts","sourceRoot":"","sources":["../src/browser-storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,CAAA;AAEpD,4EAA4E;AAC5E,MAAM,WAAW,4BAA4B;IAC3C;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,eAAO,MAAM,2BAA2B,GACtC,UAAS,4BAAiC,KACzC,cA6EF,CAAA"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * The browser `StorageAdapter` for the auth client's token storage.
3
+ *
4
+ * @module
5
+ */
6
+ import { getLogger } from '@molecule/app-logger';
7
+ /** Best-effort logger: a missing logger bond must never break token storage. */
8
+ const warn = (message, error) => {
9
+ try {
10
+ const logger = getLogger('auth');
11
+ if (error === undefined)
12
+ logger.warn(message);
13
+ else
14
+ logger.warn(message, { error });
15
+ }
16
+ catch (_error) {
17
+ // No logger bonded (a bare unit test, an SSR boot before the app's bonds):
18
+ // logging is not this adapter's contract, and throwing here would take the
19
+ // session down with it.
20
+ }
21
+ };
22
+ /**
23
+ * The auth client's `StorageAdapter` over the browser's Web Storage.
24
+ *
25
+ * Pass it as `AuthClientConfig.storage` to keep the session across a page reload:
26
+ * the client's default (`'memory'`) is lost on reload, and re-establishing the
27
+ * session then needs a credential that survived — this adapter, or an httpOnly
28
+ * session cookie the API sets (see the security note below).
29
+ *
30
+ * ```ts
31
+ * import { createJWTAuthClient, createBrowserStorageAdapter } from '@molecule/app-auth'
32
+ *
33
+ * const authClient = createJWTAuthClient({
34
+ * baseURL: '/api',
35
+ * storage: createBrowserStorageAdapter(), // a reload keeps the user signed in
36
+ * })
37
+ * ```
38
+ *
39
+ * The scaffold's `authConfig` already passes it, so a scaffolded app survives a
40
+ * reload out of the box; each of these replaces that default:
41
+ *
42
+ * ```ts
43
+ * storage: 'memory' // memory only: pair it with an httpOnly cookie session
44
+ * storage: createBrowserStorageAdapter({ kind: 'session' }) // survives a reload, dies with the tab
45
+ * storage: { getItem: (k) => …, setItem: (k, v) => …, removeItem: (k) => … } // your own
46
+ * ```
47
+ *
48
+ * @remarks
49
+ * - **The trade, stated plainly.** A bearer token in Web Storage is readable by
50
+ * any script on the origin, so one XSS is one token theft — an account takeover
51
+ * for the token's whole lifetime, and `localStorage` keeps the copy after the
52
+ * tab closes. This is the model the RealWorld suite's own specs write
53
+ * (`localStorage.setItem('jwtToken', …)` before a reload) and the reason this
54
+ * adapter exists.
55
+ * - **An httpOnly cookie session is STRONGER, and is the first choice wherever
56
+ * your API supports it.** Script cannot read an httpOnly cookie, so an XSS
57
+ * cannot exfiltrate the credential; the token stays in memory and
58
+ * `initialize()` restores the session through `currentUserEndpoint`
59
+ * (`@molecule/api-resource-user` issues exactly this cookie — that is why the
60
+ * client's default is `'memory'`). If the API sets one, `storage: 'memory'` is
61
+ * the strongest configuration. If it does not and you cannot change it, keep
62
+ * the token's lifetime short and rotate it on refresh.
63
+ * - **`kind: 'session'` narrows the window** to the tab's lifetime at the cost of
64
+ * losing the session in a new tab; `'local'` is the default because a reload is
65
+ * the requirement it exists for, and a fresh tab is the same person.
66
+ * - **Unavailable storage degrades to memory; it never throws.** SSR (`window`
67
+ * undefined), a private/blocked store and a full quota all fall back to a
68
+ * process-local store — so a login still succeeds and the session simply does
69
+ * not survive the next page load. A warning names the failure. Do not read a
70
+ * successful `setItem` as a guarantee of persistence; a caller that needs one
71
+ * must probe the store itself.
72
+ * - **The keys are the client's own** (`storagePrefix`, default
73
+ * `molecule:auth:`, plus `accessToken` / `refreshToken` / `user`); this adapter
74
+ * adds no prefix and stores nothing of its own.
75
+ *
76
+ * @param options - Which Web Storage area to use, or a store to use directly.
77
+ * @returns A synchronous `StorageAdapter` bound to that store.
78
+ */
79
+ export const createBrowserStorageAdapter = (options = {}) => {
80
+ const { kind = 'local', storage } = options;
81
+ // The fallback store: one Map per adapter, so an unusable Web Storage area
82
+ // still behaves like a store for the lifetime of the page.
83
+ const memory = new Map();
84
+ /** The store once it has answered, `null` while it is unusable (re-probed each call). */
85
+ let resolved;
86
+ /** The unusable-store warning is worth saying once, not on every token read. */
87
+ let warned = false;
88
+ const resolve = () => {
89
+ if (storage)
90
+ return storage;
91
+ if (resolved !== undefined && resolved !== null)
92
+ return resolved;
93
+ try {
94
+ const areas = globalThis;
95
+ const web = kind === 'session' ? areas.sessionStorage : areas.localStorage;
96
+ if (web) {
97
+ // A store can be PRESENT and still unusable (a blocked third-party
98
+ // context, a private mode): touching it throws, so probe before trusting it.
99
+ const probe = '__molecule_auth_probe__';
100
+ web.setItem(probe, probe);
101
+ web.removeItem(probe);
102
+ resolved = web;
103
+ return web;
104
+ }
105
+ }
106
+ catch (error) {
107
+ if (!warned) {
108
+ warned = true;
109
+ warn(`The ${kind} Web Storage area is not usable; keeping auth tokens in memory`, error);
110
+ }
111
+ }
112
+ // Not cached: a store that appears later (the app booting before its DOM is
113
+ // ready) is still picked up by the next call.
114
+ return null;
115
+ };
116
+ return {
117
+ getItem: (key) => {
118
+ const store = resolve();
119
+ if (!store)
120
+ return memory.get(key) ?? null;
121
+ try {
122
+ // A write that fell back to memory (a full or blocked store) is still
123
+ // this session's value: the store simply never received it.
124
+ return store.getItem(key) ?? memory.get(key) ?? null;
125
+ }
126
+ catch (error) {
127
+ warn('Reading a stored auth value failed; falling back to memory', error);
128
+ return memory.get(key) ?? null;
129
+ }
130
+ },
131
+ setItem: (key, value) => {
132
+ const store = resolve();
133
+ if (!store) {
134
+ memory.set(key, value);
135
+ return;
136
+ }
137
+ try {
138
+ store.setItem(key, value);
139
+ memory.delete(key);
140
+ }
141
+ catch (error) {
142
+ // A quota-full or blocked store must not fail a login: keep the value for
143
+ // this page's lifetime and say so. The session is lost on reload, which is
144
+ // the state the app was in before this adapter existed.
145
+ warn('Storing an auth value failed; keeping it in memory for this page', error);
146
+ memory.set(key, value);
147
+ }
148
+ },
149
+ removeItem: (key) => {
150
+ memory.delete(key);
151
+ const store = resolve();
152
+ if (!store)
153
+ return;
154
+ try {
155
+ store.removeItem(key);
156
+ }
157
+ catch (error) {
158
+ warn('Clearing a stored auth value failed', error);
159
+ }
160
+ },
161
+ };
162
+ };
163
+ //# sourceMappingURL=browser-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-storage.js","sourceRoot":"","sources":["../src/browser-storage.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -12,15 +12,23 @@
12
12
  * - **An API with its own auth envelope keeps this client.** `requestBody` wraps the
13
13
  * login/register payload (`(kind, p) => ({ user: p })`), `mapAuthResponse` reads the
14
14
  * token and user out of the answer (`(d) => ({ accessToken: d.user.token, user: d.user })`),
15
- * and `authScheme: 'Token'` sends `Authorization: Token <jwt>`. Do not hand-write an
16
- * auth client for a spec like RealWorld.
17
- * - **A page reload "logging the user out" is the config default, not a bug.**
18
- * Token storage defaults to `'memory'` (the secure default — a localStorage
19
- * bearer token is XSS-exfiltratable). Staying signed in across reloads works
20
- * by calling `client.initialize()` once at startup: it re-fetches
21
- * `currentUserEndpoint` (default `/users/me`) with the httpOnly cookie the
22
- * API set at login. Wire `initialize()`; do NOT "fix" reload-logout by
23
- * copying tokens into localStorage.
15
+ * and `authScheme: 'Token'` sends `Authorization: Token <jwt>` — both are fields of the
16
+ * `AuthClientConfig` the client is CONSTRUCTED with
17
+ * (`setClient(createJWTAuthClient({ authScheme: 'Token', … }))` in the auth bond), not
18
+ * properties of a client that already exists. Do not hand-write an auth client for a spec
19
+ * like RealWorld.
20
+ * - **Whether a reload keeps the user signed in is `AuthClientConfig.storage`,
21
+ * and one of the two routes must be wired.** The client's own default is
22
+ * `'memory'`, which is lost on reload, so a session survives one only by
23
+ * having a credential that survived: (1) `storage: createBrowserStorageAdapter()`
24
+ * — the browser's `localStorage`, what a scaffolded app's `authConfig` passes
25
+ * (see `@molecule/app-auth`'s `createBrowserStorageAdapter` for the trade: Web
26
+ * Storage is script-readable, so an XSS can steal the token), or (2) an
27
+ * httpOnly session cookie the API sets at login, which `initialize()` restores
28
+ * through `currentUserEndpoint` (default `/users/me`) — the stronger option
29
+ * wherever the API supports it, and what `@molecule/api-resource-user` issues.
30
+ * Wire `initialize()` once at startup either way. Do NOT hand-roll a token
31
+ * store beside the client for this: it is a config field.
24
32
  * - **Endpoint defaults must match your API's real routes** (`/auth/login`,
25
33
  * `/auth/register`, `/auth/refresh`, `/users/logout`, `/users/me`, …).
26
34
  * Align them via `createJWTAuthClient({ baseURL, ...endpoints })` — never by
@@ -34,6 +42,13 @@
34
42
  * state being settled (`state.initialized`), or let the HTTP client do it — bond the
35
43
  * auth client through `@molecule/app-bonds-default-react`, which registers
36
44
  * `whenRestored()` as the http gate so every request waits for the restore.
45
+ * - **Your own session store's gate must exempt its restore's own request.** This client
46
+ * restores with `fetch`, so the gate registered over it never holds the restore. A store
47
+ * that restores THROUGH the bonded HTTP client and registers that restore as the gate
48
+ * (`setAuthGate(() => store.whenSettled())`) waits on itself unless the restore's request
49
+ * passes `skipAuthGate: true` — otherwise the gate holds the very request it is waiting
50
+ * for, and every request it holds stalls until the gate times out. See
51
+ * `RequestConfig.skipAuthGate` in `@molecule/app-http`.
37
52
  * - Client-side auth state is UX only — the server enforces authorization on
38
53
  * every request; hiding a screen is not protection.
39
54
  *
@@ -75,25 +90,31 @@
75
90
  * - [ ] Visiting a protected route while logged OUT redirects to login (the
76
91
  * guard reads `isAuthenticated()`), and after authenticating you land back on
77
92
  * the originally-requested screen rather than a generic home.
78
- * - [ ] The session survives a FULL page reload: after login, hard-reload →
79
- * `initialize()` restores it from the httpOnly cookie (via
80
- * `currentUserEndpoint`, default `/users/me`) and you stay signed in — you are
81
- * NOT bounced to login. (The in-memory bearer token is dropped by design; the
82
- * cookie restore is what keeps you in — do not "fix" this by writing the token
83
- * to localStorage.)
93
+ * - [ ] The session survives a FULL page reload: after login, hard-reload → you
94
+ * stay signed in (the profile/sign-out UI a signed-in visitor sees is still
95
+ * there), and you are NOT bounced to login. Which route does it is the app's
96
+ * `AuthClientConfig.storage`: the scaffold's `createBrowserStorageAdapter()` keeps
97
+ * the token in the browser, an httpOnly session cookie is restored by
98
+ * `initialize()` through `currentUserEndpoint` (default `/users/me`). If the
99
+ * app has neither — `storage` left at `'memory'` against an API that sets no
100
+ * cookie — this box cannot be checked, and the fix is the config, not a token
101
+ * store written beside the client.
84
102
  * - [ ] Password reset round-trips: `requestPasswordReset({ email })` then
85
103
  * `confirmPasswordReset({ token, password })` with the emailed token, after
86
104
  * which `login()` with the NEW password succeeds and the OLD password no
87
105
  * longer works.
88
106
  * - [ ] Authorization holds: a signed-in user only ever reads/edits their OWN
89
107
  * record (`getUser()` is the caller's profile, never another user's); the
90
- * bearer token lives in memory only — it is never written to
91
- * localStorage / sessionStorage where another script could read it; and an
92
- * expired/invalid token fails closed — the app re-authenticates (`refresh()`
93
- * or `logout()`), never silently serving another user's data.
108
+ * token's storage is the deliberate choice `AuthClientConfig.storage` names —
109
+ * if it is Web Storage (the scaffold default, which a reload requires when the
110
+ * API sets no cookie), say so in the app's own words rather than leaving a
111
+ * second, undocumented store beside it; and an expired/invalid token fails
112
+ * closed — the app re-authenticates (`refresh()` or `logout()`), never
113
+ * silently serving another user's data.
94
114
  *
95
115
  * @module
96
116
  */
117
+ export * from './browser-storage.js';
97
118
  export * from './client.js';
98
119
  export * from './provider.js';
99
120
  export * from './token.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AAEH,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmHG;AAEH,cAAc,sBAAsB,CAAA;AACpC,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
package/dist/index.js CHANGED
@@ -12,15 +12,23 @@
12
12
  * - **An API with its own auth envelope keeps this client.** `requestBody` wraps the
13
13
  * login/register payload (`(kind, p) => ({ user: p })`), `mapAuthResponse` reads the
14
14
  * token and user out of the answer (`(d) => ({ accessToken: d.user.token, user: d.user })`),
15
- * and `authScheme: 'Token'` sends `Authorization: Token <jwt>`. Do not hand-write an
16
- * auth client for a spec like RealWorld.
17
- * - **A page reload "logging the user out" is the config default, not a bug.**
18
- * Token storage defaults to `'memory'` (the secure default — a localStorage
19
- * bearer token is XSS-exfiltratable). Staying signed in across reloads works
20
- * by calling `client.initialize()` once at startup: it re-fetches
21
- * `currentUserEndpoint` (default `/users/me`) with the httpOnly cookie the
22
- * API set at login. Wire `initialize()`; do NOT "fix" reload-logout by
23
- * copying tokens into localStorage.
15
+ * and `authScheme: 'Token'` sends `Authorization: Token <jwt>` — both are fields of the
16
+ * `AuthClientConfig` the client is CONSTRUCTED with
17
+ * (`setClient(createJWTAuthClient({ authScheme: 'Token', … }))` in the auth bond), not
18
+ * properties of a client that already exists. Do not hand-write an auth client for a spec
19
+ * like RealWorld.
20
+ * - **Whether a reload keeps the user signed in is `AuthClientConfig.storage`,
21
+ * and one of the two routes must be wired.** The client's own default is
22
+ * `'memory'`, which is lost on reload, so a session survives one only by
23
+ * having a credential that survived: (1) `storage: createBrowserStorageAdapter()`
24
+ * — the browser's `localStorage`, what a scaffolded app's `authConfig` passes
25
+ * (see `@molecule/app-auth`'s `createBrowserStorageAdapter` for the trade: Web
26
+ * Storage is script-readable, so an XSS can steal the token), or (2) an
27
+ * httpOnly session cookie the API sets at login, which `initialize()` restores
28
+ * through `currentUserEndpoint` (default `/users/me`) — the stronger option
29
+ * wherever the API supports it, and what `@molecule/api-resource-user` issues.
30
+ * Wire `initialize()` once at startup either way. Do NOT hand-roll a token
31
+ * store beside the client for this: it is a config field.
24
32
  * - **Endpoint defaults must match your API's real routes** (`/auth/login`,
25
33
  * `/auth/register`, `/auth/refresh`, `/users/logout`, `/users/me`, …).
26
34
  * Align them via `createJWTAuthClient({ baseURL, ...endpoints })` — never by
@@ -34,6 +42,13 @@
34
42
  * state being settled (`state.initialized`), or let the HTTP client do it — bond the
35
43
  * auth client through `@molecule/app-bonds-default-react`, which registers
36
44
  * `whenRestored()` as the http gate so every request waits for the restore.
45
+ * - **Your own session store's gate must exempt its restore's own request.** This client
46
+ * restores with `fetch`, so the gate registered over it never holds the restore. A store
47
+ * that restores THROUGH the bonded HTTP client and registers that restore as the gate
48
+ * (`setAuthGate(() => store.whenSettled())`) waits on itself unless the restore's request
49
+ * passes `skipAuthGate: true` — otherwise the gate holds the very request it is waiting
50
+ * for, and every request it holds stalls until the gate times out. See
51
+ * `RequestConfig.skipAuthGate` in `@molecule/app-http`.
37
52
  * - Client-side auth state is UX only — the server enforces authorization on
38
53
  * every request; hiding a screen is not protection.
39
54
  *
@@ -75,25 +90,31 @@
75
90
  * - [ ] Visiting a protected route while logged OUT redirects to login (the
76
91
  * guard reads `isAuthenticated()`), and after authenticating you land back on
77
92
  * the originally-requested screen rather than a generic home.
78
- * - [ ] The session survives a FULL page reload: after login, hard-reload →
79
- * `initialize()` restores it from the httpOnly cookie (via
80
- * `currentUserEndpoint`, default `/users/me`) and you stay signed in — you are
81
- * NOT bounced to login. (The in-memory bearer token is dropped by design; the
82
- * cookie restore is what keeps you in — do not "fix" this by writing the token
83
- * to localStorage.)
93
+ * - [ ] The session survives a FULL page reload: after login, hard-reload → you
94
+ * stay signed in (the profile/sign-out UI a signed-in visitor sees is still
95
+ * there), and you are NOT bounced to login. Which route does it is the app's
96
+ * `AuthClientConfig.storage`: the scaffold's `createBrowserStorageAdapter()` keeps
97
+ * the token in the browser, an httpOnly session cookie is restored by
98
+ * `initialize()` through `currentUserEndpoint` (default `/users/me`). If the
99
+ * app has neither — `storage` left at `'memory'` against an API that sets no
100
+ * cookie — this box cannot be checked, and the fix is the config, not a token
101
+ * store written beside the client.
84
102
  * - [ ] Password reset round-trips: `requestPasswordReset({ email })` then
85
103
  * `confirmPasswordReset({ token, password })` with the emailed token, after
86
104
  * which `login()` with the NEW password succeeds and the OLD password no
87
105
  * longer works.
88
106
  * - [ ] Authorization holds: a signed-in user only ever reads/edits their OWN
89
107
  * record (`getUser()` is the caller's profile, never another user's); the
90
- * bearer token lives in memory only — it is never written to
91
- * localStorage / sessionStorage where another script could read it; and an
92
- * expired/invalid token fails closed — the app re-authenticates (`refresh()`
93
- * or `logout()`), never silently serving another user's data.
108
+ * token's storage is the deliberate choice `AuthClientConfig.storage` names —
109
+ * if it is Web Storage (the scaffold default, which a reload requires when the
110
+ * API sets no cookie), say so in the app's own words rather than leaving a
111
+ * second, undocumented store beside it; and an expired/invalid token fails
112
+ * closed — the app re-authenticates (`refresh()` or `logout()`), never
113
+ * silently serving another user's data.
94
114
  *
95
115
  * @module
96
116
  */
117
+ export * from './browser-storage.js';
97
118
  export * from './client.js';
98
119
  export * from './provider.js';
99
120
  export * from './token.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AAEH,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmHG;AAEH,cAAc,sBAAsB,CAAA;AACpC,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
package/dist/token.d.ts CHANGED
@@ -17,17 +17,12 @@ import type { StorageAdapter, TokenStorage } from './types.js';
17
17
  *
18
18
  * @example
19
19
  * ```typescript
20
- * // In-memory storage (default)
20
+ * // In-memory storage (the client's default)
21
21
  * const storage = createTokenStorage('memory')
22
22
  *
23
- * // Custom storage adapter from @molecule/app-storage
24
- * import { getProvider } from '@molecule/app-storage'
25
- * const provider = getProvider()
26
- * const storage = createTokenStorage({
27
- * getItem: (key) => provider.get(key),
28
- * setItem: (key, value) => provider.set(key, value),
29
- * removeItem: (key) => provider.remove(key),
30
- * })
23
+ * // The browser's persistent storage — a reload keeps the session
24
+ * import { createBrowserStorageAdapter } from '@molecule/app-auth'
25
+ * const storage = createTokenStorage(createBrowserStorageAdapter())
31
26
  * ```
32
27
  */
33
28
  export declare const createTokenStorage: (storage?: "memory" | StorageAdapter, prefix?: string) => TokenStorage;
@@ -1 +1 @@
1
- {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAe,MAAM,YAAY,CAAA;AAE3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAS,QAAQ,GAAG,cAAyB,EAC7C,SAAQ,MAAyB,KAChC,YAoDF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,MAAM,KAAG,CAAC,GAAG,IAWzE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,gBAAe,MAAU,KAAG,OAMzE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,KAAG,MAAM,GAAG,IAI3D,CAAA"}
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAe,MAAM,YAAY,CAAA;AAE3E;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAS,QAAQ,GAAG,cAAyB,EAC7C,SAAQ,MAAyB,KAChC,YAoDF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,MAAM,KAAG,CAAC,GAAG,IAWzE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,gBAAe,MAAU,KAAG,OAMzE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,KAAG,MAAM,GAAG,IAI3D,CAAA"}
package/dist/token.js CHANGED
@@ -16,17 +16,12 @@
16
16
  *
17
17
  * @example
18
18
  * ```typescript
19
- * // In-memory storage (default)
19
+ * // In-memory storage (the client's default)
20
20
  * const storage = createTokenStorage('memory')
21
21
  *
22
- * // Custom storage adapter from @molecule/app-storage
23
- * import { getProvider } from '@molecule/app-storage'
24
- * const provider = getProvider()
25
- * const storage = createTokenStorage({
26
- * getItem: (key) => provider.get(key),
27
- * setItem: (key, value) => provider.set(key, value),
28
- * removeItem: (key) => provider.remove(key),
29
- * })
22
+ * // The browser's persistent storage — a reload keeps the session
23
+ * import { createBrowserStorageAdapter } from '@molecule/app-auth'
24
+ * const storage = createTokenStorage(createBrowserStorageAdapter())
30
25
  * ```
31
26
  */
32
27
  export const createTokenStorage = (storage = 'memory', prefix = 'molecule:auth:') => {
package/dist/token.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,UAAqC,QAAQ,EAC7C,SAAiB,gBAAgB,EACnB,EAAE;IAChB,MAAM,WAAW,GAAkC,EAAE,CAAA;IAErD,4BAA4B;IAC5B,IAAI,OAAO,GAA0B,IAAI,CAAA;IACzC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,GAAG,OAAO,CAAA;IACnB,CAAC;IAED,MAAM,GAAG,GAAG,CAAC,GAAW,EAAiB,EAAE;QACzC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,IAAI,CAAA;IACjC,CAAC,CAAA;IAED,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,KAAoB,EAAQ,EAAE;QACtD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;YAClC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QAC1B,CAAC;IACH,CAAC,CAAA;IAED,OAAO;QACL,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC;QACxC,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC;QACpD,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1C,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC;QACtD,OAAO,EAAE,GAA8B,EAAE;YACvC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;YACxB,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAA;YACtB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAA;YAC9B,CAAC;YAAC,OAAO,MAAM,EAAE,CAAC;gBAChB,2EAA2E;gBAC3E,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAkB,IAAc,EAAE,EAAE;YAC3C,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACjD,CAAC;QACD,KAAK,EAAE,GAAG,EAAE;YACV,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;YACxB,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA;YACzB,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAA8B,KAAa,EAAY,EAAE;IAC/E,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;QACnE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAA;IACjC,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,sFAAsF;QACtF,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,gBAAwB,CAAC,EAAW,EAAE;IAClF,MAAM,OAAO,GAAG,QAAQ,CAAmB,KAAK,CAAC,CAAA;IACjD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAA;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,IAAI,CAAA;IAC7C,OAAO,GAAG,IAAI,SAAS,CAAA;AACzB,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAAiB,EAAE;IACjE,MAAM,OAAO,GAAG,QAAQ,CAAmB,KAAK,CAAC,CAAA;IACjD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACzC,OAAO,OAAO,CAAC,GAAG,GAAG,IAAI,CAAA;AAC3B,CAAC,CAAA"}
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -263,6 +263,12 @@ export interface AuthClient<T = UserProfile> {
263
263
  *
264
264
  * Optional: a provider that restores no session has nothing to wait for. Without it, an
265
265
  * HTTP client bonded to that provider sends first-paint requests unauthenticated.
266
+ *
267
+ * A provider whose restore sends a request THROUGH the gated HTTP client must send that
268
+ * request with `skipAuthGate: true` (`RequestConfig` in `@molecule/app-http`): the gate
269
+ * waits on this promise, so holding the restore's own request makes the gate wait on
270
+ * itself and stalls every request it holds until it times out. `createJWTAuthClient`'s
271
+ * restore does not need it — it uses `fetch`, not the bonded client.
266
272
  */
267
273
  whenRestored?(): Promise<void>;
268
274
  /**
@@ -326,10 +332,10 @@ export interface AuthClientConfig {
326
332
  profileEndpoint?: string;
327
333
  /**
328
334
  * Current-user endpoint for session restore (default `/users/me`). Called by
329
- * `initialize()` with credentials to re-establish the session from the
330
- * httpOnly cookie after a full page load — the only way to stay logged in when
331
- * the bearer token is held in memory (the secure default; a localStorage copy
332
- * is XSS-exfiltratable). Must return the user (as `user` or `props`).
335
+ * `initialize()` with credentials to re-establish the session after a full page
336
+ * load when the token did not survive the reload itself — i.e. when `storage` is
337
+ * `'memory'` and the API sets an httpOnly session cookie. Must return the user
338
+ * (as `user` or `props`).
333
339
  */
334
340
  currentUserEndpoint?: string;
335
341
  /**
@@ -360,23 +366,36 @@ export interface AuthClientConfig {
360
366
  */
361
367
  mapAuthResponse?: (data: unknown) => AuthResult<UserProfile>;
362
368
  /**
363
- * Token storage type or custom storage adapter.
364
- * - 'memory': In-memory storage (lost on page refresh)
365
- * - StorageAdapter: Custom storage implementation (e.g., from `@molecule/app-storage`)
369
+ * Where the access/refresh token and the cached user are kept — the field that
370
+ * decides whether a page reload keeps the user signed in.
371
+ *
372
+ * - `'memory'` (the client's default): a process-local store, lost on reload.
373
+ * Correct when the API sets an httpOnly session cookie, which `initialize()`
374
+ * then restores through {@link AuthClientConfig.currentUserEndpoint} — the
375
+ * strongest configuration, because no script can read the cookie.
376
+ * - a `StorageAdapter`: the token survives the reload itself. The browser
377
+ * adapter is `createBrowserStorageAdapter()` (from `@molecule/app-auth`), and
378
+ * the scaffold's generated auth bond (`src/bonds/auth-default.ts`) passes it;
379
+ * `src/config.ts` leaves `storage` out on purpose. A bearer token in Web
380
+ * Storage is readable by any script on the origin, so an XSS can steal it; see
381
+ * that function's `@remarks` for the trade and for the cookie alternative.
382
+ *
383
+ * Any adapter with `getItem`/`setItem`/`removeItem` works — the methods are
384
+ * SYNCHRONOUS, so the async `@molecule/app-storage` provider
385
+ * (`getProvider()`, whose `get()` returns a Promise) is NOT one: wrap the
386
+ * `Storage` object it was built on (`createBrowserStorageAdapter({ storage })`),
387
+ * or store a different way.
366
388
  *
367
389
  * @example
368
390
  * ```typescript
369
- * // Use in-memory storage
370
- * storage: 'memory'
391
+ * import { createBrowserStorageAdapter } from '@molecule/app-auth'
371
392
  *
372
- * // Use custom storage from `@molecule/app-storage`
373
- * import { getProvider } from '@molecule/app-storage'
374
- * const storageProvider = getProvider()
375
- * storage: {
376
- * getItem: (key) => storageProvider.get(key),
377
- * setItem: (key, value) => storageProvider.set(key, value),
378
- * removeItem: (key) => storageProvider.remove(key),
379
- * }
393
+ * // A reload keeps the session (the scaffold's own default):
394
+ * storage: createBrowserStorageAdapter()
395
+ * // Only this tab's lifetime, at a narrower exposure than localStorage:
396
+ * storage: createBrowserStorageAdapter({ kind: 'session' })
397
+ * // An httpOnly cookie session instead — memory only, the stronger route:
398
+ * storage: 'memory'
380
399
  * ```
381
400
  */
382
401
  storage?: 'memory' | StorageAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/app-auth",
3
- "version": "1.2.2",
3
+ "version": "1.3.1",
4
4
  "description": "Client-side authentication interface for molecule.dev",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",