@molecule/app-auth 1.0.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/LICENSE ADDED
@@ -0,0 +1,115 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work.
38
+
39
+ "Derivative Works" shall mean any work, whether in Source or Object
40
+ form, that is based on (or derived from) the Work and for which the
41
+ editorial revisions, annotations, elaborations, or other modifications
42
+ represent, as a whole, an original work of authorship.
43
+
44
+ "Contribution" shall mean any work of authorship, including the
45
+ original version of the Work and any modifications or additions
46
+ to that Work, that is intentionally submitted to the Licensor for
47
+ inclusion in the Work by the copyright owner or by an individual or
48
+ Legal Entity authorized to submit on behalf of the copyright owner.
49
+
50
+ "Contributor" shall mean Licensor and any individual or Legal Entity
51
+ on behalf of whom a Contribution has been received by the Licensor and
52
+ subsequently incorporated within the Work.
53
+
54
+ 2. Grant of Copyright License. Subject to the terms and conditions of
55
+ this License, each Contributor hereby grants to You a perpetual,
56
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
57
+ copyright license to reproduce, prepare Derivative Works of,
58
+ publicly display, publicly perform, sublicense, and distribute the
59
+ Work and such Derivative Works in Source or Object form.
60
+
61
+ 3. Grant of Patent License. Subject to the terms and conditions of
62
+ this License, each Contributor hereby grants to You a perpetual,
63
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
64
+ patent license to make, have made, use, offer to sell, sell, import,
65
+ and otherwise transfer the Work.
66
+
67
+ 4. Redistribution. You may reproduce and distribute copies of the
68
+ Work or Derivative Works thereof in any medium, with or without
69
+ modifications, and in Source or Object form, provided that You
70
+ meet the following conditions:
71
+
72
+ (a) You must give any other recipients of the Work or
73
+ Derivative Works a copy of this License; and
74
+
75
+ (b) You must cause any modified files to carry prominent notices
76
+ stating that You changed the files; and
77
+
78
+ (c) You must retain, in the Source form of any Derivative Works
79
+ that You distribute, all copyright, patent, trademark, and
80
+ attribution notices from the Source form of the Work,
81
+ excluding those notices that do not pertain to any part of
82
+ the Derivative Works; and
83
+
84
+ (d) If the Work includes a "NOTICE" text file as part of its
85
+ distribution, then any Derivative Works that You distribute must
86
+ include a readable copy of the attribution notices contained
87
+ within such NOTICE file.
88
+
89
+ 5. Submission of Contributions.
90
+
91
+ 6. Trademarks. This License does not grant permission to use the trade
92
+ names, trademarks, service marks, or product names of the Licensor.
93
+
94
+ 7. Disclaimer of Warranty. Unless required by applicable law or
95
+ agreed to in writing, Licensor provides the Work on an "AS IS" BASIS,
96
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
97
+
98
+ 8. Limitation of Liability. In no event and under no legal theory shall
99
+ any Contributor be liable to You for damages.
100
+
101
+ 9. Accepting Warranty or Additional Liability.
102
+
103
+ Copyright 2026 Molecule Dev, Inc.
104
+
105
+ Licensed under the Apache License, Version 2.0 (the "License");
106
+ you may not use this file except in compliance with the License.
107
+ You may obtain a copy of the License at
108
+
109
+ http://www.apache.org/licenses/LICENSE-2.0
110
+
111
+ Unless required by applicable law or agreed to in writing, software
112
+ distributed under the License is distributed on an "AS IS" BASIS,
113
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114
+ See the License for the specific language governing permissions and
115
+ limitations under the License.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Auth client creation and management.
3
+ *
4
+ * Provides the JWT-based auth client implementation.
5
+ *
6
+ * @module
7
+ */
8
+ import type { AuthClient, AuthClientConfig, UserProfile } from './types.js';
9
+ /**
10
+ * Creates a simple JWT-based auth client.
11
+ *
12
+ * This is a basic implementation that can be extended or replaced
13
+ * with more sophisticated auth providers.
14
+ *
15
+ * @param config - Auth client configuration including endpoints, storage, and refresh settings.
16
+ * @returns A fully configured `AuthClient` instance.
17
+ */
18
+ export declare const createJWTAuthClient: <T extends UserProfile = UserProfile>(config?: AuthClientConfig) => AuthClient<T>;
19
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAShB,WAAW,EACZ,MAAM,YAAY,CAAA;AA6BnB;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,WAAW,GAAG,WAAW,EACrE,SAAQ,gBAAqB,KAC5B,UAAU,CAAC,CAAC,CAmbd,CAAA"}
package/dist/client.js ADDED
@@ -0,0 +1,413 @@
1
+ /**
2
+ * Auth client creation and management.
3
+ *
4
+ * Provides the JWT-based auth client implementation.
5
+ *
6
+ * @module
7
+ */
8
+ import { I18nError } from '@molecule/app-i18n';
9
+ import { getLogger } from '@molecule/app-logger';
10
+ import { createTokenStorage, getTokenExpiration, isTokenExpired } from './token.js';
11
+ /**
12
+ * Whether this app is running inside a CROSS-SITE iframe — i.e. the molecule.dev
13
+ * live preview (the app at `127.0.0.1:<port>` embedded in the `localhost:3000`
14
+ * IDE). This mirrors the server's cross-site-preview decision (see
15
+ * `@molecule/api-resource-user` `getAuthCookieOptions`): in that case the server
16
+ * issues the `mol_auth` hint as `Secure; SameSite=None; Partitioned`, and a
17
+ * Partitioned cookie can only be deleted by a Set-Cookie / `document.cookie`
18
+ * write that ALSO carries Partitioned. A top-level document (the IDE itself, a
19
+ * normally-deployed app, or local `vite dev`) sets a plain `Lax` hint that the
20
+ * bare deletion already matches — so we must NOT append the cross-site attrs
21
+ * there (they would target the wrong cookie jar and miss the real cookie).
22
+ *
23
+ * Comparing `window.self !== window.top` is reference-only, so it never throws
24
+ * on a cross-origin embed.
25
+ *
26
+ * @returns `true` when embedded in a (cross-site) iframe, `false` at top level.
27
+ */
28
+ const isCrossSitePreviewFrame = () => {
29
+ try {
30
+ return typeof window !== 'undefined' && window.self !== window.top;
31
+ }
32
+ catch (_error) {
33
+ // A cross-origin frame can, in rare engines, throw on `window.top` access —
34
+ // if we can't tell, assume top-level (the safe default matching a Lax hint).
35
+ return false;
36
+ }
37
+ };
38
+ /**
39
+ * Creates a simple JWT-based auth client.
40
+ *
41
+ * This is a basic implementation that can be extended or replaced
42
+ * with more sophisticated auth providers.
43
+ *
44
+ * @param config - Auth client configuration including endpoints, storage, and refresh settings.
45
+ * @returns A fully configured `AuthClient` instance.
46
+ */
47
+ export const createJWTAuthClient = (config = {}) => {
48
+ const { baseURL = '', loginEndpoint = '/auth/login', logoutEndpoint = '/users/logout', registerEndpoint = '/auth/register', refreshEndpoint = '/auth/refresh', profileEndpoint = '/auth/profile', forgotPasswordEndpoint = '/auth/password/reset', resetPasswordEndpoint = '/auth/password/reset/confirm', changePasswordEndpoint = '/auth/password/change', currentUserEndpoint = '/users/me', storagePrefix = 'molecule:auth:', storage = 'memory', autoRefresh = true, refreshBuffer = 60, } = config;
49
+ const logger = getLogger('auth');
50
+ const tokenStorage = createTokenStorage(storage, storagePrefix);
51
+ const stateListeners = new Set();
52
+ const eventListeners = new Set();
53
+ let refreshTimer = null;
54
+ let state = {
55
+ initialized: false,
56
+ authenticated: false,
57
+ user: null,
58
+ loading: false,
59
+ error: null,
60
+ };
61
+ const notify = () => {
62
+ stateListeners.forEach((callback) => callback(state));
63
+ };
64
+ const emitEvent = (event) => {
65
+ eventListeners.forEach((listener) => listener(event));
66
+ };
67
+ const setState = (updates) => {
68
+ state = { ...state, ...updates };
69
+ notify();
70
+ };
71
+ const scheduleRefresh = () => {
72
+ if (!autoRefresh)
73
+ return;
74
+ const token = tokenStorage.getAccessToken();
75
+ if (!token)
76
+ return;
77
+ const expiresAt = getTokenExpiration(token);
78
+ if (!expiresAt)
79
+ return;
80
+ const refreshTime = expiresAt - refreshBuffer * 1000 - Date.now();
81
+ if (refreshTime <= 0)
82
+ return;
83
+ if (refreshTimer) {
84
+ clearTimeout(refreshTimer);
85
+ }
86
+ refreshTimer = setTimeout(() => {
87
+ client.refresh().catch((err) => {
88
+ logger.warn('Token refresh failed, logging out', err);
89
+ client.logout();
90
+ });
91
+ }, refreshTime);
92
+ };
93
+ const fetchAPI = async (endpoint, options = {}) => {
94
+ const url = baseURL + endpoint;
95
+ const headers = {
96
+ 'Content-Type': 'application/json',
97
+ ...options.headers,
98
+ };
99
+ const token = tokenStorage.getAccessToken();
100
+ if (token) {
101
+ headers['Authorization'] = `Bearer ${token}`;
102
+ }
103
+ // 'include' so httpOnly session cookies flow when the API is on another
104
+ // origin (fetch defaults to 'same-origin', which silently DROPS the login
105
+ // Set-Cookie cross-origin and breaks session restore). Safe both ways:
106
+ // same-origin behaves identically, and the fleet CORS bond pairs a strict
107
+ // origin allowlist with credentials:true. True cross-SITE deployments
108
+ // additionally need SameSite=None cookies — a server deployment concern.
109
+ const response = await fetch(url, {
110
+ credentials: 'include',
111
+ ...options,
112
+ headers,
113
+ });
114
+ if (!response.ok) {
115
+ const body = await response.json().catch(() => ({}));
116
+ const key = body.errorKey ?? 'auth.error.requestFailed';
117
+ const fallback = body.error ?? body.message ?? 'Request failed';
118
+ throw new I18nError(key, undefined, fallback);
119
+ }
120
+ const data = await response.json();
121
+ // Compatibility shim: many @molecule/api-resource-* handlers (notably
122
+ // the user resource) wrap the entity under `props` rather than `user`
123
+ // (the auth-client's expected shape). Surface either so login/register
124
+ // populate state correctly regardless of the API's wrapper convention.
125
+ if (data && typeof data === 'object' && data.user === undefined && data.props !== undefined) {
126
+ data.user = data.props;
127
+ }
128
+ return data;
129
+ };
130
+ // [M1-1] Session restore from the httpOnly cookie. The bearer token is held
131
+ // in memory (a localStorage copy is XSS-exfiltratable, so it is forbidden)
132
+ // and is therefore lost on a full page load — but the httpOnly session cookie
133
+ // persists. Probe the current-user endpoint with credentials; if the cookie
134
+ // is still valid the server returns the user, and we re-establish the
135
+ // authenticated session WITHOUT the token ever being exposed to JavaScript.
136
+ //
137
+ // GATE on the non-httpOnly `mol_auth` presence hint (set by the server
138
+ // alongside the httpOnly token): only probe when a session plausibly exists.
139
+ // Without this gate, every anonymous caller would fire a guaranteed-401
140
+ // request (extra API call + console error). A forged hint only costs one
141
+ // harmless 401.
142
+ //
143
+ // Shared by initialize() (reload/deep-link restore) and refresh() (see the
144
+ // no-refresh-token fallback there).
145
+ const restoreFromSessionCookie = async () => {
146
+ const hasSessionHint = typeof document !== 'undefined' && /(?:^|;\s*)mol_auth=1(?:;|$)/.test(document.cookie);
147
+ if (!hasSessionHint)
148
+ return null;
149
+ try {
150
+ const result = await fetchAPI(currentUserEndpoint, {
151
+ method: 'GET',
152
+ credentials: 'include',
153
+ });
154
+ const restoredUser = (result?.user ?? null);
155
+ if (restoredUser) {
156
+ tokenStorage.setUser(restoredUser);
157
+ setState({ authenticated: true, user: restoredUser });
158
+ return restoredUser;
159
+ }
160
+ }
161
+ catch (_error) {
162
+ // No valid session cookie (401) or no current-user endpoint — remain
163
+ // logged out. This is an expected path for anonymous visitors.
164
+ }
165
+ return null;
166
+ };
167
+ const client = {
168
+ getState: () => state,
169
+ isAuthenticated: () => state.authenticated,
170
+ getUser: () => state.user,
171
+ setUser: (user) => {
172
+ tokenStorage.setUser(user);
173
+ setState({ user });
174
+ },
175
+ getAccessToken: () => tokenStorage.getAccessToken(),
176
+ setAccessToken: (token) => {
177
+ tokenStorage.setAccessToken(token);
178
+ },
179
+ getRefreshToken: () => tokenStorage.getRefreshToken(),
180
+ async login(credentials) {
181
+ setState({ loading: true, error: null });
182
+ try {
183
+ const result = await fetchAPI(loginEndpoint, {
184
+ method: 'POST',
185
+ body: JSON.stringify(credentials),
186
+ });
187
+ // Two-factor gate: the server answered 206 `{ twoFactorRequired: true }`
188
+ // — no tokens/user issued. Surface the result WITHOUT marking the
189
+ // session authenticated; the caller re-prompts for the TOTP and retries.
190
+ if (result.twoFactorRequired) {
191
+ setState({ loading: false });
192
+ return result;
193
+ }
194
+ tokenStorage.setAccessToken(result.accessToken || null);
195
+ tokenStorage.setRefreshToken(result.refreshToken || null);
196
+ tokenStorage.setUser(result.user);
197
+ setState({
198
+ loading: false,
199
+ authenticated: true,
200
+ user: result.user,
201
+ });
202
+ logger.debug('User logged in');
203
+ emitEvent({ type: 'login', user: result.user });
204
+ scheduleRefresh();
205
+ return result;
206
+ }
207
+ catch (err) {
208
+ const error = err instanceof Error ? err.message : 'Login failed';
209
+ setState({ loading: false, error });
210
+ emitEvent({ type: 'error', error });
211
+ throw err;
212
+ }
213
+ },
214
+ async logout() {
215
+ setState({ loading: true });
216
+ try {
217
+ // [M1-1] The persistent credential is the httpOnly session cookie, not
218
+ // the in-memory bearer token. The bearer does not survive a page reload
219
+ // (after a reload `initialize()` restores `authenticated` from the cookie
220
+ // but cannot repopulate the in-memory token), so guarding the server
221
+ // logout on `token` alone meant a reloaded session could never log out
222
+ // server-side and the httpOnly cookie lived on. Call the endpoint
223
+ // whenever we believe a session exists — token OR restored-authenticated —
224
+ // and send `credentials` so the cookie authenticates the device
225
+ // revocation and the server clears the httpOnly cookie.
226
+ const token = tokenStorage.getAccessToken();
227
+ if (logoutEndpoint && (token || state.authenticated)) {
228
+ await fetchAPI(logoutEndpoint, { method: 'POST', credentials: 'include' }).catch((err) => {
229
+ logger.debug('Logout endpoint call failed (non-critical)', err);
230
+ });
231
+ }
232
+ }
233
+ finally {
234
+ if (refreshTimer) {
235
+ clearTimeout(refreshTimer);
236
+ refreshTimer = null;
237
+ }
238
+ tokenStorage.clear();
239
+ // [M1-1] Drop the non-httpOnly session-presence hint so initialize()
240
+ // won't probe for cookie-restore on the next load even if the server
241
+ // logout call didn't complete (the server clears it too, on success).
242
+ // The deletion must MATCH the attributes the server SET the hint with, or
243
+ // it targets the wrong cookie jar and the stale hint survives. Only the
244
+ // cross-site live-preview iframe issues `mol_auth` as `Secure;
245
+ // SameSite=None; Partitioned` (a Partitioned cookie can only be deleted by
246
+ // a write that ALSO carries Partitioned); a top-level document sets a plain
247
+ // `Lax` hint the bare deletion already matches.
248
+ if (typeof document !== 'undefined') {
249
+ const previewAttrs = isCrossSitePreviewFrame()
250
+ ? '; Secure; SameSite=None; Partitioned'
251
+ : '';
252
+ document.cookie = `mol_auth=; Max-Age=0; path=/${previewAttrs}`;
253
+ }
254
+ setState({
255
+ loading: false,
256
+ authenticated: false,
257
+ user: null,
258
+ });
259
+ logger.debug('User logged out');
260
+ emitEvent({ type: 'logout' });
261
+ }
262
+ },
263
+ async register(data) {
264
+ setState({ loading: true, error: null });
265
+ try {
266
+ const result = await fetchAPI(registerEndpoint, {
267
+ method: 'POST',
268
+ body: JSON.stringify(data),
269
+ });
270
+ tokenStorage.setAccessToken(result.accessToken || null);
271
+ tokenStorage.setRefreshToken(result.refreshToken || null);
272
+ tokenStorage.setUser(result.user);
273
+ setState({
274
+ loading: false,
275
+ authenticated: true,
276
+ user: result.user,
277
+ });
278
+ emitEvent({ type: 'register', user: result.user });
279
+ scheduleRefresh();
280
+ return result;
281
+ }
282
+ catch (err) {
283
+ const error = err instanceof Error ? err.message : 'Registration failed';
284
+ setState({ loading: false, error });
285
+ emitEvent({ type: 'error', error });
286
+ throw err;
287
+ }
288
+ },
289
+ async refresh() {
290
+ const refreshToken = tokenStorage.getRefreshToken();
291
+ if (!refreshToken) {
292
+ // Cookie-session APIs (the @molecule/api-resource-user model) issue NO
293
+ // refresh token at all — login/register return only { accessToken, user }
294
+ // and the durable credential is the httpOnly session cookie. For them,
295
+ // "refresh" means re-deriving the session from that cookie, exactly like
296
+ // initialize()'s restore. Without this fallback every post-auth refresh
297
+ // (the auth modal's finishAuth, the upgrade-tab focus-return) threw
298
+ // 'No refresh token available' — which silently aborted the modal's
299
+ // signup/login flow right after the account was created.
300
+ const restoredUser = await restoreFromSessionCookie();
301
+ if (restoredUser) {
302
+ emitEvent({ type: 'refresh' });
303
+ return { user: restoredUser };
304
+ }
305
+ throw new I18nError('auth.error.noRefreshToken', undefined, 'No refresh token available');
306
+ }
307
+ const result = await fetchAPI(refreshEndpoint, {
308
+ method: 'POST',
309
+ body: JSON.stringify({ refreshToken }),
310
+ });
311
+ tokenStorage.setAccessToken(result.accessToken || null);
312
+ if (result.refreshToken) {
313
+ tokenStorage.setRefreshToken(result.refreshToken);
314
+ }
315
+ tokenStorage.setUser(result.user);
316
+ setState({
317
+ authenticated: true,
318
+ user: result.user,
319
+ });
320
+ emitEvent({ type: 'refresh' });
321
+ scheduleRefresh();
322
+ return result;
323
+ },
324
+ async requestPasswordReset(data) {
325
+ await fetchAPI(forgotPasswordEndpoint, {
326
+ method: 'POST',
327
+ body: JSON.stringify(data),
328
+ });
329
+ },
330
+ async confirmPasswordReset(data) {
331
+ await fetchAPI(resetPasswordEndpoint, {
332
+ method: 'POST',
333
+ body: JSON.stringify(data),
334
+ });
335
+ },
336
+ async updateProfile(data) {
337
+ const result = await fetchAPI(profileEndpoint, {
338
+ method: 'PATCH',
339
+ body: JSON.stringify(data),
340
+ });
341
+ tokenStorage.setUser(result);
342
+ setState({ user: result });
343
+ return result;
344
+ },
345
+ async changePassword(oldPassword, newPassword) {
346
+ // Server handler (@molecule/api-resource-user `updatePassword`)
347
+ // reads `currentPassword`; legacy callers passed `oldPassword`,
348
+ // so accept either name in the hook signature but translate to
349
+ // the canonical `currentPassword` field when sending.
350
+ await fetchAPI(changePasswordEndpoint, {
351
+ method: 'POST',
352
+ body: JSON.stringify({ currentPassword: oldPassword, newPassword }),
353
+ });
354
+ },
355
+ async initialize() {
356
+ const token = tokenStorage.getAccessToken();
357
+ const user = tokenStorage.getUser();
358
+ if (token && user) {
359
+ if (!isTokenExpired(token)) {
360
+ setState({
361
+ initialized: true,
362
+ authenticated: true,
363
+ user,
364
+ });
365
+ scheduleRefresh();
366
+ return;
367
+ }
368
+ // Token expired, try to refresh
369
+ const refreshToken = tokenStorage.getRefreshToken();
370
+ if (refreshToken) {
371
+ try {
372
+ await this.refresh();
373
+ setState({ initialized: true });
374
+ return;
375
+ }
376
+ catch (err) {
377
+ logger.warn('Initial token refresh failed', err);
378
+ tokenStorage.clear();
379
+ }
380
+ }
381
+ }
382
+ // [M1-1] Cookie-restore — this is what keeps a refresh / deep-link logged
383
+ // in under the in-memory-token model. See restoreFromSessionCookie above.
384
+ await restoreFromSessionCookie();
385
+ setState({ initialized: true });
386
+ },
387
+ subscribe(callback) {
388
+ stateListeners.add(callback);
389
+ return () => stateListeners.delete(callback);
390
+ },
391
+ onAuthChange(callback) {
392
+ stateListeners.add(callback);
393
+ return () => stateListeners.delete(callback);
394
+ },
395
+ getToken() {
396
+ return tokenStorage.getAccessToken();
397
+ },
398
+ addEventListener(listener) {
399
+ eventListeners.add(listener);
400
+ return () => eventListeners.delete(listener);
401
+ },
402
+ destroy() {
403
+ if (refreshTimer) {
404
+ clearTimeout(refreshTimer);
405
+ refreshTimer = null;
406
+ }
407
+ stateListeners.clear();
408
+ eventListeners.clear();
409
+ },
410
+ };
411
+ return client;
412
+ };
413
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Client-side authentication interface for molecule.dev.
3
+ *
4
+ * Provides a unified auth API that works across different auth strategies
5
+ * (JWT, session, OAuth, etc.): `createJWTAuthClient` builds a fetch-based
6
+ * client; `setClient`/`getClient` bond it; `login`/`logout`/`register`/
7
+ * `isAuthenticated`/`getUser` delegate to the bonded client. Framework
8
+ * bindings (e.g. `AuthProvider`/`useAuth` in `@molecule/app-react`) wrap the
9
+ * same client.
10
+ *
11
+ * @remarks
12
+ * - **A page reload "logging the user out" is the config default, not a bug.**
13
+ * Token storage defaults to `'memory'` (the secure default — a localStorage
14
+ * bearer token is XSS-exfiltratable). Staying signed in across reloads works
15
+ * by calling `client.initialize()` once at startup: it re-fetches
16
+ * `currentUserEndpoint` (default `/users/me`) with the httpOnly cookie the
17
+ * API set at login. Wire `initialize()`; do NOT "fix" reload-logout by
18
+ * copying tokens into localStorage.
19
+ * - **Endpoint defaults must match your API's real routes** (`/auth/login`,
20
+ * `/auth/register`, `/auth/refresh`, `/users/logout`, `/users/me`, …).
21
+ * Align them via `createJWTAuthClient({ baseURL, ...endpoints })` — never by
22
+ * hand-editing fetch calls in components.
23
+ * - Client-side auth state is UX only — the server enforces authorization on
24
+ * every request; hiding a screen is not protection.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * import { createJWTAuthClient, setClient } from '@molecule/app-auth'
29
+ *
30
+ * const client = createJWTAuthClient({ baseURL: '/api' })
31
+ * setClient(client)
32
+ * await client.initialize() // restore the session from the httpOnly cookie
33
+ *
34
+ * // anywhere in the app
35
+ * import { getUser, isAuthenticated, login, logout } from '@molecule/app-auth'
36
+ * await login({ email, password })
37
+ * if (isAuthenticated()) console.log(getUser()?.email)
38
+ * ```
39
+ *
40
+ * @e2e
41
+ * Integration checklist — drive the real UI (live preview, no mocks), adapt
42
+ * each item to this app's actual screens/flows, and check every box off one
43
+ * by one. A box you can't check is an integration bug to fix — not a skip:
44
+ * - [ ] Logging in with VALID credentials on the real login screen resolves
45
+ * `login()` and flips AuthState to `authenticated: true` with `getUser()`
46
+ * returning the actual UserProfile — the UI shows that user's own `email` /
47
+ * `name` / `avatar`, never a placeholder or a different account.
48
+ * - [ ] A WRONG password shows a visible error (AuthState `error` is set and
49
+ * the promise rejects) and establishes NO session: `isAuthenticated()` stays
50
+ * false and no protected screen becomes reachable.
51
+ * - [ ] Registering through the sign-up form calls `register()`, creates the
52
+ * account, and lands authenticated (`authenticated: true`, `user` populated)
53
+ * on the app's post-signup screen — not back on the login form. If the flow
54
+ * shows an email-verification / "check your inbox" step, it must be genuinely
55
+ * backed (this client's `register()` returns an authenticated session
56
+ * directly and exposes no verify method) — never a dead screen the auth
57
+ * contract cannot advance past.
58
+ * - [ ] Logout calls `logout()` and clears the session (`authenticated: false`,
59
+ * `user: null`, tokens cleared); afterward every protected screen redirects
60
+ * back to login.
61
+ * - [ ] Visiting a protected route while logged OUT redirects to login (the
62
+ * guard reads `isAuthenticated()`), and after authenticating you land back on
63
+ * the originally-requested screen rather than a generic home.
64
+ * - [ ] The session survives a FULL page reload: after login, hard-reload →
65
+ * `initialize()` restores it from the httpOnly cookie (via
66
+ * `currentUserEndpoint`, default `/users/me`) and you stay signed in — you are
67
+ * NOT bounced to login. (The in-memory bearer token is dropped by design; the
68
+ * cookie restore is what keeps you in — do not "fix" this by writing the token
69
+ * to localStorage.)
70
+ * - [ ] Password reset round-trips: `requestPasswordReset({ email })` then
71
+ * `confirmPasswordReset({ token, password })` with the emailed token, after
72
+ * which `login()` with the NEW password succeeds and the OLD password no
73
+ * longer works.
74
+ * - [ ] Authorization holds: a signed-in user only ever reads/edits their OWN
75
+ * record (`getUser()` is the caller's profile, never another user's); the
76
+ * bearer token lives in memory only — it is never written to
77
+ * localStorage / sessionStorage where another script could read it; and an
78
+ * expired/invalid token fails closed — the app re-authenticates (`refresh()`
79
+ * or `logout()`), never silently serving another user's data.
80
+ *
81
+ * @module
82
+ */
83
+ export * from './client.js';
84
+ export * from './provider.js';
85
+ export * from './token.js';
86
+ export * from './types.js';
87
+ export * from './utilities.js';
88
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiFG;AAEH,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}