@prabhask5/stellar-engine 1.0.11 → 1.0.13

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
@@ -13,7 +13,7 @@ A local-first, offline-capable sync engine for **SvelteKit + Supabase + Dexie**
13
13
  - **Intent-based sync operations** -- operations preserve intent (`increment`, `set`, `create`, `delete`) instead of just final state, enabling smarter coalescing and conflict handling.
14
14
  - **Three-tier conflict resolution** -- field-level diffing, numeric merge fields, and configurable exclusion lists let you resolve conflicts precisely rather than with blanket last-write-wins.
15
15
  - **Offline authentication** -- credential caching and offline session tokens let users sign in and work without connectivity; sessions reconcile automatically on reconnect.
16
- - **Single-user auth mode** -- for personal apps, replace email/password with a local PIN code or password gate backed by Supabase anonymous auth. Setup, unlock, lock, and gate change are all handled by the engine with full offline support.
16
+ - **Single-user auth mode** -- for personal apps, use a simplified PIN code or password gate backed by real Supabase email/password auth. The user provides an email during setup; the PIN is padded to meet Supabase's minimum password length and verified server-side. Setup, unlock, lock, and gate change are all handled by the engine with full offline support.
17
17
  - **Realtime subscriptions** -- Supabase Realtime channels push remote changes into local state instantly, with duplicate-delivery guards to prevent re-processing.
18
18
  - **Operation coalescing** -- batches of rapid local writes (e.g., 50 individual increments) are compressed into a single outbound operation, reducing sync traffic dramatically.
19
19
  - **Tombstone management** -- soft deletes are propagated cleanly, and stale tombstones are garbage-collected after a configurable retention period.
@@ -68,7 +68,7 @@ if (auth.authMode !== 'none') await startSyncEngine();
68
68
 
69
69
  ### Single-user mode
70
70
 
71
- For personal apps with a PIN code gate instead of email/password:
71
+ For personal apps with a PIN code gate backed by real Supabase email/password auth:
72
72
 
73
73
  ```ts
74
74
  import { initEngine, startSyncEngine, supabase } from '@prabhask5/stellar-engine';
@@ -84,6 +84,8 @@ initEngine({
84
84
  mode: 'single-user',
85
85
  singleUser: { gateType: 'code', codeLength: 4 },
86
86
  enableOfflineAuth: true,
87
+ // emailConfirmation: { enabled: true }, // require email confirmation on setup
88
+ // deviceVerification: { enabled: true }, // require OTP verification on new devices
87
89
  },
88
90
  });
89
91
 
@@ -91,9 +93,13 @@ await initConfig();
91
93
  const auth = await resolveAuthState();
92
94
 
93
95
  if (!auth.singleUserSetUp) {
94
- // Show setup screen → call setupSingleUser(code, profile)
96
+ // Show setup screen → call setupSingleUser(code, profile, email)
97
+ // Returns { error, confirmationRequired }
98
+ // If confirmationRequired, prompt user to check email then call completeSingleUserSetup()
95
99
  } else if (auth.authMode === 'none') {
96
100
  // Show unlock screen → call unlockSingleUser(code)
101
+ // Returns { error, deviceVerificationRequired?, maskedEmail? }
102
+ // If deviceVerificationRequired, prompt for OTP then call completeDeviceVerification(tokenHash?)
97
103
  } else {
98
104
  await startSyncEngine();
99
105
  }
@@ -107,7 +113,7 @@ Import only what you need via subpath exports:
107
113
  |---|---|
108
114
  | `@prabhask5/stellar-engine` | `initEngine`, `startSyncEngine`, `runFullSync`, `supabase`, `getDb`, `validateSupabaseCredentials`, `validateSchema` |
109
115
  | `@prabhask5/stellar-engine/data` | All engine CRUD + query operations (`engineCreate`, `engineUpdate`, etc.) |
110
- | `@prabhask5/stellar-engine/auth` | All auth functions (`signIn`, `signUp`, `resolveAuthState`, `isAdmin`, single-user: `setupSingleUser`, `unlockSingleUser`, `lockSingleUser`, etc.) |
116
+ | `@prabhask5/stellar-engine/auth` | All auth functions (`signIn`, `signUp`, `resolveAuthState`, `isAdmin`, single-user: `setupSingleUser`, `unlockSingleUser`, `lockSingleUser`, `completeSingleUserSetup`, `completeDeviceVerification`, `padPin`, etc.) |
111
117
  | `@prabhask5/stellar-engine/stores` | Reactive stores + event subscriptions (`syncStatusStore`, `authState`, `onSyncComplete`, etc.) |
112
118
  | `@prabhask5/stellar-engine/types` | All type exports (`Session`, `SyncEngineConfig`, `BatchOperation`, `SingleUserConfig`, etc.) |
113
119
  | `@prabhask5/stellar-engine/utils` | Utility functions (`generateId`, `now`, `calculateNewOrder`, `snakeToCamel`, `debug`, etc.) |
@@ -130,34 +136,28 @@ Row-Level Security policies should scope reads and writes to the authenticated u
130
136
 
131
137
  **Single-user mode additional requirements:**
132
138
 
133
- Single-user mode requires a `single_user_config` table in Supabase for multi-device config sync:
139
+ Single-user mode uses real Supabase email/password auth where the PIN is padded to meet Supabase's minimum password length. The user provides an email during setup, and the PIN is verified server-side.
140
+
141
+ If `deviceVerification` is enabled in the auth config, you need a `trusted_devices` table:
134
142
 
135
143
  ```sql
