@myrjfa/state 3.0.9 → 3.0.10

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.
@@ -1,3 +1,4 @@
1
+ import { User } from "../models/user";
1
2
  import type { AuthenticationAccountType, RegisterPayload, RecoveryDevice } from "../models/authentication";
2
3
  import type { SessionIdentity } from "../authSessionPolicy";
3
4
  export declare function signIn(formData: {
@@ -298,6 +299,7 @@ export declare function resetPassword(password: string, token: string, role: str
298
299
  export declare function validateSession(): Promise<{
299
300
  success: boolean;
300
301
  identity?: SessionIdentity;
302
+ user?: User;
301
303
  message?: string;
302
304
  error?: string;
303
305
  statusCode?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/lib/actions/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/lib/actions/auth.ts"],"names":[],"mappings":"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"}
@@ -180,8 +180,17 @@ export async function resetPassword(password, token, role) {
180
180
  export async function validateSession() {
181
181
  try {
182
182
  const data = await get("/auth/session");
183
+ if (!getNativeTransport() && typeof window !== "undefined" && typeof localStorage !== "undefined" && data.data.deviceId) {
184
+ // Browser cache is optional; a denied/quota-limited write must not
185
+ // turn successful cookie authentication into a failed session.
186
+ try {
187
+ localStorage.setItem("_trippeaze_device_id", data.data.deviceId);
188
+ }
189
+ catch { /* The scoped device cookie remains canonical. */ }
190
+ }
183
191
  return {
184
192
  success: true,
193
+ user: data.data.user,
185
194
  identity: data.data,
186
195
  message: data.message
187
196
  };
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../../src/lib/actions/fetcher.ts"],"names":[],"mappings":"AA0BA,UAAU,YAAY;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAuCD;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAYnD;AAoLD,wBAAsB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,GAAE,OAAc,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAM,cAEhH;AAED,wBAAsB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,GAAE,OAAc,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,kBAAkB,CAAM,cAErL;AAED,wBAAsB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAM,cAExG;AAED,wBAAsB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAM,cAE1G;AAED,wBAAsB,GAAG,CAAC,CAAC,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,WAAW,GAAE,OAAc,EAC3B,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAM,cAGnE"}
1
+ {"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../../src/lib/actions/fetcher.ts"],"names":[],"mappings":"AA0BA,UAAU,YAAY;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAuCD;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAYnD;AAwJD,wBAAsB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,GAAE,OAAc,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAM,cAEhH;AAED,wBAAsB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,GAAE,OAAc,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,GAAG,kBAAkB,CAAM,cAErL;AAED,wBAAsB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAM,cAExG;AAED,wBAAsB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAM,cAE1G;AAED,wBAAsB,GAAG,CAAC,CAAC,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,WAAW,GAAE,OAAc,EAC3B,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAM,cAGnE"}
@@ -1,4 +1,4 @@
1
- import { getAccountType, getCookieHeader, getRole } from "./serverActions";
1
+ import { getCookieHeader } from "./serverActions";
2
2
  import { normalizeRefreshFailureStatus } from "../authSessionPolicy";
3
3
  import { acceptNativeSession, getNativeTransport, nativeSessionGeneration } from "./nativeTransport";
4
4
  // Custom API error class — do NOT import from next/dist internals
@@ -175,61 +175,36 @@ async function refreshToken(input, method, body, options = {}) {
175
175
  throw new ApiError(401, 'Session changed');
176
176
  return customFetch(input, method, body, { ...options, includeAuth: true, retry: false });
177
177
  }
178
- let refreshEndpoint = "/auth/session/refresh";
179
- if (typeof window === "undefined") {
180
- const accountType = await getAccountType();
181
- const legacyRole = accountType ? null : await getRole();
182
- refreshEndpoint = accountType === "staff"
183
- ? "/auth/staff/refresh-token"
184
- : accountType === "host" || legacyRole === "host"
185
- ? "/hosts/refresh-token"
186
- : "/users/refresh-token";
187
- }
188
- // Deduplicate: if a refresh is already in flight, wait for it rather than firing a second one
189
- if (!refreshPromise) {
190
- refreshPromise = (async () => {
191
- const refreshHeaders = {};
192
- // Always include device ID so backend can match the device record
193
- const deviceId = getOrCreateDeviceId();
194
- if (deviceId)
195
- refreshHeaders['X-Device-Id'] = deviceId;
196
- try {
197
- const cookieHeader = await getCookieHeader();
198
- if (cookieHeader)
199
- refreshHeaders['Cookie'] = cookieHeader;
200
- }
201
- catch {
202
- // CSR or static context — credentials:'include' handles cookie forwarding to backend
203
- }
204
- const response = await fetch(`${baseURL}${refreshEndpoint}`, {
205
- method: 'POST',
206
- credentials: 'include',
207
- headers: refreshHeaders,
208
- });
209
- if (!response.ok) {
210
- const data = await response.json();
211
- // A rejected refresh means this browser no longer has a usable
212
- // session, regardless of whether validation/auth middleware
213
- // returned 400, 401, 403, or 422. Normalize client-side refresh
214
- // failures to 401 so expected signed-out initialization stays
215
- // quiet instead of surfacing as a Next.js error overlay.
216
- const statusCode = normalizeRefreshFailureStatus(response.status);
217
- throw { statusCode, error: data.error || data.message || 'Session expired' };
218
- }
219
- })().finally(() => { refreshPromise = null; });
220
- }
221
- try {
222
- await refreshPromise;
223
- return customFetch(input, method, body, { ...options, includeAuth: true, retry: false });
224
- }
225
- catch (error) {
226
- if (error?.name === 'AbortError')
227
- throw error;
228
- if (error && typeof error === 'object' && ('$$typeof' in error || error.digest === 'DYNAMIC_SERVER_USAGE')) {
229
- throw error; // Re-throw Next.js PPR bail-out
178
+ // Rendering cannot reliably deliver Set-Cookie. Browser bootstrap owns
179
+ // rotation; server requests must never consume its refresh credential.
180
+ if (typeof window === "undefined")
181
+ throw new ApiError(401, 'Browser session requires client refresh');
182
+ const refresh = async () => {
183
+ const deviceId = getOrCreateDeviceId();
184
+ const response = await fetch(`${baseURL}/auth/session/refresh`, {
185
+ // Rotation consumes the old credential. Let the browser receive
186
+ // replacement cookies even if this document navigates away.
187
+ method: 'POST', credentials: 'include', keepalive: true,
188
+ headers: deviceId ? { 'X-Device-Id': deviceId } : {},
189
+ });
190
+ if (!response.ok) {
191
+ const data = await response.json();
192
+ throw new ApiError(normalizeRefreshFailureStatus(response.status), data.error || data.message || 'Session expired');
230
193
  }
231
- throw new ApiError(error.statusCode ?? 500, error.error || error.message || 'Session expired. Please log in again.');
194
+ };
195
+ if (!refreshPromise) {
196
+ const locks = typeof navigator !== 'undefined' ? navigator.locks : undefined;
197
+ refreshPromise = (locks ? locks.request(`trippeaze-refresh:${baseURL}`, async () => {
198
+ const probe = await fetch(`${baseURL}/auth/session`, { credentials: 'include' });
199
+ if (probe.ok)
200
+ return;
201
+ if (probe.status !== 401)
202
+ throw new ApiError(probe.status, 'Session validation temporarily unavailable');
203
+ await refresh();
204
+ }) : refresh()).finally(() => { refreshPromise = null; });
232
205
  }
206
+ await refreshPromise;
207
+ return customFetch(input, method, body, { ...options, includeAuth: true, retry: false });
233
208
  }
234
209
  // ✅ Server-safe exported functions
235
210
  export async function get(url, includeAuth = true, options = {}) {
@@ -1 +1 @@
1
- {"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/lib/actions/serverActions.ts"],"names":[],"mappings":"AAKA,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAKvD;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWtD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAahF"}
1
+ {"version":3,"file":"serverActions.d.ts","sourceRoot":"","sources":["../../../src/lib/actions/serverActions.ts"],"names":[],"mappings":"AAMA,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAKvD;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWtD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAahF"}
@@ -1,4 +1,5 @@
1
1
  'use server';
2
+ import { authCookieName } from '../utils/authCookies';
2
3
  import { cookies } from 'next/headers';
3
4
  import { validRoles } from '../utils/text';
4
5
  export async function getCookieHeader() {
@@ -9,7 +10,7 @@ export async function getCookieHeader() {
9
10
  }
10
11
  export async function getRole() {
11
12
  try {
12
- const role = (await cookies()).get("role")?.value ?? null;
13
+ const role = (await cookies()).get(authCookieName("role"))?.value ?? null;
13
14
  return (role && validRoles.includes(role)) ? role : null;
14
15
  }
15
16
  catch (err) {
@@ -22,7 +23,7 @@ export async function getRole() {
22
23
  }
23
24
  export async function getAccountType() {
24
25
  try {
25
- const accountType = (await cookies()).get("accountType")?.value;
26
+ const accountType = (await cookies()).get(authCookieName("accountType"))?.value;
26
27
  return accountType === "user" || accountType === "host" || accountType === "staff"
27
28
  ? accountType
28
29
  : null;
@@ -1 +1 @@
1
- {"version":3,"file":"authSessionManager.d.ts","sourceRoot":"","sources":["../../src/lib/authSessionManager.tsx"],"names":[],"mappings":"AAuBA,MAAM,CAAC,OAAO,UAAU,kBAAkB,SA2GzC"}
1
+ {"version":3,"file":"authSessionManager.d.ts","sourceRoot":"","sources":["../../src/lib/authSessionManager.tsx"],"names":[],"mappings":"AAuBA,MAAM,CAAC,OAAO,UAAU,kBAAkB,SAiGzC"}
@@ -1,14 +1,16 @@
1
1
  'use client';
2
2
  import { useAtomValue, useSetAtom } from "jotai";
3
3
  import { useEffect } from 'react';
4
- import { useQuery } from '@tanstack/react-query';
5
- import { authRevisionAtom, authSessionStatusAtom, beginAuthCleanupAtom, finishAuthCleanupAtom, initializeAuthSessionAtom, isLoggedInAtom, storageInitializedAtom, userAtom, } from "./userAtom";
6
- import { clearSessionCookies, validateSession } from './actions/auth';
4
+ import { useQuery, useQueryClient } from '@tanstack/react-query';
5
+ import { authRevisionAtom, commitLoginAtom, resetAuthStateAtom, authSessionStatusAtom, initializeAuthSessionAtom, isLoggedInAtom, storageInitializedAtom, userAtom, } from "./userAtom";
6
+ import { validateSession } from './actions/auth';
7
7
  import { bindSessionFailureToRevision, sessionIdentityMatchesPersistedUser, shouldResetAuthStateForQuery, } from './authSessionPolicy';
8
8
  export default function AuthSessionManager() {
9
+ const queryClient = useQueryClient();
10
+ const commitLogin = useSetAtom(commitLoginAtom);
11
+ const updateUser = useSetAtom(userAtom);
12
+ const resetLocal = useSetAtom(resetAuthStateAtom);
9
13
  const initializeAuthSession = useSetAtom(initializeAuthSessionAtom);
10
- const beginAuthCleanup = useSetAtom(beginAuthCleanupAtom);
11
- const finishAuthCleanup = useSetAtom(finishAuthCleanupAtom);
12
14
  const setAuthSessionStatus = useSetAtom(authSessionStatusAtom);
13
15
  const authRevision = useAtomValue(authRevisionAtom);
14
16
  const user = useAtomValue(userAtom);
@@ -24,6 +26,16 @@ export default function AuthSessionManager() {
24
26
  });
25
27
  return () => window.cancelAnimationFrame(frame);
26
28
  }, [initializeAuthSession]);
29
+ useEffect(() => {
30
+ const reconcile = (event) => {
31
+ if (event.key === process.env.NEXT_PUBLIC_USER_KEY || event.key === process.env.NEXT_PUBLIC_LOGIN_KEY) {
32
+ setAuthSessionStatus("validating");
33
+ void queryClient.invalidateQueries({ queryKey: ["session"] });
34
+ }
35
+ };
36
+ window.addEventListener("storage", reconcile);
37
+ return () => window.removeEventListener("storage", reconcile);
38
+ }, [queryClient, setAuthSessionStatus]);
27
39
  // --- Continuous Background Re-validation ---
28
40
  const { data: sessionResult, error, } = useQuery({
29
41
  queryKey: ["session", authRevision],
@@ -38,62 +50,53 @@ export default function AuthSessionManager() {
38
50
  throw bindSessionFailureToRevision(queryError, authRevision);
39
51
  }
40
52
  },
41
- refetchOnWindowFocus: true,
42
- refetchOnReconnect: true,
53
+ refetchOnWindowFocus: "always",
54
+ refetchOnReconnect: "always",
43
55
  retry: (failureCount, err) => {
44
56
  if (err?.statusCode === 401)
45
57
  return false;
46
58
  return failureCount < 2;
47
59
  },
48
60
  staleTime: 15 * 60 * 1000,
49
- enabled: storageInitialized && Boolean(isLoggedIn && user),
61
+ enabled: storageInitialized,
50
62
  });
51
63
  // Clear auth state only when the backend explicitly says the session is invalid (401).
52
64
  // Network errors or 5xx (backend down) are ignored to avoid false logouts.
53
65
  useEffect(() => {
54
- // A signed-out browser does not need to be reset repeatedly.
55
- if (!isLoggedIn && !user)
66
+ if (!storageInitialized)
56
67
  return;
57
- const shouldClearRejectedOrInvalidSession = shouldResetAuthStateForQuery({
58
- session: sessionResult?.session,
59
- sessionRevision: sessionResult?.revision,
60
- error: error,
61
- currentRevision: authRevision,
62
- });
63
- const currentSuccessfulResult = sessionResult?.revision === authRevision
64
- ? sessionResult
65
- : null;
66
- if (shouldClearRejectedOrInvalidSession || (currentSuccessfulResult
67
- && !sessionIdentityMatchesPersistedUser(currentSuccessfulResult.session.identity, user))) {
68
- // Keep auth controls non-interactive until the Set-Cookie cleanup
69
- // response settles; otherwise a delayed response can erase a new
70
- // login performed while cleanup is still in flight.
71
- beginAuthCleanup();
72
- const cleanupRevision = authRevision + 1;
73
- void (async () => {
74
- try {
75
- await clearSessionCookies();
76
- }
77
- finally {
78
- finishAuthCleanup(cleanupRevision);
79
- }
80
- })();
68
+ const current = sessionResult?.revision === authRevision ? sessionResult.session : null;
69
+ const rejected = shouldResetAuthStateForQuery({ session: current, sessionRevision: sessionResult?.revision, error: error, currentRevision: authRevision });
70
+ if (rejected) {
71
+ if (isLoggedIn || user)
72
+ resetLocal();
73
+ else
74
+ setAuthSessionStatus("signed-out");
81
75
  return;
82
76
  }
83
- // A retryable network/server failure has no authoritative session
84
- // result. Keep the provisional identity validating until a later retry.
85
- if (!currentSuccessfulResult)
77
+ if (!current?.success) {
78
+ if (error && !user)
79
+ setAuthSessionStatus("signed-out");
86
80
  return;
81
+ }
82
+ if (!sessionIdentityMatchesPersistedUser(current.identity, user)) {
83
+ if (current.user)
84
+ commitLogin(current.user);
85
+ else
86
+ resetLocal();
87
+ return;
88
+ }
89
+ if (current.user && JSON.stringify(current.user) !== JSON.stringify(user))
90
+ updateUser(current.user);
87
91
  setAuthSessionStatus("authenticated");
88
92
  }, [
93
+ commitLogin, resetLocal, updateUser,
89
94
  sessionResult,
90
95
  error,
91
96
  authRevision,
92
97
  isLoggedIn,
93
98
  storageInitialized,
94
99
  user,
95
- beginAuthCleanup,
96
- finishAuthCleanup,
97
100
  setAuthSessionStatus,
98
101
  ]);
99
102
  return null;
@@ -24,6 +24,8 @@ export interface PersistedIdentityLike {
24
24
  export type AuthSessionStatus = "initializing" | "clearing" | "signed-out" | "validating" | "authenticated";
25
25
  export declare function isAuthSessionPending(status: AuthSessionStatus): boolean;
26
26
  export declare function canFinishAuthCleanup(expectedRevision: number, currentRevision: number): boolean;
27
+ /** Legacy explicit-cleanup compatibility export. Never call this merely because
28
+ * an origin-local profile cache is absent; reconcile the cookie session instead. */
27
29
  export declare function clearCacheMissSessionBoundary({ cleanupRevision, getCurrentRevision, clearSession, }: {
28
30
  cleanupRevision: number;
29
31
  getCurrentRevision: () => number;
@@ -1 +1 @@
1
- {"version":3,"file":"authSessionPolicy.d.ts","sourceRoot":"","sources":["../../src/lib/authSessionPolicy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAChE,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,MAAM,iBAAiB,GACvB,cAAc,GACd,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,eAAe,CAAC;AAEtB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAIvE;AAED,wBAAgB,oBAAoB,CAChC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,GACxB,OAAO,CAET;AAED,wBAAsB,6BAA6B,CAAC,EAChD,eAAe,EACf,kBAAkB,EAClB,YAAY,GACf,EAAE;IACC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC,GAAG,OAAO,CAAC,OAAO,CAAC,CAInB;AAED,wBAAgB,4BAA4B,CACxC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,GACrB,wBAAwB,CAO1B;AAED,wBAAgB,4BAA4B,CAAC,EACzC,OAAO,EACP,eAAe,EACf,KAAK,EACL,eAAe,GAClB,EAAE;IACC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACxC,eAAe,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAIV;AAED,wBAAgB,uBAAuB,CACnC,IAAI,EAAE,qBAAqB,GAC5B,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAMlC;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE9F;AAED,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,EACjD,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAC7C,OAAO,CAET;AAED,wBAAgB,mCAAmC,CAC/C,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC5C,IAAI,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAC/C,OAAO,CAcT"}
1
+ {"version":3,"file":"authSessionPolicy.d.ts","sourceRoot":"","sources":["../../src/lib/authSessionPolicy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAChE,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,MAAM,iBAAiB,GACvB,cAAc,GACd,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,eAAe,CAAC;AAEtB,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAIvE;AAED,wBAAgB,oBAAoB,CAChC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,GACxB,OAAO,CAET;AAED;oFACoF;AACpF,wBAAsB,6BAA6B,CAAC,EAChD,eAAe,EACf,kBAAkB,EAClB,YAAY,GACf,EAAE;IACC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC,GAAG,OAAO,CAAC,OAAO,CAAC,CAInB;AAED,wBAAgB,4BAA4B,CACxC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,GACrB,wBAAwB,CAO1B;AAED,wBAAgB,4BAA4B,CAAC,EACzC,OAAO,EACP,eAAe,EACf,KAAK,EACL,eAAe,GAClB,EAAE;IACC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACxC,eAAe,EAAE,MAAM,CAAC;CAC3B,GAAG,OAAO,CAIV;AAED,wBAAgB,uBAAuB,CACnC,IAAI,EAAE,qBAAqB,GAC5B,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAMlC;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE9F;AAED,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,EACjD,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAC7C,OAAO,CAET;AAED,wBAAgB,mCAAmC,CAC/C,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC5C,IAAI,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAC/C,OAAO,CAcT"}
@@ -6,6 +6,8 @@ export function isAuthSessionPending(status) {
6
6
  export function canFinishAuthCleanup(expectedRevision, currentRevision) {
7
7
  return expectedRevision === currentRevision;
8
8
  }
9
+ /** Legacy explicit-cleanup compatibility export. Never call this merely because
10
+ * an origin-local profile cache is absent; reconcile the cookie session instead. */
9
11
  export async function clearCacheMissSessionBoundary({ cleanupRevision, getCurrentRevision, clearSession, }) {
10
12
  if (getCurrentRevision() !== cleanupRevision)
11
13
  return false;
@@ -38,7 +40,7 @@ export function getPersistedAccountType(user) {
38
40
  return null;
39
41
  }
40
42
  export function normalizeRefreshFailureStatus(statusCode) {
41
- return statusCode >= 400 && statusCode < 500 ? 401 : statusCode;
43
+ return [400, 401, 403, 422].includes(statusCode) ? 401 : statusCode;
42
44
  }
43
45
  export function isExpectedSignedOutError(error) {
44
46
  return error?.statusCode === 401;
@@ -1 +1 @@
1
- {"version":3,"file":"userAtom.d.ts","sourceRoot":"","sources":["../../src/lib/userAtom.ts"],"names":[],"mappings":"AAMA,OAAO,EAIH,KAAK,iBAAiB,EACzB,MAAM,qBAAqB,CAAC;AA0D7B,eAAO,MAAM,sBAAsB;;CAAuB,CAAC;AAG3D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6DAQpB,CAAC;AAEF,eAAO,MAAM,cAAc,iKAA6C,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;CAAU,CAAC;AAExC,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,yEAAyE;AACzE,eAAO,MAAM,qBAAqB;;CAA0C,CAAC;AAE7E;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS3B,CAAC;AAGF,eAAO,MAAM,eAAe,+BAS1B,CAAC;AAGH,eAAO,MAAM,kBAAkB;;CAY7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;CAU/B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;CAMjC,CAAC;AAGF,eAAO,MAAM,yBAAyB;;CAiCrC,CAAC;AAEF,wBAAgB,cAAc,SAY7B"}
1
+ {"version":3,"file":"userAtom.d.ts","sourceRoot":"","sources":["../../src/lib/userAtom.ts"],"names":[],"mappings":"AAKA,OAAO,EAGH,KAAK,iBAAiB,EACzB,MAAM,qBAAqB,CAAC;AA6D7B,eAAO,MAAM,sBAAsB;;CAAuB,CAAC;AAG3D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6DAQpB,CAAC;AAEF,eAAO,MAAM,cAAc,iKAA6C,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;CAAU,CAAC;AAExC,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,yEAAyE;AACzE,eAAO,MAAM,qBAAqB;;CAA0C,CAAC;AAE7E;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS3B,CAAC;AAGF,eAAO,MAAM,eAAe,+BAS1B,CAAC;AAGH,eAAO,MAAM,kBAAkB;;CAY7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;CAU/B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;CAMjC,CAAC;AAGF,eAAO,MAAM,yBAAyB;;CAgBrC,CAAC;AAEF,wBAAgB,cAAc,SAY7B"}
@@ -2,8 +2,7 @@
2
2
  import CryptoJS from 'crypto-js';
3
3
  import { atom, getDefaultStore } from 'jotai';
4
4
  import { atomWithStorage } from 'jotai/utils';
5
- import { clearSessionCookies } from './actions/auth';
6
- import { canFinishAuthCleanup, clearCacheMissSessionBoundary, isAuthSessionPending, } from './authSessionPolicy';
5
+ import { canFinishAuthCleanup, isAuthSessionPending, } from './authSessionPolicy';
7
6
  const STORAGE_KEY = process.env.NEXT_PUBLIC_USER_KEY;
8
7
  const LOGIN_KEY = process.env.NEXT_PUBLIC_LOGIN_KEY;
9
8
  const SECRET_KEY = process.env.NEXT_PUBLIC_RACE;
@@ -35,11 +34,16 @@ const getWithExpiry = (key) => {
35
34
  if (!data)
36
35
  return null;
37
36
  const { value, expiry } = data;
37
+ if (!value || !value._id || typeof value.firstName !== 'string' || !Number.isFinite(expiry))
38
+ return null;
38
39
  if (Date.now() > expiry) {
39
40
  localStorage.removeItem(key);
40
41
  return null;
41
42
  }
42
- return value;
43
+ const safe = { ...value };
44
+ for (const field of ['devices', 'password', 'accessToken', 'refreshToken', 'emailOtp', 'resetPasswordToken'])
45
+ delete safe[field];
46
+ return safe;
43
47
  }
44
48
  catch (e) {
45
49
  console.warn('Invalid user data:', e);
@@ -131,32 +135,19 @@ export const initializeAuthSessionAtom = atom(null, async (get, set) => {
131
135
  // Only run in browser
132
136
  if (typeof window === 'undefined')
133
137
  return;
134
- // Try the local identity cache first. It remains provisional until the
135
- // backend confirms that the cookies belong to the same actor.
136
138
  const userData = getWithExpiry(STORAGE_KEY);
137
139
  if (userData) {
138
- set(commitLoginAtom, userData);
139
- set(authSessionStatusAtom, "validating");
140
- return;
141
- }
142
- // Missing persisted identity is always a cleanup boundary. The endpoint
143
- // is idempotent for a fresh guest and revokes stale cookie-only sessions.
144
- set(beginAuthCleanupAtom);
145
- const cleanupRevision = get(authRevisionAtom);
146
- try {
147
- await clearCacheMissSessionBoundary({
148
- cleanupRevision,
149
- getCurrentRevision: () => get(authRevisionAtom),
150
- clearSession: clearSessionCookies,
151
- });
152
- }
153
- catch {
154
- // clearSessionCookies is bounded. Local signed-out state is still
155
- // published only after the cleanup attempt has settled.
140
+ const safe = { ...userData };
141
+ delete safe.devices;
142
+ set(userAtom, safe);
143
+ set(isLoggedInAtom, true);
156
144
  }
157
- finally {
158
- set(finishAuthCleanupAtom, cleanupRevision);
145
+ else {
146
+ set(userAtom, null);
147
+ set(isLoggedInAtom, false);
159
148
  }
149
+ set(storageInitializedAtom, true);
150
+ set(authSessionStatusAtom, "validating");
160
151
  });
161
152
  export function resetAuthState() {
162
153
  if (typeof window === 'undefined') {
@@ -0,0 +1,3 @@
1
+ /** Must match backend AUTH_COOKIE_PREFIX; cookie domain alone cannot isolate UAT. */
2
+ export declare function authCookieName(name: string): string;
3
+ //# sourceMappingURL=authCookies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authCookies.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/authCookies.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,4 @@
1
+ /** Must match backend AUTH_COOKIE_PREFIX; cookie domain alone cannot isolate UAT. */
2
+ export function authCookieName(name) {
3
+ return `${process.env.NEXT_PUBLIC_AUTH_COOKIE_PREFIX || ''}${name}`;
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myrjfa/state",
3
- "version": "3.0.9",
3
+ "version": "3.0.10",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./dist/*": "./dist/*.js"
@@ -14,7 +14,6 @@
14
14
  ],
15
15
  "dependencies": {
16
16
  "@tanstack/react-query": "^5.89.0",
17
- "@types/socket.io-client": "^3.0.0",
18
17
  "cheerio": "^1.0.0",
19
18
  "clsx": "^2.1.1",
20
19
  "crypto-js": "^4.2.0",