stellar-drive 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/README.md +607 -0
- package/dist/actions/remoteChange.d.ts +204 -0
- package/dist/actions/remoteChange.d.ts.map +1 -0
- package/dist/actions/remoteChange.js +424 -0
- package/dist/actions/remoteChange.js.map +1 -0
- package/dist/actions/truncateTooltip.d.ts +56 -0
- package/dist/actions/truncateTooltip.d.ts.map +1 -0
- package/dist/actions/truncateTooltip.js +312 -0
- package/dist/actions/truncateTooltip.js.map +1 -0
- package/dist/auth/crypto.d.ts +41 -0
- package/dist/auth/crypto.d.ts.map +1 -0
- package/dist/auth/crypto.js +50 -0
- package/dist/auth/crypto.js.map +1 -0
- package/dist/auth/deviceVerification.d.ts +283 -0
- package/dist/auth/deviceVerification.d.ts.map +1 -0
- package/dist/auth/deviceVerification.js +575 -0
- package/dist/auth/deviceVerification.js.map +1 -0
- package/dist/auth/displayUtils.d.ts +98 -0
- package/dist/auth/displayUtils.d.ts.map +1 -0
- package/dist/auth/displayUtils.js +145 -0
- package/dist/auth/displayUtils.js.map +1 -0
- package/dist/auth/loginGuard.d.ts +134 -0
- package/dist/auth/loginGuard.d.ts.map +1 -0
- package/dist/auth/loginGuard.js +276 -0
- package/dist/auth/loginGuard.js.map +1 -0
- package/dist/auth/offlineCredentials.d.ts +105 -0
- package/dist/auth/offlineCredentials.d.ts.map +1 -0
- package/dist/auth/offlineCredentials.js +176 -0
- package/dist/auth/offlineCredentials.js.map +1 -0
- package/dist/auth/offlineSession.d.ts +96 -0
- package/dist/auth/offlineSession.d.ts.map +1 -0
- package/dist/auth/offlineSession.js +145 -0
- package/dist/auth/offlineSession.js.map +1 -0
- package/dist/auth/resolveAuthState.d.ts +85 -0
- package/dist/auth/resolveAuthState.d.ts.map +1 -0
- package/dist/auth/resolveAuthState.js +249 -0
- package/dist/auth/resolveAuthState.js.map +1 -0
- package/dist/auth/singleUser.d.ts +498 -0
- package/dist/auth/singleUser.d.ts.map +1 -0
- package/dist/auth/singleUser.js +1282 -0
- package/dist/auth/singleUser.js.map +1 -0
- package/dist/bin/commands.d.ts +14 -0
- package/dist/bin/commands.d.ts.map +1 -0
- package/dist/bin/commands.js +68 -0
- package/dist/bin/commands.js.map +1 -0
- package/dist/bin/install-pwa.d.ts +41 -0
- package/dist/bin/install-pwa.d.ts.map +1 -0
- package/dist/bin/install-pwa.js +4594 -0
- package/dist/bin/install-pwa.js.map +1 -0
- package/dist/config.d.ts +249 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +395 -0
- package/dist/config.js.map +1 -0
- package/dist/conflicts.d.ts +306 -0
- package/dist/conflicts.d.ts.map +1 -0
- package/dist/conflicts.js +807 -0
- package/dist/conflicts.js.map +1 -0
- package/dist/crdt/awareness.d.ts +128 -0
- package/dist/crdt/awareness.d.ts.map +1 -0
- package/dist/crdt/awareness.js +284 -0
- package/dist/crdt/awareness.js.map +1 -0
- package/dist/crdt/channel.d.ts +165 -0
- package/dist/crdt/channel.d.ts.map +1 -0
- package/dist/crdt/channel.js +522 -0
- package/dist/crdt/channel.js.map +1 -0
- package/dist/crdt/config.d.ts +58 -0
- package/dist/crdt/config.d.ts.map +1 -0
- package/dist/crdt/config.js +123 -0
- package/dist/crdt/config.js.map +1 -0
- package/dist/crdt/helpers.d.ts +104 -0
- package/dist/crdt/helpers.d.ts.map +1 -0
- package/dist/crdt/helpers.js +116 -0
- package/dist/crdt/helpers.js.map +1 -0
- package/dist/crdt/offline.d.ts +58 -0
- package/dist/crdt/offline.d.ts.map +1 -0
- package/dist/crdt/offline.js +130 -0
- package/dist/crdt/offline.js.map +1 -0
- package/dist/crdt/persistence.d.ts +65 -0
- package/dist/crdt/persistence.d.ts.map +1 -0
- package/dist/crdt/persistence.js +171 -0
- package/dist/crdt/persistence.js.map +1 -0
- package/dist/crdt/provider.d.ts +109 -0
- package/dist/crdt/provider.d.ts.map +1 -0
- package/dist/crdt/provider.js +543 -0
- package/dist/crdt/provider.js.map +1 -0
- package/dist/crdt/store.d.ts +111 -0
- package/dist/crdt/store.d.ts.map +1 -0
- package/dist/crdt/store.js +158 -0
- package/dist/crdt/store.js.map +1 -0
- package/dist/crdt/types.d.ts +281 -0
- package/dist/crdt/types.d.ts.map +1 -0
- package/dist/crdt/types.js +26 -0
- package/dist/crdt/types.js.map +1 -0
- package/dist/data.d.ts +502 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +862 -0
- package/dist/data.js.map +1 -0
- package/dist/database.d.ts +153 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +325 -0
- package/dist/database.js.map +1 -0
- package/dist/debug.d.ts +87 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +135 -0
- package/dist/debug.js.map +1 -0
- package/dist/demo.d.ts +131 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +168 -0
- package/dist/demo.js.map +1 -0
- package/dist/deviceId.d.ts +47 -0
- package/dist/deviceId.d.ts.map +1 -0
- package/dist/deviceId.js +106 -0
- package/dist/deviceId.js.map +1 -0
- package/dist/diagnostics.d.ts +292 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +378 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/engine.d.ts +230 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +2636 -0
- package/dist/engine.js.map +1 -0
- package/dist/entries/actions.d.ts +16 -0
- package/dist/entries/actions.d.ts.map +1 -0
- package/dist/entries/actions.js +29 -0
- package/dist/entries/actions.js.map +1 -0
- package/dist/entries/auth.d.ts +19 -0
- package/dist/entries/auth.d.ts.map +1 -0
- package/dist/entries/auth.js +50 -0
- package/dist/entries/auth.js.map +1 -0
- package/dist/entries/config.d.ts +15 -0
- package/dist/entries/config.d.ts.map +1 -0
- package/dist/entries/config.js +20 -0
- package/dist/entries/config.js.map +1 -0
- package/dist/entries/crdt.d.ts +32 -0
- package/dist/entries/crdt.d.ts.map +1 -0
- package/dist/entries/crdt.js +52 -0
- package/dist/entries/crdt.js.map +1 -0
- package/dist/entries/kit.d.ts +22 -0
- package/dist/entries/kit.d.ts.map +1 -0
- package/dist/entries/kit.js +58 -0
- package/dist/entries/kit.js.map +1 -0
- package/dist/entries/stores.d.ts +22 -0
- package/dist/entries/stores.d.ts.map +1 -0
- package/dist/entries/stores.js +57 -0
- package/dist/entries/stores.js.map +1 -0
- package/dist/entries/types.d.ts +23 -0
- package/dist/entries/types.d.ts.map +1 -0
- package/dist/entries/types.js +12 -0
- package/dist/entries/types.js.map +1 -0
- package/dist/entries/utils.d.ts +12 -0
- package/dist/entries/utils.d.ts.map +1 -0
- package/dist/entries/utils.js +42 -0
- package/dist/entries/utils.js.map +1 -0
- package/dist/entries/vite.d.ts +20 -0
- package/dist/entries/vite.d.ts.map +1 -0
- package/dist/entries/vite.js +26 -0
- package/dist/entries/vite.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +234 -0
- package/dist/index.js.map +1 -0
- package/dist/kit/auth.d.ts +80 -0
- package/dist/kit/auth.d.ts.map +1 -0
- package/dist/kit/auth.js +75 -0
- package/dist/kit/auth.js.map +1 -0
- package/dist/kit/confirm.d.ts +111 -0
- package/dist/kit/confirm.d.ts.map +1 -0
- package/dist/kit/confirm.js +169 -0
- package/dist/kit/confirm.js.map +1 -0
- package/dist/kit/loads.d.ts +187 -0
- package/dist/kit/loads.d.ts.map +1 -0
- package/dist/kit/loads.js +208 -0
- package/dist/kit/loads.js.map +1 -0
- package/dist/kit/server.d.ts +175 -0
- package/dist/kit/server.d.ts.map +1 -0
- package/dist/kit/server.js +297 -0
- package/dist/kit/server.js.map +1 -0
- package/dist/kit/sw.d.ts +176 -0
- package/dist/kit/sw.d.ts.map +1 -0
- package/dist/kit/sw.js +320 -0
- package/dist/kit/sw.js.map +1 -0
- package/dist/queue.d.ts +306 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +925 -0
- package/dist/queue.js.map +1 -0
- package/dist/realtime.d.ts +280 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +1031 -0
- package/dist/realtime.js.map +1 -0
- package/dist/runtime/runtimeConfig.d.ts +110 -0
- package/dist/runtime/runtimeConfig.d.ts.map +1 -0
- package/dist/runtime/runtimeConfig.js +260 -0
- package/dist/runtime/runtimeConfig.js.map +1 -0
- package/dist/schema.d.ts +150 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +891 -0
- package/dist/schema.js.map +1 -0
- package/dist/stores/authState.d.ts +204 -0
- package/dist/stores/authState.d.ts.map +1 -0
- package/dist/stores/authState.js +336 -0
- package/dist/stores/authState.js.map +1 -0
- package/dist/stores/factories.d.ts +140 -0
- package/dist/stores/factories.d.ts.map +1 -0
- package/dist/stores/factories.js +157 -0
- package/dist/stores/factories.js.map +1 -0
- package/dist/stores/network.d.ts +48 -0
- package/dist/stores/network.d.ts.map +1 -0
- package/dist/stores/network.js +261 -0
- package/dist/stores/network.js.map +1 -0
- package/dist/stores/remoteChanges.d.ts +417 -0
- package/dist/stores/remoteChanges.d.ts.map +1 -0
- package/dist/stores/remoteChanges.js +626 -0
- package/dist/stores/remoteChanges.js.map +1 -0
- package/dist/stores/sync.d.ts +165 -0
- package/dist/stores/sync.d.ts.map +1 -0
- package/dist/stores/sync.js +275 -0
- package/dist/stores/sync.js.map +1 -0
- package/dist/supabase/auth.d.ts +219 -0
- package/dist/supabase/auth.d.ts.map +1 -0
- package/dist/supabase/auth.js +459 -0
- package/dist/supabase/auth.js.map +1 -0
- package/dist/supabase/client.d.ts +88 -0
- package/dist/supabase/client.d.ts.map +1 -0
- package/dist/supabase/client.js +313 -0
- package/dist/supabase/client.js.map +1 -0
- package/dist/supabase/validate.d.ts +118 -0
- package/dist/supabase/validate.d.ts.map +1 -0
- package/dist/supabase/validate.js +208 -0
- package/dist/supabase/validate.js.map +1 -0
- package/dist/sw/build/vite-plugin.d.ts +149 -0
- package/dist/sw/build/vite-plugin.d.ts.map +1 -0
- package/dist/sw/build/vite-plugin.js +517 -0
- package/dist/sw/build/vite-plugin.js.map +1 -0
- package/dist/sw/sw.js +664 -0
- package/dist/types.d.ts +363 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +85 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +156 -0
- package/dist/utils.js.map +1 -0
- package/package.json +117 -0
- package/src/components/DeferredChangesBanner.svelte +477 -0
- package/src/components/DemoBanner.svelte +110 -0
- package/src/components/SyncStatus.svelte +1732 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Auth State Resolution
|
|
3
|
+
*
|
|
4
|
+
* Determines the current authentication state for single-user mode by checking
|
|
5
|
+
* Supabase session, offline session, and cached credentials. Used by app layouts
|
|
6
|
+
* and route guards to determine whether the user is authenticated and in which
|
|
7
|
+
* mode (online Supabase session vs. offline cached session).
|
|
8
|
+
*
|
|
9
|
+
* Architecture:
|
|
10
|
+
* - Requires `auth.singleUser` to be configured in the engine config.
|
|
11
|
+
* If not configured, returns `authMode: 'none'` immediately.
|
|
12
|
+
* - Checks local `singleUserConfig` in IndexedDB, handles legacy migration,
|
|
13
|
+
* PIN length migration, session refresh, and offline fallback.
|
|
14
|
+
* - The resolver does NOT start the sync engine -- callers decide whether to
|
|
15
|
+
* start sync based on the returned `authMode`.
|
|
16
|
+
* - On catastrophic failure (corrupted auth state), all Supabase localStorage
|
|
17
|
+
* keys (`sb-*`) are purged and `authMode: 'none'` is returned, ensuring the
|
|
18
|
+
* user can start fresh rather than being permanently locked out.
|
|
19
|
+
*
|
|
20
|
+
* Security considerations:
|
|
21
|
+
* - In single-user mode, legacy configs without an email (from the anonymous
|
|
22
|
+
* auth era) are nuked entirely -- anonymous data is inaccessible under
|
|
23
|
+
* ownership-based RLS anyway.
|
|
24
|
+
* - The `singleUserConfig` table has been moved to IndexedDB + Supabase
|
|
25
|
+
* `user_metadata`; there is no longer a Supabase `single_user_config` table.
|
|
26
|
+
* - Session refresh is attempted for expired single-user sessions before
|
|
27
|
+
* falling back to the PIN gate, preventing unnecessary re-authentication
|
|
28
|
+
* when only the access token (not the refresh token) has expired.
|
|
29
|
+
*
|
|
30
|
+
* @module auth/resolveAuthState
|
|
31
|
+
*/
|
|
32
|
+
import { getSession, isSessionExpired } from '../supabase/auth';
|
|
33
|
+
import { getValidOfflineSession } from './offlineSession';
|
|
34
|
+
import { resetSingleUserRemote } from './singleUser';
|
|
35
|
+
import { getEngineConfig, waitForDb } from '../config';
|
|
36
|
+
import { supabase } from '../supabase/client';
|
|
37
|
+
import { debugLog, debugWarn, debugError } from '../debug';
|
|
38
|
+
import { isDemoMode } from '../demo';
|
|
39
|
+
// =============================================================================
|
|
40
|
+
// PUBLIC API
|
|
41
|
+
// =============================================================================
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the current authentication state.
|
|
44
|
+
*
|
|
45
|
+
* Requires `auth.singleUser` to be configured. Delegates to
|
|
46
|
+
* {@link resolveSingleUserAuthState} for the full resolution flow.
|
|
47
|
+
* If single-user mode is not configured, returns `authMode: 'none'`.
|
|
48
|
+
*
|
|
49
|
+
* Handles corrupted state cleanup by purging `sb-*` localStorage keys if
|
|
50
|
+
* session retrieval throws.
|
|
51
|
+
*
|
|
52
|
+
* @returns A promise resolving to an {@link AuthStateResult} describing the
|
|
53
|
+
* current auth mode, session, and offline profile (if applicable).
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const { authMode, session, singleUserSetUp } = await resolveAuthState();
|
|
58
|
+
* if (authMode === 'supabase') {
|
|
59
|
+
* startSyncEngine(session);
|
|
60
|
+
* } else if (authMode === 'offline') {
|
|
61
|
+
* enterOfflineMode();
|
|
62
|
+
* } else {
|
|
63
|
+
* redirectToLogin();
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @see {@link AuthStateResult} for the return type shape.
|
|
68
|
+
*/
|
|
69
|
+
export async function resolveAuthState() {
|
|
70
|
+
/* Demo mode short-circuit: skip all real auth resolution. */
|
|
71
|
+
if (isDemoMode()) {
|
|
72
|
+
return { session: null, authMode: 'demo', offlineProfile: null, singleUserSetUp: true };
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
/* Ensure DB is open and upgraded before any IndexedDB access.
|
|
76
|
+
This is critical during cold start when the DB may still be initializing. */
|
|
77
|
+
await waitForDb();
|
|
78
|
+
const engineConfig = getEngineConfig();
|
|
79
|
+
if (engineConfig.auth?.singleUser) {
|
|
80
|
+
return resolveSingleUserAuthState();
|
|
81
|
+
}
|
|
82
|
+
/* Single-user mode not configured -- no auth available. */
|
|
83
|
+
return { session: null, authMode: 'none', offlineProfile: null };
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
/* Catastrophic failure: session retrieval threw (corrupted auth state).
|
|
87
|
+
Clear all Supabase auth data from localStorage so the user can start
|
|
88
|
+
fresh rather than being permanently locked out. */
|
|
89
|
+
debugError('[Auth] Failed to resolve auth state, clearing auth storage:', e);
|
|
90
|
+
try {
|
|
91
|
+
if (typeof localStorage !== 'undefined') {
|
|
92
|
+
const keys = Object.keys(localStorage).filter((k) => k.startsWith('sb-'));
|
|
93
|
+
keys.forEach((k) => localStorage.removeItem(k));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
/* Ignore storage errors -- we are already in error recovery. */
|
|
98
|
+
}
|
|
99
|
+
return { session: null, authMode: 'none', offlineProfile: null };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// =============================================================================
|
|
103
|
+
// INTERNAL -- Single-User Mode Resolution
|
|
104
|
+
// =============================================================================
|
|
105
|
+
/**
|
|
106
|
+
* Resolve auth state for single-user mode.
|
|
107
|
+
*
|
|
108
|
+
* Handles the following scenarios in order:
|
|
109
|
+
*
|
|
110
|
+
* 1. **No local config**: User has not set up on this device.
|
|
111
|
+
* Returns `authMode: 'none'`, `singleUserSetUp: false`.
|
|
112
|
+
*
|
|
113
|
+
* 2. **Legacy config without email**: Config from the anonymous auth era.
|
|
114
|
+
* Nukes all local auth artifacts and returns `singleUserSetUp: false`.
|
|
115
|
+
*
|
|
116
|
+
* 3. **Code-length migration**: The engine config specifies a different PIN
|
|
117
|
+
* length than what is stored locally. Resets remote and local state, forcing
|
|
118
|
+
* re-setup with the new PIN length.
|
|
119
|
+
*
|
|
120
|
+
* 4. **Valid Supabase session**: Returns `authMode: 'supabase'`, `singleUserSetUp: true`.
|
|
121
|
+
*
|
|
122
|
+
* 5. **Expired session with valid refresh token**: Attempts token refresh.
|
|
123
|
+
* On success, returns `authMode: 'supabase'`. On failure, falls through.
|
|
124
|
+
*
|
|
125
|
+
* 6. **Offline with cached session**: Even an expired Supabase session is usable
|
|
126
|
+
* offline (RLS is not enforced client-side).
|
|
127
|
+
* Returns `authMode: 'supabase'`, `singleUserSetUp: true`.
|
|
128
|
+
*
|
|
129
|
+
* 7. **Offline with offline session**: Falls back to offline credentials.
|
|
130
|
+
* Returns `authMode: 'offline'`, `singleUserSetUp: true`.
|
|
131
|
+
*
|
|
132
|
+
* 8. **No valid session (locked)**: User must re-enter their PIN.
|
|
133
|
+
* Returns `authMode: 'none'`, `singleUserSetUp: true`.
|
|
134
|
+
*
|
|
135
|
+
* @returns A promise resolving to an {@link AuthStateResult} with the
|
|
136
|
+
* `singleUserSetUp` field populated.
|
|
137
|
+
*/
|
|
138
|
+
async function resolveSingleUserAuthState() {
|
|
139
|
+
try {
|
|
140
|
+
const db = getEngineConfig().db;
|
|
141
|
+
if (!db) {
|
|
142
|
+
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
|
|
143
|
+
}
|
|
144
|
+
const config = (await db.table('singleUserConfig').get('config'));
|
|
145
|
+
if (!config) {
|
|
146
|
+
/* No local config -- user has not set up on this device.
|
|
147
|
+
With real email/password auth, new devices go through the login flow
|
|
148
|
+
(email + PIN) which creates the local config after signInWithPassword. */
|
|
149
|
+
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
|
|
150
|
+
}
|
|
151
|
+
if (!config.email) {
|
|
152
|
+
/* Config without email is invalid — user needs to go through setup. */
|
|
153
|
+
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
|
|
154
|
+
}
|
|
155
|
+
/* codeLength migration: if the engine config specifies a different PIN length
|
|
156
|
+
than what is stored locally, the user must re-setup. This handles the case
|
|
157
|
+
where the app developer changes the codeLength in their engine config. */
|
|
158
|
+
const expectedCodeLength = getEngineConfig().auth?.singleUser?.codeLength;
|
|
159
|
+
const storedCodeLength = config.codeLength;
|
|
160
|
+
if (expectedCodeLength && storedCodeLength !== expectedCodeLength) {
|
|
161
|
+
debugLog('[Auth] codeLength mismatch detected:', storedCodeLength, '→', expectedCodeLength);
|
|
162
|
+
try {
|
|
163
|
+
await resetSingleUserRemote();
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
debugWarn('[Auth] Failed to reset remote single user:', e);
|
|
167
|
+
}
|
|
168
|
+
/* Sign out to kill in-memory and persisted Supabase session. */
|
|
169
|
+
try {
|
|
170
|
+
await supabase.auth.signOut();
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
/* Ignore -- session may already be cleared by resetSingleUserRemote. */
|
|
174
|
+
}
|
|
175
|
+
/* Clear local state so the setup flow starts fresh. */
|
|
176
|
+
try {
|
|
177
|
+
await db.table('singleUserConfig').delete('config');
|
|
178
|
+
await db.table('offlineCredentials').delete('current_user');
|
|
179
|
+
await db.table('offlineSession').delete('current_session');
|
|
180
|
+
}
|
|
181
|
+
catch (e) {
|
|
182
|
+
debugWarn('[Auth] Failed to clear local auth state:', e);
|
|
183
|
+
}
|
|
184
|
+
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
|
|
185
|
+
}
|
|
186
|
+
// =========================================================================
|
|
187
|
+
// Config exists -- check for an active session
|
|
188
|
+
// =========================================================================
|
|
189
|
+
let session = await getSession();
|
|
190
|
+
/* If the access token is expired, try refreshing before giving up.
|
|
191
|
+
Refresh tokens outlive the access token -- without this, users are forced
|
|
192
|
+
to re-enter their PIN on every page load once the access token expires
|
|
193
|
+
(default Supabase access token lifetime: 1 hour). */
|
|
194
|
+
if (session && isSessionExpired(session)) {
|
|
195
|
+
debugLog('[Auth] Single-user session expired, attempting refresh...');
|
|
196
|
+
try {
|
|
197
|
+
const { data, error } = await supabase.auth.refreshSession();
|
|
198
|
+
if (!error && data.session) {
|
|
199
|
+
session = data.session;
|
|
200
|
+
debugLog('[Auth] Single-user session refreshed successfully');
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
debugWarn('[Auth] Single-user session refresh failed:', error?.message);
|
|
204
|
+
session = null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
session = null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const hasValidSession = session && !isSessionExpired(session);
|
|
212
|
+
if (hasValidSession) {
|
|
213
|
+
return { session, authMode: 'supabase', offlineProfile: null, singleUserSetUp: true };
|
|
214
|
+
}
|
|
215
|
+
// =========================================================================
|
|
216
|
+
// No valid online session -- check offline fallbacks
|
|
217
|
+
// =========================================================================
|
|
218
|
+
const isOffline = typeof navigator !== 'undefined' && !navigator.onLine;
|
|
219
|
+
if (isOffline) {
|
|
220
|
+
/* Even an expired cached Supabase session is usable offline because RLS
|
|
221
|
+
is not enforced on the client side -- it only matters when syncing. */
|
|
222
|
+
if (session) {
|
|
223
|
+
return { session, authMode: 'supabase', offlineProfile: null, singleUserSetUp: true };
|
|
224
|
+
}
|
|
225
|
+
const offlineSession = await getValidOfflineSession();
|
|
226
|
+
if (offlineSession) {
|
|
227
|
+
/* Construct an OfflineCredentials-shaped object from the local config
|
|
228
|
+
so the caller has profile data available for the offline UI. */
|
|
229
|
+
const offlineProfile = {
|
|
230
|
+
id: 'current_user',
|
|
231
|
+
userId: offlineSession.userId,
|
|
232
|
+
email: config.email || '',
|
|
233
|
+
password: config.gateHash || '',
|
|
234
|
+
profile: config.profile,
|
|
235
|
+
cachedAt: new Date().toISOString()
|
|
236
|
+
};
|
|
237
|
+
return { session: null, authMode: 'offline', offlineProfile, singleUserSetUp: true };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/* No valid session -- the single-user app is "locked" and the user must
|
|
241
|
+
re-enter their PIN to unlock. */
|
|
242
|
+
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: true };
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
debugError('[Auth] Failed to resolve single-user auth state:', e);
|
|
246
|
+
return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=resolveAuthState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveAuthState.js","sourceRoot":"","sources":["../../src/auth/resolveAuthState.ts"],"names":[],"mappings":"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"}
|