136
- CREATE TABLE single_user_config (
144
+ CREATE TABLE trusted_devices (
137
145
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
138
- gate_type text NOT NULL DEFAULT 'code',
139
- code_length integer,
140
- gate_hash text NOT NULL,
141
- profile jsonb NOT NULL DEFAULT '{}',
142
- setup_at timestamptz NOT NULL DEFAULT now(),
143
- updated_at timestamptz NOT NULL DEFAULT now(),
144
- is_deleted boolean NOT NULL DEFAULT false,
145
- user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE
146
+ user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
147
+ device_id text NOT NULL,
148
+ device_label text,
149
+ trusted_at timestamptz DEFAULT now() NOT NULL,
150
+ last_used_at timestamptz DEFAULT now() NOT NULL,
151
+ UNIQUE(user_id, device_id)
146
152
  );
147
-
148
- -- Enable RLS
149
- ALTER TABLE single_user_config ENABLE ROW LEVEL SECURITY;
150
-
151
- -- RLS policy: authenticated users (anonymous sessions) can manage their own row
152
- CREATE POLICY "Users can manage their own config"
153
- ON single_user_config FOR ALL
154
- USING (auth.uid() = user_id)
155
- WITH CHECK (auth.uid() = user_id);
153
+ ALTER TABLE trusted_devices ENABLE ROW LEVEL SECURITY;
154
+ CREATE POLICY "Users manage own devices" ON trusted_devices FOR ALL
155
+ USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
156
156
  ```
157
157
 
158
- You must also enable **"Allow anonymous sign-ins"** in your Supabase project under Authentication > Settings.
158
+ If `emailConfirmation` is enabled, Supabase email templates must be configured.
159
159
 
160
- **Schema validation:** The engine automatically validates that all configured tables (and `single_user_config` in single-user mode) exist in Supabase on the first sync. Missing tables are reported via `syncStatusStore` and the debug console.
160
+ **Schema validation:** The engine automatically validates that all configured tables (and `trusted_devices` when `deviceVerification.enabled`) exist in Supabase on the first sync. Missing tables are reported via `syncStatusStore` and the debug console.
161
161
 
162
162
  **Dexie (IndexedDB)**
163
163
 
@@ -260,18 +260,21 @@ Alternatively, you can provide a pre-created Dexie instance via the `db` config
260
260
 
261
261
  ### Single-user auth
262
262
 
263
- For personal apps that don't need email/password accounts. Uses a local PIN code or password gate with Supabase anonymous auth behind the scenes. Enable by setting `auth.mode: 'single-user'` in the engine config. Requires "Allow anonymous sign-ins" enabled in Supabase Authentication settings.
263
+ For personal apps that use a simplified PIN or password gate. Uses real Supabase email/password auth where the PIN is padded to meet minimum password length. Enable by setting `auth.mode: 'single-user'` in the engine config.
264
264
 
265
265
  | Export | Description |
266
266
  |---|---|
267
267
  | `isSingleUserSetUp()` | Check if initial setup is complete. |
268
268
  | `getSingleUserInfo()` | Get display info (profile, gate type) for the unlock screen. |
269
- | `setupSingleUser(gate, profile)` | First-time setup: create gate, anonymous Supabase user, and store config. |
270
- | `unlockSingleUser(gate)` | Verify gate and restore session (online or offline). |
269
+ | `setupSingleUser(gate, profile, email)` | First-time setup: create gate, Supabase email/password user, and store config. Returns `{ error, confirmationRequired }`. |
270
+ | `unlockSingleUser(gate)` | Verify gate and restore session (online or offline). Returns `{ error, deviceVerificationRequired?, maskedEmail? }`. |
271
+ | `completeSingleUserSetup()` | Called after the user confirms their email (when `emailConfirmation` is enabled). |
272
+ | `completeDeviceVerification(tokenHash?)` | Called after the user completes device OTP verification (when `deviceVerification` is enabled). |
271
273
  | `lockSingleUser()` | Stop sync and reset auth state without destroying data. |
272
274
  | `changeSingleUserGate(oldGate, newGate)` | Change the PIN code or password. |
273
275
  | `updateSingleUserProfile(profile)` | Update profile in IndexedDB and Supabase metadata. |
274
276
  | `resetSingleUser()` | Full reset: clear config, sign out, wipe local data. |
277
+ | `padPin(pin)` | Pad a PIN to meet Supabase's minimum password length requirement. |
275
278
 
276
279
  ### Queue
277
280
 
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Device Verification Module
3
+ *
4
+ * Manages trusted devices for single-user and multi-user modes.
5
+ * Uses Supabase `trusted_devices` table and `signInWithOtp()` for email-based
6
+ * device verification on untrusted devices.
7
+ */
8
+ import type { TrustedDevice } from '../types';
9
+ /**
10
+ * Generate a human-readable device label (e.g. "Chrome on macOS").
11
+ */
12
+ export declare function getDeviceLabel(): string;
13
+ /**
14
+ * Mask an email address for display (e.g. "pr••••@gmail.com").
15
+ */
16
+ export declare function maskEmail(email: string): string;
17
+ /**
18
+ * Check if the current device is trusted for a given user.
19
+ * A device is trusted if it has a `trusted_devices` row with `last_used_at`
20
+ * within the configured trust duration.
21
+ */
22
+ export declare function isDeviceTrusted(userId: string): Promise<boolean>;
23
+ /**
24
+ * Trust the current device for a user.
25
+ * Uses upsert on (user_id, device_id) unique constraint.
26
+ */
27
+ export declare function trustCurrentDevice(userId: string): Promise<void>;
28
+ /**
29
+ * Update `last_used_at` for the current device (called on each successful login).
30
+ */
31
+ export declare function touchTrustedDevice(userId: string): Promise<void>;
32
+ /**
33
+ * Get all trusted devices for a user.
34
+ */
35
+ export declare function getTrustedDevices(userId: string): Promise<TrustedDevice[]>;
36
+ /**
37
+ * Remove a trusted device by ID.
38
+ */
39
+ export declare function removeTrustedDevice(id: string): Promise<void>;
40
+ /**
41
+ * Send a device verification OTP email.
42
+ * Signs out first (untrusted device flow), then sends OTP.
43
+ */
44
+ export declare function sendDeviceVerification(email: string): Promise<{
45
+ error: string | null;
46
+ }>;
47
+ /**
48
+ * Verify a device verification OTP token hash (from email link).
49
+ */
50
+ export declare function verifyDeviceCode(tokenHash: string): Promise<{
51
+ error: string | null;
52
+ }>;
53
+ /**
54
+ * Get the current device ID (exposed for consumers).
55
+ */
56
+ export declare function getCurrentDeviceId(): string;
57
+ //# sourceMappingURL=deviceVerification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceVerification.d.ts","sourceRoot":"","sources":["../../src/auth/deviceVerification.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAqC9C;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAqBvC;AAMD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO/C;AAMD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBtE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBtE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBtE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAkBhF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAenE;AAMD;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAqB7F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAkB3F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Device Verification Module
3
+ *
4
+ * Manages trusted devices for single-user and multi-user modes.
5
+ * Uses Supabase `trusted_devices` table and `signInWithOtp()` for email-based
6
+ * device verification on untrusted devices.
7
+ */
8
+ import { getEngineConfig } from '../config';
9
+ import { supabase } from '../supabase/client';
10
+ import { getDeviceId } from '../deviceId';
11
+ import { debugLog, debugWarn, debugError } from '../debug';
12
+ const DEFAULT_TRUST_DURATION_DAYS = 90;
13
+ // ============================================================
14
+ // HELPERS
15
+ // ============================================================
16
+ function getDb() {
17
+ const db = getEngineConfig().db;
18
+ if (!db)
19
+ throw new Error('Database not initialized.');
20
+ return db;
21
+ }
22
+ function getTrustDurationDays() {
23
+ return getEngineConfig().auth?.deviceVerification?.trustDurationDays ?? DEFAULT_TRUST_DURATION_DAYS;
24
+ }
25
+ function snakeToCamelDevice(row) {
26
+ return {
27
+ id: row.id,
28
+ userId: row.user_id,
29
+ deviceId: row.device_id,
30
+ deviceLabel: row.device_label,
31
+ trustedAt: row.trusted_at,
32
+ lastUsedAt: row.last_used_at,
33
+ };
34
+ }
35
+ // ============================================================
36
+ // DEVICE LABEL
37
+ // ============================================================
38
+ /**
39
+ * Generate a human-readable device label (e.g. "Chrome on macOS").
40
+ */
41
+ export function getDeviceLabel() {
42
+ if (typeof navigator === 'undefined')
43
+ return 'Unknown device';
44
+ const ua = navigator.userAgent;
45
+ let browser = 'Browser';
46
+ let os = '';
47
+ // Detect browser
48
+ if (ua.includes('Firefox'))
49
+ browser = 'Firefox';
50
+ else if (ua.includes('Edg/'))
51
+ browser = 'Edge';
52
+ else if (ua.includes('Chrome') && !ua.includes('Edg/'))
53
+ browser = 'Chrome';
54
+ else if (ua.includes('Safari') && !ua.includes('Chrome'))
55
+ browser = 'Safari';
56
+ // Detect OS
57
+ if (ua.includes('Mac OS X'))
58
+ os = 'macOS';
59
+ else if (ua.includes('Windows'))
60
+ os = 'Windows';
61
+ else if (ua.includes('Linux'))
62
+ os = 'Linux';
63
+ else if (ua.includes('Android'))
64
+ os = 'Android';
65
+ else if (ua.includes('iPhone') || ua.includes('iPad'))
66
+ os = 'iOS';
67
+ return os ? `${browser} on ${os}` : browser;
68
+ }
69
+ // ============================================================
70
+ // EMAIL MASKING
71
+ // ============================================================
72
+ /**
73
+ * Mask an email address for display (e.g. "pr••••@gmail.com").
74
+ */
75
+ export function maskEmail(email) {
76
+ const [local, domain] = email.split('@');
77
+ if (!domain)
78
+ return email;
79
+ const visible = Math.min(2, local.length);
80
+ const masked = local.slice(0, visible) + '\u2022'.repeat(Math.max(1, local.length - visible));
81
+ return `${masked}@${domain}`;
82
+ }
83
+ // ============================================================
84
+ // DEVICE TRUST QUERIES
85
+ // ============================================================
86
+ /**
87
+ * Check if the current device is trusted for a given user.
88
+ * A device is trusted if it has a `trusted_devices` row with `last_used_at`
89
+ * within the configured trust duration.
90
+ */
91
+ export async function isDeviceTrusted(userId) {
92
+ try {
93
+ const deviceId = getDeviceId();
94
+ const trustDays = getTrustDurationDays();
95
+ const cutoff = new Date();
96
+ cutoff.setDate(cutoff.getDate() - trustDays);
97
+ const { data, error } = await supabase
98
+ .from('trusted_devices')
99
+ .select('id, last_used_at')
100
+ .eq('user_id', userId)
101
+ .eq('device_id', deviceId)
102
+ .gte('last_used_at', cutoff.toISOString())
103
+ .limit(1);
104
+ if (error) {
105
+ debugWarn('[DeviceVerification] Trust check failed:', error.message);
106
+ return false;
107
+ }
108
+ return (data?.length ?? 0) > 0;
109
+ }
110
+ catch (e) {
111
+ debugError('[DeviceVerification] Trust check error:', e);
112
+ return false;
113
+ }
114
+ }
115
+ /**
116
+ * Trust the current device for a user.
117
+ * Uses upsert on (user_id, device_id) unique constraint.
118
+ */
119
+ export async function trustCurrentDevice(userId) {
120
+ try {
121
+ const deviceId = getDeviceId();
122
+ const label = getDeviceLabel();
123
+ const now = new Date().toISOString();
124
+ const { error } = await supabase
125
+ .from('trusted_devices')
126
+ .upsert({
127
+ user_id: userId,
128
+ device_id: deviceId,
129
+ device_label: label,
130
+ trusted_at: now,
131
+ last_used_at: now,
132
+ }, { onConflict: 'user_id,device_id' });
133
+ if (error) {
134
+ debugError('[DeviceVerification] Trust device failed:', error.message);
135
+ }
136
+ else {
137
+ debugLog('[DeviceVerification] Device trusted:', label);
138
+ }
139
+ }
140
+ catch (e) {
141
+ debugError('[DeviceVerification] Trust device error:', e);
142
+ }
143
+ }
144
+ /**
145
+ * Update `last_used_at` for the current device (called on each successful login).
146
+ */
147
+ export async function touchTrustedDevice(userId) {
148
+ try {
149
+ const deviceId = getDeviceId();
150
+ const { error } = await supabase
151
+ .from('trusted_devices')
152
+ .update({ last_used_at: new Date().toISOString() })
153
+ .eq('user_id', userId)
154
+ .eq('device_id', deviceId);
155
+ if (error) {
156
+ debugWarn('[DeviceVerification] Touch device failed:', error.message);
157
+ }
158
+ }
159
+ catch (e) {
160
+ debugWarn('[DeviceVerification] Touch device error:', e);
161
+ }
162
+ }
163
+ /**
164
+ * Get all trusted devices for a user.
165
+ */
166
+ export async function getTrustedDevices(userId) {
167
+ try {
168
+ const { data, error } = await supabase
169
+ .from('trusted_devices')
170
+ .select('id, user_id, device_id, device_label, trusted_at, last_used_at')
171
+ .eq('user_id', userId)
172
+ .order('last_used_at', { ascending: false });
173
+ if (error) {
174
+ debugError('[DeviceVerification] Get devices failed:', error.message);
175
+ return [];
176
+ }
177
+ return (data || []).map(snakeToCamelDevice);
178
+ }
179
+ catch (e) {
180
+ debugError('[DeviceVerification] Get devices error:', e);
181
+ return [];
182
+ }
183
+ }
184
+ /**
185
+ * Remove a trusted device by ID.
186
+ */
187
+ export async function removeTrustedDevice(id) {
188
+ try {
189
+ const { error } = await supabase
190
+ .from('trusted_devices')
191
+ .delete()
192
+ .eq('id', id);
193
+ if (error) {
194
+ debugError('[DeviceVerification] Remove device failed:', error.message);
195
+ }
196
+ else {
197
+ debugLog('[DeviceVerification] Device removed:', id);
198
+ }
199
+ }
200
+ catch (e) {
201
+ debugError('[DeviceVerification] Remove device error:', e);
202
+ }
203
+ }
204
+ // ============================================================
205
+ // OTP VERIFICATION FLOW
206
+ // ============================================================
207
+ /**
208
+ * Send a device verification OTP email.
209
+ * Signs out first (untrusted device flow), then sends OTP.
210
+ */
211
+ export async function sendDeviceVerification(email) {
212
+ try {
213
+ // Sign out first — untrusted device should not retain a session
214
+ await supabase.auth.signOut();
215
+ const { error } = await supabase.auth.signInWithOtp({
216
+ email,
217
+ options: { shouldCreateUser: false },
218
+ });
219
+ if (error) {
220
+ debugError('[DeviceVerification] Send OTP failed:', error.message);
221
+ return { error: error.message };
222
+ }
223
+ debugLog('[DeviceVerification] OTP sent to:', maskEmail(email));
224
+ return { error: null };
225
+ }
226
+ catch (e) {
227
+ debugError('[DeviceVerification] Send OTP error:', e);
228
+ return { error: e instanceof Error ? e.message : 'Failed to send verification email' };
229
+ }
230
+ }
231
+ /**
232
+ * Verify a device verification OTP token hash (from email link).
233
+ */
234
+ export async function verifyDeviceCode(tokenHash) {
235
+ try {
236
+ const { error } = await supabase.auth.verifyOtp({
237
+ token_hash: tokenHash,
238
+ type: 'email',
239
+ });
240
+ if (error) {
241
+ debugError('[DeviceVerification] Verify OTP failed:', error.message);
242
+ return { error: error.message };
243
+ }
244
+ debugLog('[DeviceVerification] OTP verified successfully');
245
+ return { error: null };
246
+ }
247
+ catch (e) {
248
+ debugError('[DeviceVerification] Verify OTP error:', e);
249
+ return { error: e instanceof Error ? e.message : 'Verification failed' };
250
+ }
251
+ }
252
+ /**
253
+ * Get the current device ID (exposed for consumers).
254
+ */
255
+ export function getCurrentDeviceId() {
256
+ return getDeviceId();
257
+ }
258
+ //# sourceMappingURL=deviceVerification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deviceVerification.js","sourceRoot":"","sources":["../../src/auth/deviceVerification.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolveAuthState.d.ts","sourceRoot":"","sources":["../../src/auth/resolveAuthState.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAoB,MAAM,UAAU,CAAC;AAQrE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1C,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,0FAA0F;IAC1F,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,eAAe,CAAC,CA8DjE"}
1
+ {"version":3,"file":"resolveAuthState.d.ts","sourceRoot":"","sources":["../../src/auth/resolveAuthState.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAoB,MAAM,UAAU,CAAC;AAUrE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1C,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,0FAA0F;IAC1F,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,eAAe,CAAC,CA8DjE"}
@@ -91,21 +91,34 @@ async function resolveSingleUserAuthState() {
91
91
  if (!db) {
92
92
  return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
93
93
  }
94
- let config = await db.table('singleUserConfig').get('config');
95
- const isOffline = typeof navigator !== 'undefined' && !navigator.onLine;
96
- // Multi-device: if no local config but online, check Supabase
97
- if (!config && !isOffline) {
98
- config = await fetchAndCacheRemoteConfig(db);
99
- }
94
+ const config = await db.table('singleUserConfig').get('config');
100
95
  if (!config) {
96
+ // No local config — user hasn't set up on this device.
97
+ // With real email/password auth, new devices go through the login flow
98
+ // (email + PIN) which creates the local config after signInWithPassword.
99
+ return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
100
+ }
101
+ if (!config.email) {
102
+ // Legacy config from anonymous auth era — no email means user needs to
103
+ // go through the new setup flow (email + PIN). Old anonymous data won't
104
+ // be accessible under ownership-based RLS anyway.
105
+ // Nuke all legacy auth artifacts so the user gets a clean slate.
106
+ debugLog('[Auth] Legacy config without email detected, clearing old auth state');
107
+ try {
108
+ await db.table('singleUserConfig').delete('config');
109
+ await db.table('offlineCredentials').delete('current_user');
110
+ await db.table('offlineSession').delete('current_session');
111
+ }
112
+ catch (e) {
113
+ debugWarn('[Auth] Failed to clear legacy auth state:', e);
114
+ }
101
115
  return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
102
116
  }
103
117
  // Config exists — check session
104
118
  let session = await getSession();
105
119
  // If session exists but access token is expired, try refreshing before giving up.
106
- // Anonymous sessions have refresh tokens that outlive the access token.
107
- // Without this, users are forced to re-enter the PIN on every page load once
108
- // the access token expires (default: 1 hour).
120
+ // Refresh tokens outlive the access token — without this, users are forced to
121
+ // re-enter the PIN on every page load once the access token expires (default: 1 hour).
109
122
  if (session && isSessionExpired(session)) {
110
123
  debugLog('[Auth] Single-user session expired, attempting refresh...');
111
124
  try {
@@ -125,12 +138,10 @@ async function resolveSingleUserAuthState() {
125
138
  }
126
139
  const hasValidSession = session && !isSessionExpired(session);
127
140
  if (hasValidSession) {
128
- // Ensure Supabase single_user_config is populated (for existing users who
129
- // set up before the Supabase write was added, and for extension access)
130
- ensureRemoteConfig(config).catch(() => { });
131
141
  return { session, authMode: 'supabase', offlineProfile: null, singleUserSetUp: true };
132
142
  }
133
143
  // Check for offline session
144
+ const isOffline = typeof navigator !== 'undefined' && !navigator.onLine;
134
145
  if (isOffline) {
135
146
  // Even expired cached Supabase session is usable offline
136
147
  if (session) {
@@ -141,8 +152,8 @@ async function resolveSingleUserAuthState() {
141
152
  const offlineProfile = {
142
153
  id: 'current_user',
143
154
  userId: offlineSession.userId,
144
- email: '',
145
- password: config.gateHash,
155
+ email: config.email || '',
156
+ password: config.gateHash || '',
146
157
  profile: config.profile,
147
158
  cachedAt: new Date().toISOString()
148
159
  };
@@ -157,73 +168,4 @@ async function resolveSingleUserAuthState() {
157
168
  return { session: null, authMode: 'none', offlineProfile: null, singleUserSetUp: false };
158
169
  }
159
170
  }
160
- /**
161
- * Multi-device support: fetch config from Supabase and cache locally.
162
- * Called when a new device has no local config but is online.
163
- */
164
- async function fetchAndCacheRemoteConfig(db) {
165
- try {
166
- // Need a session to query — sign in anonymously
167
- const { data: sessionData } = await supabase.auth.getSession();
168
- if (!sessionData?.session) {
169
- const { error } = await supabase.auth.signInAnonymously();
170
- if (error) {
171
- debugWarn('[Auth] Anonymous sign-in failed during remote config fetch:', error.message);
172
- return null;
173
- }
174
- }
175
- const { data, error } = await supabase
176
- .from('single_user_config')
177
- .select('gate_type, code_length, gate_hash, profile')
178
- .eq('id', 'config')
179
- .single();
180
- if (error || !data)
181
- return null;
182
- const engineConfig = getEngineConfig();
183
- const singleUserOpts = engineConfig.auth?.singleUser;
184
- const config = {
185
- id: 'config',
186
- gateType: data.gate_type,
187
- codeLength: data.code_length ?? singleUserOpts?.codeLength,
188
- gateHash: data.gate_hash,
189
- profile: data.profile || {},
190
- setupAt: new Date().toISOString(),
191
- updatedAt: new Date().toISOString()
192
- };
193
- await db.table('singleUserConfig').put(config);
194
- debugLog('[Auth] Fetched remote config and cached locally (multi-device)');
195
- return config;
196
- }
197
- catch (e) {
198
- debugWarn('[Auth] Failed to fetch remote config:', e);
199
- return null;
200
- }
201
- }
202
- /**
203
- * Ensure Supabase single_user_config is populated.
204
- * Syncs from local IndexedDB if the Supabase row is missing.
205
- */
206
- async function ensureRemoteConfig(config) {
207
- try {
208
- const { data } = await supabase
209
- .from('single_user_config')
210
- .select('id')
211
- .eq('id', 'config')
212
- .single();
213
- if (data)
214
- return; // Already exists
215
- // Missing — sync from local
216
- await supabase.from('single_user_config').upsert({
217
- id: 'config',
218
- gate_type: config.gateType,
219
- code_length: config.codeLength,
220
- gate_hash: config.gateHash,
221
- profile: config.profile,
222
- });
223
- debugLog('[Auth] Synced local config to Supabase (ensureRemoteConfig)');
224
- }
225
- catch (e) {
226
- debugWarn('[Auth] Failed to ensure remote config:', e);
227
- }
228
- }
229
171
  //# sourceMappingURL=resolveAuthState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveAuthState.js","sourceRoot":"","sources":["../../src/auth/resolveAuthState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolveAuthState.js","sourceRoot":"","sources":["../../src/auth/resolveAuthState.ts"],"names":[],"mappings":"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"}