stellar-drive 1.2.22 → 1.2.24
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/dist/auth/deviceVerification.d.ts.map +1 -1
- package/dist/auth/deviceVerification.js +7 -1
- package/dist/auth/deviceVerification.js.map +1 -1
- package/dist/auth/loginGuard.d.ts +50 -10
- package/dist/auth/loginGuard.d.ts.map +1 -1
- package/dist/auth/loginGuard.js +177 -11
- package/dist/auth/loginGuard.js.map +1 -1
- package/dist/auth/offlineCredentials.d.ts.map +1 -1
- package/dist/auth/offlineCredentials.js +4 -1
- package/dist/auth/offlineCredentials.js.map +1 -1
- package/dist/auth/offlineSession.d.ts.map +1 -1
- package/dist/auth/offlineSession.js +4 -1
- package/dist/auth/offlineSession.js.map +1 -1
- package/dist/auth/singleUser.d.ts.map +1 -1
- package/dist/auth/singleUser.js +4 -3
- package/dist/auth/singleUser.js.map +1 -1
- package/dist/bin/install-pwa.d.ts.map +1 -1
- package/dist/bin/install-pwa.js +68 -9
- package/dist/bin/install-pwa.js.map +1 -1
- package/dist/deviceId.d.ts +40 -3
- package/dist/deviceId.d.ts.map +1 -1
- package/dist/deviceId.js +152 -10
- package/dist/deviceId.js.map +1 -1
- package/dist/entries/auth.d.ts +1 -1
- package/dist/entries/auth.d.ts.map +1 -1
- package/dist/entries/auth.js +1 -1
- package/dist/entries/auth.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/supabase/auth.js +2 -2
- package/dist/supabase/auth.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DemoBanner.svelte +48 -23
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviceVerification.d.ts","sourceRoot":"","sources":["../../src/auth/deviceVerification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuE9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAyBvC;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS/C;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"deviceVerification.d.ts","sourceRoot":"","sources":["../../src/auth/deviceVerification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuE9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAyBvC;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS/C;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCtE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BtE;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBtE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAoBhF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAanE;AAMD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAoC7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CA6DxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAmB3F;AAMD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
*/
|
|
55
55
|
import { getEngineConfig } from '../config';
|
|
56
56
|
import { supabase } from '../supabase/client';
|
|
57
|
-
import { getDeviceId } from '../deviceId';
|
|
57
|
+
import { getDeviceId, waitForDeviceId } from '../deviceId';
|
|
58
58
|
import { debugLog, debugWarn, debugError } from '../debug';
|
|
59
59
|
import { isDemoMode } from '../demo';
|
|
60
60
|
/** Default number of days a device remains trusted before requiring re-verification. */
|
|
@@ -225,6 +225,9 @@ export async function isDeviceTrusted(userId) {
|
|
|
225
225
|
if (isDemoMode())
|
|
226
226
|
return true;
|
|
227
227
|
try {
|
|
228
|
+
/* Ensure the IDB recovery attempt has completed so that a localStorage-
|
|
229
|
+
cleared device ID is restored before we look it up in trusted_devices. */
|
|
230
|
+
await waitForDeviceId();
|
|
228
231
|
const deviceId = getDeviceId();
|
|
229
232
|
const trustDays = getTrustDurationDays();
|
|
230
233
|
/* Calculate the cutoff date — devices not used within this window
|
|
@@ -427,6 +430,9 @@ export async function sendDeviceVerification(email) {
|
|
|
427
430
|
if (isDemoMode())
|
|
428
431
|
return { error: null };
|
|
429
432
|
try {
|
|
433
|
+
/* Ensure the IDB recovery attempt has completed so the device ID we
|
|
434
|
+
embed in user_metadata is the recovered UUID, not a fresh one. */
|
|
435
|
+
await waitForDeviceId();
|
|
430
436
|
/* Store the pending device info in user_metadata so the confirm page
|
|
431
437
|
can trust THIS device even if the link is opened on a different one.
|
|
432
438
|
This enables the cross-device verification pattern. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviceVerification.js","sourceRoot":"","sources":["../../src/auth/deviceVerification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"deviceVerification.js","sourceRoot":"","sources":["../../src/auth/deviceVerification.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,13 @@
|
|
|
6
6
|
* local hash exists (with rate limiting).
|
|
7
7
|
*
|
|
8
8
|
* Architecture:
|
|
9
|
-
* - Maintains **in-memory
|
|
10
|
-
*
|
|
9
|
+
* - Maintains **in-memory** state for fast local-hash failure counters and
|
|
10
|
+
* ephemeral backoff timers (resets on page refresh by design — these are
|
|
11
|
+
* UX-level optimisations, not security boundaries).
|
|
12
|
+
* - Maintains **persistent** lockout state in IndexedDB (`singleUserConfig`
|
|
13
|
+
* table, key `'pin_lockout'`). This survives page refreshes and tab
|
|
14
|
+
* closes, preventing brute-force attacks that rely on reloading to reset
|
|
15
|
+
* counters.
|
|
11
16
|
* - Two operational strategies:
|
|
12
17
|
* 1. `local-match`: A cached hash exists and the user's input matches it.
|
|
13
18
|
* Proceed to Supabase for authoritative verification.
|
|
@@ -17,13 +22,25 @@
|
|
|
17
22
|
* is invalidated (it may be stale from a server-side password change) and the
|
|
18
23
|
* guard falls back to rate-limited Supabase mode.
|
|
19
24
|
*
|
|
25
|
+
* ## Lockout Tiers (persistent, survives page refresh)
|
|
26
|
+
*
|
|
27
|
+
* | Total failures | Lockout duration |
|
|
28
|
+
* |---------------|-----------------|
|
|
29
|
+
* | 5 | 5 minutes |
|
|
30
|
+
* | 10 | 30 minutes |
|
|
31
|
+
* | 15 | 2 hours |
|
|
32
|
+
* | 20+ | 24 hours |
|
|
33
|
+
*
|
|
34
|
+
* Counters reset to zero after any successful Supabase authentication.
|
|
35
|
+
*
|
|
20
36
|
* Security considerations:
|
|
21
|
-
* - The guard is a **client-side
|
|
37
|
+
* - The guard is a **client-side optimisation**, not a security boundary. It
|
|
22
38
|
* reduces unnecessary network calls and provides a better UX (instant
|
|
23
39
|
* rejection for wrong passwords) but Supabase remains the authoritative
|
|
24
40
|
* verifier.
|
|
25
|
-
* -
|
|
26
|
-
*
|
|
41
|
+
* - Persistent lockout counters are stored in IndexedDB. An attacker with
|
|
42
|
+
* physical device access can clear IndexedDB, but Supabase's own server-side
|
|
43
|
+
* rate limiting is then the next line of defence.
|
|
27
44
|
* - Cached hashes are SHA-256 digests stored in IndexedDB. They are invalidated
|
|
28
45
|
* when stale-hash scenarios are detected (local match but Supabase rejects).
|
|
29
46
|
*
|
|
@@ -54,6 +71,26 @@ export type PreCheckResult = {
|
|
|
54
71
|
error: string;
|
|
55
72
|
retryAfterMs?: number;
|
|
56
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Check whether a persistent PIN lockout is currently active, without
|
|
76
|
+
* requiring the user to submit a PIN attempt.
|
|
77
|
+
*
|
|
78
|
+
* Call this on page/component mount to pre-populate the retry countdown so
|
|
79
|
+
* the UI immediately shows how long the user must wait rather than waiting
|
|
80
|
+
* for a failed submit to reveal the lockout.
|
|
81
|
+
*
|
|
82
|
+
* @returns Milliseconds remaining in the active lockout, or `0` if there is
|
|
83
|
+
* no active lockout.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* onMount(async () => {
|
|
88
|
+
* const remainingMs = await checkPersistentLockout();
|
|
89
|
+
* if (remainingMs > 0) startRetryCountdown(remainingMs);
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare function checkPersistentLockout(): Promise<number>;
|
|
57
94
|
/**
|
|
58
95
|
* Pre-check login credentials locally before calling Supabase.
|
|
59
96
|
*
|
|
@@ -85,7 +122,8 @@ export declare function preCheckLogin(input: string): Promise<PreCheckResult>;
|
|
|
85
122
|
* Called after a successful Supabase login.
|
|
86
123
|
*
|
|
87
124
|
* Resets all login guard counters (local failure count, rate-limit attempts,
|
|
88
|
-
* and the next-allowed-attempt timestamp)
|
|
125
|
+
* and the next-allowed-attempt timestamp) and clears the persistent lockout
|
|
126
|
+
* record from IndexedDB so the user starts fresh.
|
|
89
127
|
*
|
|
90
128
|
* @example
|
|
91
129
|
* ```ts
|
|
@@ -93,7 +131,7 @@ export declare function preCheckLogin(input: string): Promise<PreCheckResult>;
|
|
|
93
131
|
* if (!error) onLoginSuccess();
|
|
94
132
|
* ```
|
|
95
133
|
*/
|
|
96
|
-
export declare function onLoginSuccess(): void
|
|
134
|
+
export declare function onLoginSuccess(): Promise<void>;
|
|
97
135
|
/**
|
|
98
136
|
* Called after a failed Supabase login.
|
|
99
137
|
*
|
|
@@ -103,7 +141,9 @@ export declare function onLoginSuccess(): void;
|
|
|
103
141
|
* cached hash is **stale** (password changed server-side). The cached hash is
|
|
104
142
|
* invalidated so future attempts go through rate-limited Supabase mode.
|
|
105
143
|
* - `'no-cache'`: Increment the rate-limit counter and apply exponential
|
|
106
|
-
* backoff (base * 2^(n-1), capped at MAX_DELAY_MS).
|
|
144
|
+
* backoff (base * 2^(n-1), capped at MAX_DELAY_MS). Also increments the
|
|
145
|
+
* persistent failure counter and applies a tier-based lockout if the
|
|
146
|
+
* threshold is reached.
|
|
107
147
|
*
|
|
108
148
|
* @param strategy - The {@link PreCheckStrategy} that was returned by
|
|
109
149
|
* {@link preCheckLogin} for this attempt.
|
|
@@ -127,8 +167,8 @@ export declare function onLoginFailure(strategy: PreCheckStrategy): Promise<void
|
|
|
127
167
|
* @example
|
|
128
168
|
* ```ts
|
|
129
169
|
* await supabase.auth.signOut();
|
|
130
|
-
* resetLoginGuard();
|
|
170
|
+
* await resetLoginGuard();
|
|
131
171
|
* ```
|
|
132
172
|
*/
|
|
133
|
-
export declare function resetLoginGuard(): void
|
|
173
|
+
export declare function resetLoginGuard(): Promise<void>;
|
|
134
174
|
//# sourceMappingURL=loginGuard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loginGuard.d.ts","sourceRoot":"","sources":["../../src/auth/loginGuard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loginGuard.d.ts","sourceRoot":"","sources":["../../src/auth/loginGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAoEH;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,UAAU,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GAC7C;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AA4H7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAQ9D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAuF1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAYpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC9E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAWrD"}
|
package/dist/auth/loginGuard.js
CHANGED
|
@@ -6,8 +6,13 @@
|
|
|
6
6
|
* local hash exists (with rate limiting).
|
|
7
7
|
*
|
|
8
8
|
* Architecture:
|
|
9
|
-
* - Maintains **in-memory
|
|
10
|
-
*
|
|
9
|
+
* - Maintains **in-memory** state for fast local-hash failure counters and
|
|
10
|
+
* ephemeral backoff timers (resets on page refresh by design — these are
|
|
11
|
+
* UX-level optimisations, not security boundaries).
|
|
12
|
+
* - Maintains **persistent** lockout state in IndexedDB (`singleUserConfig`
|
|
13
|
+
* table, key `'pin_lockout'`). This survives page refreshes and tab
|
|
14
|
+
* closes, preventing brute-force attacks that rely on reloading to reset
|
|
15
|
+
* counters.
|
|
11
16
|
* - Two operational strategies:
|
|
12
17
|
* 1. `local-match`: A cached hash exists and the user's input matches it.
|
|
13
18
|
* Proceed to Supabase for authoritative verification.
|
|
@@ -17,20 +22,32 @@
|
|
|
17
22
|
* is invalidated (it may be stale from a server-side password change) and the
|
|
18
23
|
* guard falls back to rate-limited Supabase mode.
|
|
19
24
|
*
|
|
25
|
+
* ## Lockout Tiers (persistent, survives page refresh)
|
|
26
|
+
*
|
|
27
|
+
* | Total failures | Lockout duration |
|
|
28
|
+
* |---------------|-----------------|
|
|
29
|
+
* | 5 | 5 minutes |
|
|
30
|
+
* | 10 | 30 minutes |
|
|
31
|
+
* | 15 | 2 hours |
|
|
32
|
+
* | 20+ | 24 hours |
|
|
33
|
+
*
|
|
34
|
+
* Counters reset to zero after any successful Supabase authentication.
|
|
35
|
+
*
|
|
20
36
|
* Security considerations:
|
|
21
|
-
* - The guard is a **client-side
|
|
37
|
+
* - The guard is a **client-side optimisation**, not a security boundary. It
|
|
22
38
|
* reduces unnecessary network calls and provides a better UX (instant
|
|
23
39
|
* rejection for wrong passwords) but Supabase remains the authoritative
|
|
24
40
|
* verifier.
|
|
25
|
-
* -
|
|
26
|
-
*
|
|
41
|
+
* - Persistent lockout counters are stored in IndexedDB. An attacker with
|
|
42
|
+
* physical device access can clear IndexedDB, but Supabase's own server-side
|
|
43
|
+
* rate limiting is then the next line of defence.
|
|
27
44
|
* - Cached hashes are SHA-256 digests stored in IndexedDB. They are invalidated
|
|
28
45
|
* when stale-hash scenarios are detected (local match but Supabase rejects).
|
|
29
46
|
*
|
|
30
47
|
* @module auth/loginGuard
|
|
31
48
|
*/
|
|
32
49
|
import { hashValue } from './crypto';
|
|
33
|
-
import { getEngineConfig } from '../config';
|
|
50
|
+
import { getEngineConfig, waitForDb } from '../config';
|
|
34
51
|
import { debugLog, debugWarn } from '../debug';
|
|
35
52
|
// =============================================================================
|
|
36
53
|
// CONSTANTS
|
|
@@ -46,6 +63,21 @@ const BASE_DELAY_MS = 1000;
|
|
|
46
63
|
const MAX_DELAY_MS = 30000;
|
|
47
64
|
/** Multiplier for exponential backoff between rate-limited attempts. */
|
|
48
65
|
const BACKOFF_MULTIPLIER = 2;
|
|
66
|
+
/**
|
|
67
|
+
* Progressive persistent-lockout tiers.
|
|
68
|
+
*
|
|
69
|
+
* After `failures` total failed Supabase login attempts (across page
|
|
70
|
+
* refreshes), the user is locked out for `durationMs` milliseconds.
|
|
71
|
+
* The tiers are checked in order — the **highest** matching tier wins.
|
|
72
|
+
*/
|
|
73
|
+
const PERSISTENT_LOCKOUT_TIERS = [
|
|
74
|
+
{ failures: 5, durationMs: 5 * 60000 }, // 5 min after 5 failures
|
|
75
|
+
{ failures: 10, durationMs: 30 * 60000 }, // 30 min after 10 failures
|
|
76
|
+
{ failures: 15, durationMs: 2 * 60 * 60000 }, // 2 hr after 15 failures
|
|
77
|
+
{ failures: 20, durationMs: 24 * 60 * 60000 } // 24 hr after 20+ failures
|
|
78
|
+
];
|
|
79
|
+
/** IndexedDB record key for the persistent lockout state. */
|
|
80
|
+
const PIN_LOCKOUT_KEY = 'pin_lockout';
|
|
49
81
|
// =============================================================================
|
|
50
82
|
// IN-MEMORY STATE
|
|
51
83
|
// =============================================================================
|
|
@@ -108,9 +140,93 @@ async function invalidateCachedHash() {
|
|
|
108
140
|
debugWarn('[LoginGuard] Failed to invalidate cached hash:', e);
|
|
109
141
|
}
|
|
110
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Read the persistent lockout record from IndexedDB.
|
|
145
|
+
*
|
|
146
|
+
* Returns a zeroed default record when none exists or on any read error.
|
|
147
|
+
*/
|
|
148
|
+
async function readPersistentLockout() {
|
|
149
|
+
const zero = {
|
|
150
|
+
id: PIN_LOCKOUT_KEY,
|
|
151
|
+
failureCount: 0,
|
|
152
|
+
lockoutUntil: 0,
|
|
153
|
+
updatedAt: new Date().toISOString()
|
|
154
|
+
};
|
|
155
|
+
try {
|
|
156
|
+
await waitForDb();
|
|
157
|
+
const db = getEngineConfig().db;
|
|
158
|
+
if (!db)
|
|
159
|
+
return zero;
|
|
160
|
+
const record = await db.table('singleUserConfig').get(PIN_LOCKOUT_KEY);
|
|
161
|
+
return record ?? zero;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return zero;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Write a persistent lockout record to IndexedDB.
|
|
169
|
+
*
|
|
170
|
+
* Errors are swallowed — a failed write degrades gracefully to in-memory-only
|
|
171
|
+
* protection; Supabase server-side limits remain the primary defence.
|
|
172
|
+
*/
|
|
173
|
+
async function writePersistentLockout(record) {
|
|
174
|
+
try {
|
|
175
|
+
const db = getEngineConfig().db;
|
|
176
|
+
if (db) {
|
|
177
|
+
await db.table('singleUserConfig').put(record);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
debugWarn('[LoginGuard] Failed to write persistent lockout:', e);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Compute the lockout duration for a given failure count.
|
|
186
|
+
*
|
|
187
|
+
* Returns 0 when the count has not yet reached the first tier.
|
|
188
|
+
*/
|
|
189
|
+
function getLockoutDurationMs(failureCount) {
|
|
190
|
+
let duration = 0;
|
|
191
|
+
for (const tier of PERSISTENT_LOCKOUT_TIERS) {
|
|
192
|
+
if (failureCount >= tier.failures) {
|
|
193
|
+
duration = tier.durationMs;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return duration;
|
|
197
|
+
}
|
|
111
198
|
// =============================================================================
|
|
112
199
|
// PUBLIC API
|
|
113
200
|
// =============================================================================
|
|
201
|
+
/**
|
|
202
|
+
* Check whether a persistent PIN lockout is currently active, without
|
|
203
|
+
* requiring the user to submit a PIN attempt.
|
|
204
|
+
*
|
|
205
|
+
* Call this on page/component mount to pre-populate the retry countdown so
|
|
206
|
+
* the UI immediately shows how long the user must wait rather than waiting
|
|
207
|
+
* for a failed submit to reveal the lockout.
|
|
208
|
+
*
|
|
209
|
+
* @returns Milliseconds remaining in the active lockout, or `0` if there is
|
|
210
|
+
* no active lockout.
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* onMount(async () => {
|
|
215
|
+
* const remainingMs = await checkPersistentLockout();
|
|
216
|
+
* if (remainingMs > 0) startRetryCountdown(remainingMs);
|
|
217
|
+
* });
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
export async function checkPersistentLockout() {
|
|
221
|
+
try {
|
|
222
|
+
const record = await readPersistentLockout();
|
|
223
|
+
const remaining = record.lockoutUntil - Date.now();
|
|
224
|
+
return remaining > 0 ? remaining : 0;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
114
230
|
/**
|
|
115
231
|
* Pre-check login credentials locally before calling Supabase.
|
|
116
232
|
*
|
|
@@ -139,6 +255,20 @@ async function invalidateCachedHash() {
|
|
|
139
255
|
*/
|
|
140
256
|
export async function preCheckLogin(input) {
|
|
141
257
|
try {
|
|
258
|
+
/* ── Persistent lockout check (survives page refresh) ── */
|
|
259
|
+
const lockoutRecord = await readPersistentLockout();
|
|
260
|
+
const persistentRemaining = lockoutRecord.lockoutUntil - Date.now();
|
|
261
|
+
if (persistentRemaining > 0) {
|
|
262
|
+
const mins = Math.ceil(persistentRemaining / 60000);
|
|
263
|
+
const timeDesc = persistentRemaining >= 60 * 60000
|
|
264
|
+
? `${Math.ceil(persistentRemaining / (60 * 60000))} hour${Math.ceil(persistentRemaining / (60 * 60000)) !== 1 ? 's' : ''}`
|
|
265
|
+
: `${mins} minute${mins !== 1 ? 's' : ''}`;
|
|
266
|
+
return {
|
|
267
|
+
proceed: false,
|
|
268
|
+
error: `Too many failed attempts. Please wait ${timeDesc} before trying again.`,
|
|
269
|
+
retryAfterMs: persistentRemaining
|
|
270
|
+
};
|
|
271
|
+
}
|
|
142
272
|
let cachedHash;
|
|
143
273
|
const config = getEngineConfig();
|
|
144
274
|
const db = config.db;
|
|
@@ -202,7 +332,8 @@ export async function preCheckLogin(input) {
|
|
|
202
332
|
* Called after a successful Supabase login.
|
|
203
333
|
*
|
|
204
334
|
* Resets all login guard counters (local failure count, rate-limit attempts,
|
|
205
|
-
* and the next-allowed-attempt timestamp)
|
|
335
|
+
* and the next-allowed-attempt timestamp) and clears the persistent lockout
|
|
336
|
+
* record from IndexedDB so the user starts fresh.
|
|
206
337
|
*
|
|
207
338
|
* @example
|
|
208
339
|
* ```ts
|
|
@@ -210,10 +341,17 @@ export async function preCheckLogin(input) {
|
|
|
210
341
|
* if (!error) onLoginSuccess();
|
|
211
342
|
* ```
|
|
212
343
|
*/
|
|
213
|
-
export function onLoginSuccess() {
|
|
344
|
+
export async function onLoginSuccess() {
|
|
214
345
|
consecutiveLocalFailures = 0;
|
|
215
346
|
rateLimitAttempts = 0;
|
|
216
347
|
nextAllowedAttempt = 0;
|
|
348
|
+
/* Clear persistent failure counter and lockout */
|
|
349
|
+
await writePersistentLockout({
|
|
350
|
+
id: PIN_LOCKOUT_KEY,
|
|
351
|
+
failureCount: 0,
|
|
352
|
+
lockoutUntil: 0,
|
|
353
|
+
updatedAt: new Date().toISOString()
|
|
354
|
+
});
|
|
217
355
|
debugLog('[LoginGuard] Login success, counters reset');
|
|
218
356
|
}
|
|
219
357
|
/**
|
|
@@ -225,7 +363,9 @@ export function onLoginSuccess() {
|
|
|
225
363
|
* cached hash is **stale** (password changed server-side). The cached hash is
|
|
226
364
|
* invalidated so future attempts go through rate-limited Supabase mode.
|
|
227
365
|
* - `'no-cache'`: Increment the rate-limit counter and apply exponential
|
|
228
|
-
* backoff (base * 2^(n-1), capped at MAX_DELAY_MS).
|
|
366
|
+
* backoff (base * 2^(n-1), capped at MAX_DELAY_MS). Also increments the
|
|
367
|
+
* persistent failure counter and applies a tier-based lockout if the
|
|
368
|
+
* threshold is reached.
|
|
229
369
|
*
|
|
230
370
|
* @param strategy - The {@link PreCheckStrategy} that was returned by
|
|
231
371
|
* {@link preCheckLogin} for this attempt.
|
|
@@ -253,6 +393,26 @@ export async function onLoginFailure(strategy) {
|
|
|
253
393
|
const delay = Math.min(BASE_DELAY_MS * Math.pow(BACKOFF_MULTIPLIER, rateLimitAttempts - 1), MAX_DELAY_MS);
|
|
254
394
|
nextAllowedAttempt = Date.now() + delay;
|
|
255
395
|
debugWarn(`[LoginGuard] Rate limit applied: ${delay}ms delay (attempt ${rateLimitAttempts})`);
|
|
396
|
+
/* Update persistent failure counter and apply tier-based lockout. */
|
|
397
|
+
try {
|
|
398
|
+
const record = await readPersistentLockout();
|
|
399
|
+
const newCount = record.failureCount + 1;
|
|
400
|
+
const lockoutDuration = getLockoutDurationMs(newCount);
|
|
401
|
+
const lockoutUntil = lockoutDuration > 0 ? Date.now() + lockoutDuration : 0;
|
|
402
|
+
if (lockoutUntil > 0) {
|
|
403
|
+
const mins = Math.ceil(lockoutDuration / 60000);
|
|
404
|
+
debugWarn(`[LoginGuard] Persistent lockout applied: ${mins} min (${newCount} total failures)`);
|
|
405
|
+
}
|
|
406
|
+
await writePersistentLockout({
|
|
407
|
+
id: PIN_LOCKOUT_KEY,
|
|
408
|
+
failureCount: newCount,
|
|
409
|
+
lockoutUntil,
|
|
410
|
+
updatedAt: new Date().toISOString()
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
catch (e) {
|
|
414
|
+
debugWarn('[LoginGuard] Failed to update persistent lockout:', e);
|
|
415
|
+
}
|
|
256
416
|
}
|
|
257
417
|
}
|
|
258
418
|
/**
|
|
@@ -264,13 +424,19 @@ export async function onLoginFailure(strategy) {
|
|
|
264
424
|
* @example
|
|
265
425
|
* ```ts
|
|
266
426
|
* await supabase.auth.signOut();
|
|
267
|
-
* resetLoginGuard();
|
|
427
|
+
* await resetLoginGuard();
|
|
268
428
|
* ```
|
|
269
429
|
*/
|
|
270
|
-
export function resetLoginGuard() {
|
|
430
|
+
export async function resetLoginGuard() {
|
|
271
431
|
consecutiveLocalFailures = 0;
|
|
272
432
|
rateLimitAttempts = 0;
|
|
273
433
|
nextAllowedAttempt = 0;
|
|
434
|
+
await writePersistentLockout({
|
|
435
|
+
id: PIN_LOCKOUT_KEY,
|
|
436
|
+
failureCount: 0,
|
|
437
|
+
lockoutUntil: 0,
|
|
438
|
+
updatedAt: new Date().toISOString()
|
|
439
|
+
});
|
|
274
440
|
debugLog('[LoginGuard] Guard reset');
|
|
275
441
|
}
|
|
276
442
|
//# sourceMappingURL=loginGuard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loginGuard.js","sourceRoot":"","sources":["../../src/auth/loginGuard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loginGuard.js","sourceRoot":"","sources":["../../src/auth/loginGuard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offlineCredentials.d.ts","sourceRoot":"","sources":["../../src/auth/offlineCredentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAmB3D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"offlineCredentials.d.ts","sourceRoot":"","sources":["../../src/auth/offlineCredentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAmB3D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAShF;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAI7D"}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
*
|
|
25
25
|
* @module auth/offlineCredentials
|
|
26
26
|
*/
|
|
27
|
-
import { getEngineConfig } from '../config';
|
|
27
|
+
import { getEngineConfig, waitForDb } from '../config';
|
|
28
28
|
import { debugError } from '../debug';
|
|
29
29
|
import { hashValue } from './crypto';
|
|
30
30
|
// =============================================================================
|
|
@@ -73,6 +73,7 @@ export async function cacheOfflineCredentials(email, password, user, _session) {
|
|
|
73
73
|
debugError('[Auth] Cannot cache credentials: email or password is empty');
|
|
74
74
|
throw new Error('Cannot cache credentials: email or password is empty');
|
|
75
75
|
}
|
|
76
|
+
await waitForDb();
|
|
76
77
|
const config = getEngineConfig();
|
|
77
78
|
const db = config.db;
|
|
78
79
|
/* Extract a normalized profile using the host app's profileExtractor,
|
|
@@ -120,6 +121,7 @@ export async function cacheOfflineCredentials(email, password, user, _session) {
|
|
|
120
121
|
* ```
|
|
121
122
|
*/
|
|
122
123
|
export async function getOfflineCredentials() {
|
|
124
|
+
await waitForDb();
|
|
123
125
|
const db = getEngineConfig().db;
|
|
124
126
|
const credentials = await db.table('offlineCredentials').get(CREDENTIALS_ID);
|
|
125
127
|
if (!credentials) {
|
|
@@ -170,6 +172,7 @@ export async function updateOfflineCredentialsProfile(profile) {
|
|
|
170
172
|
* @see {@link cacheOfflineCredentials} for storing credentials on login.
|
|
171
173
|
*/
|
|
172
174
|
export async function clearOfflineCredentials() {
|
|
175
|
+
await waitForDb();
|
|
173
176
|
const db = getEngineConfig().db;
|
|
174
177
|
await db.table('offlineCredentials').delete(CREDENTIALS_ID);
|
|
175
178
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offlineCredentials.js","sourceRoot":"","sources":["../../src/auth/offlineCredentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"offlineCredentials.js","sourceRoot":"","sources":["../../src/auth/offlineCredentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offlineSession.d.ts","sourceRoot":"","sources":["../../src/auth/offlineSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAgB/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"offlineSession.d.ts","sourceRoot":"","sources":["../../src/auth/offlineSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAgB/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAwBlF;AAkBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAE7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAIzD"}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*
|
|
28
28
|
* @module auth/offlineSession
|
|
29
29
|
*/
|
|
30
|
-
import { getEngineConfig } from '../config';
|
|
30
|
+
import { getEngineConfig, waitForDb } from '../config';
|
|
31
31
|
// =============================================================================
|
|
32
32
|
// CONSTANTS
|
|
33
33
|
// =============================================================================
|
|
@@ -66,6 +66,7 @@ const SESSION_ID = 'current_session';
|
|
|
66
66
|
* @see {@link clearOfflineSession} to revoke the session on logout.
|
|
67
67
|
*/
|
|
68
68
|
export async function createOfflineSession(userId) {
|
|
69
|
+
await waitForDb();
|
|
69
70
|
const now = new Date();
|
|
70
71
|
const db = getEngineConfig().db;
|
|
71
72
|
const session = {
|
|
@@ -95,6 +96,7 @@ export async function createOfflineSession(userId) {
|
|
|
95
96
|
* @returns The current offline session, or `null` if none exists.
|
|
96
97
|
*/
|
|
97
98
|
async function getOfflineSession() {
|
|
99
|
+
await waitForDb();
|
|
98
100
|
const db = getEngineConfig().db;
|
|
99
101
|
const session = await db.table('offlineSession').get(SESSION_ID);
|
|
100
102
|
return session || null;
|
|
@@ -139,6 +141,7 @@ export async function getValidOfflineSession() {
|
|
|
139
141
|
* @see {@link createOfflineSession} for session creation.
|
|
140
142
|
*/
|
|
141
143
|
export async function clearOfflineSession() {
|
|
144
|
+
await waitForDb();
|
|
142
145
|
const db = getEngineConfig().db;
|
|
143
146
|
await db.table('offlineSession').delete(SESSION_ID);
|
|
144
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offlineSession.js","sourceRoot":"","sources":["../../src/auth/offlineSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"offlineSession.js","sourceRoot":"","sources":["../../src/auth/offlineSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGvD,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAErC,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAc;IACvD,MAAM,SAAS,EAAE,CAAC;IAClB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC,EAAG,CAAC;IAEjC,MAAM,OAAO,GAAmB;QAC9B,EAAE,EAAE,UAAU;QACd,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE;QACjC,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE;KAC7B,CAAC;IAEF,gEAAgE;IAChE,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAE9C;;oEAEgE;IAChE,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,iBAAiB;IAC9B,MAAM,SAAS,EAAE,CAAC;IAClB,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC,EAAG,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACjE,OAAO,OAAO,IAAI,IAAI,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,OAAO,MAAM,iBAAiB,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,SAAS,EAAE,CAAC;IAClB,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC,EAAG,CAAC;IACjC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleUser.d.ts","sourceRoot":"","sources":["../../src/auth/singleUser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAwCjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C;
|
|
1
|
+
{"version":3,"file":"singleUser.d.ts","sourceRoot":"","sources":["../../src/auth/singleUser.ts"],"names":[],"mappings":"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"}
|