@prabhask5/stellar-engine 1.1.7 → 1.1.9

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.
Files changed (191) hide show
  1. package/README.md +12 -18
  2. package/dist/actions/remoteChange.d.ts +143 -18
  3. package/dist/actions/remoteChange.d.ts.map +1 -1
  4. package/dist/actions/remoteChange.js +182 -58
  5. package/dist/actions/remoteChange.js.map +1 -1
  6. package/dist/actions/truncateTooltip.d.ts +26 -12
  7. package/dist/actions/truncateTooltip.d.ts.map +1 -1
  8. package/dist/actions/truncateTooltip.js +89 -34
  9. package/dist/actions/truncateTooltip.js.map +1 -1
  10. package/dist/auth/crypto.d.ts +35 -8
  11. package/dist/auth/crypto.d.ts.map +1 -1
  12. package/dist/auth/crypto.js +38 -10
  13. package/dist/auth/crypto.js.map +1 -1
  14. package/dist/auth/deviceVerification.d.ts +236 -20
  15. package/dist/auth/deviceVerification.d.ts.map +1 -1
  16. package/dist/auth/deviceVerification.js +293 -40
  17. package/dist/auth/deviceVerification.js.map +1 -1
  18. package/dist/auth/displayUtils.d.ts +98 -0
  19. package/dist/auth/displayUtils.d.ts.map +1 -0
  20. package/dist/auth/displayUtils.js +133 -0
  21. package/dist/auth/displayUtils.js.map +1 -0
  22. package/dist/auth/loginGuard.d.ts +103 -16
  23. package/dist/auth/loginGuard.d.ts.map +1 -1
  24. package/dist/auth/loginGuard.js +163 -76
  25. package/dist/auth/loginGuard.js.map +1 -1
  26. package/dist/auth/offlineCredentials.d.ts +88 -24
  27. package/dist/auth/offlineCredentials.d.ts.map +1 -1
  28. package/dist/auth/offlineCredentials.js +114 -73
  29. package/dist/auth/offlineCredentials.js.map +1 -1
  30. package/dist/auth/offlineSession.d.ts +83 -9
  31. package/dist/auth/offlineSession.d.ts.map +1 -1
  32. package/dist/auth/offlineSession.js +104 -13
  33. package/dist/auth/offlineSession.js.map +1 -1
  34. package/dist/auth/resolveAuthState.d.ts +67 -9
  35. package/dist/auth/resolveAuthState.d.ts.map +1 -1
  36. package/dist/auth/resolveAuthState.js +125 -71
  37. package/dist/auth/resolveAuthState.js.map +1 -1
  38. package/dist/auth/singleUser.d.ts +390 -37
  39. package/dist/auth/singleUser.d.ts.map +1 -1
  40. package/dist/auth/singleUser.js +504 -103
  41. package/dist/auth/singleUser.js.map +1 -1
  42. package/dist/bin/install-pwa.d.ts +18 -2
  43. package/dist/bin/install-pwa.d.ts.map +1 -1
  44. package/dist/bin/install-pwa.js +2624 -77
  45. package/dist/bin/install-pwa.js.map +1 -1
  46. package/dist/config.d.ts +131 -15
  47. package/dist/config.d.ts.map +1 -1
  48. package/dist/config.js +87 -9
  49. package/dist/config.js.map +1 -1
  50. package/dist/conflicts.d.ts +246 -23
  51. package/dist/conflicts.d.ts.map +1 -1
  52. package/dist/conflicts.js +495 -46
  53. package/dist/conflicts.js.map +1 -1
  54. package/dist/data.d.ts +338 -18
  55. package/dist/data.d.ts.map +1 -1
  56. package/dist/data.js +385 -34
  57. package/dist/data.js.map +1 -1
  58. package/dist/database.d.ts +72 -14
  59. package/dist/database.d.ts.map +1 -1
  60. package/dist/database.js +120 -29
  61. package/dist/database.js.map +1 -1
  62. package/dist/debug.d.ts +77 -1
  63. package/dist/debug.d.ts.map +1 -1
  64. package/dist/debug.js +88 -1
  65. package/dist/debug.js.map +1 -1
  66. package/dist/deviceId.d.ts +38 -7
  67. package/dist/deviceId.d.ts.map +1 -1
  68. package/dist/deviceId.js +68 -10
  69. package/dist/deviceId.js.map +1 -1
  70. package/dist/engine.d.ts +175 -3
  71. package/dist/engine.d.ts.map +1 -1
  72. package/dist/engine.js +756 -109
  73. package/dist/engine.js.map +1 -1
  74. package/dist/entries/actions.d.ts +13 -0
  75. package/dist/entries/actions.d.ts.map +1 -1
  76. package/dist/entries/actions.js +26 -1
  77. package/dist/entries/actions.js.map +1 -1
  78. package/dist/entries/auth.d.ts +15 -4
  79. package/dist/entries/auth.d.ts.map +1 -1
  80. package/dist/entries/auth.js +47 -4
  81. package/dist/entries/auth.js.map +1 -1
  82. package/dist/entries/config.d.ts +12 -0
  83. package/dist/entries/config.d.ts.map +1 -1
  84. package/dist/entries/config.js +18 -1
  85. package/dist/entries/config.js.map +1 -1
  86. package/dist/entries/kit.d.ts +11 -0
  87. package/dist/entries/kit.d.ts.map +1 -1
  88. package/dist/entries/kit.js +52 -2
  89. package/dist/entries/kit.js.map +1 -1
  90. package/dist/entries/stores.d.ts +11 -0
  91. package/dist/entries/stores.d.ts.map +1 -1
  92. package/dist/entries/stores.js +43 -2
  93. package/dist/entries/stores.js.map +1 -1
  94. package/dist/entries/types.d.ts +10 -1
  95. package/dist/entries/types.d.ts.map +1 -1
  96. package/dist/entries/types.js +10 -0
  97. package/dist/entries/types.js.map +1 -1
  98. package/dist/entries/utils.d.ts +6 -0
  99. package/dist/entries/utils.d.ts.map +1 -1
  100. package/dist/entries/utils.js +22 -1
  101. package/dist/entries/utils.js.map +1 -1
  102. package/dist/entries/vite.d.ts +17 -0
  103. package/dist/entries/vite.d.ts.map +1 -1
  104. package/dist/entries/vite.js +24 -1
  105. package/dist/entries/vite.js.map +1 -1
  106. package/dist/index.d.ts +32 -4
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +166 -23
  109. package/dist/index.js.map +1 -1
  110. package/dist/kit/auth.d.ts +60 -5
  111. package/dist/kit/auth.d.ts.map +1 -1
  112. package/dist/kit/auth.js +45 -4
  113. package/dist/kit/auth.js.map +1 -1
  114. package/dist/kit/confirm.d.ts +93 -12
  115. package/dist/kit/confirm.d.ts.map +1 -1
  116. package/dist/kit/confirm.js +103 -16
  117. package/dist/kit/confirm.js.map +1 -1
  118. package/dist/kit/loads.d.ts +148 -23
  119. package/dist/kit/loads.d.ts.map +1 -1
  120. package/dist/kit/loads.js +136 -28
  121. package/dist/kit/loads.js.map +1 -1
  122. package/dist/kit/server.d.ts +142 -10
  123. package/dist/kit/server.d.ts.map +1 -1
  124. package/dist/kit/server.js +158 -15
  125. package/dist/kit/server.js.map +1 -1
  126. package/dist/kit/sw.d.ts +152 -23
  127. package/dist/kit/sw.d.ts.map +1 -1
  128. package/dist/kit/sw.js +182 -26
  129. package/dist/kit/sw.js.map +1 -1
  130. package/dist/queue.d.ts +274 -0
  131. package/dist/queue.d.ts.map +1 -1
  132. package/dist/queue.js +556 -38
  133. package/dist/queue.js.map +1 -1
  134. package/dist/realtime.d.ts +241 -27
  135. package/dist/realtime.d.ts.map +1 -1
  136. package/dist/realtime.js +633 -109
  137. package/dist/realtime.js.map +1 -1
  138. package/dist/runtime/runtimeConfig.d.ts +91 -8
  139. package/dist/runtime/runtimeConfig.d.ts.map +1 -1
  140. package/dist/runtime/runtimeConfig.js +146 -19
  141. package/dist/runtime/runtimeConfig.js.map +1 -1
  142. package/dist/stores/authState.d.ts +150 -11
  143. package/dist/stores/authState.d.ts.map +1 -1
  144. package/dist/stores/authState.js +169 -17
  145. package/dist/stores/authState.js.map +1 -1
  146. package/dist/stores/network.d.ts +39 -0
  147. package/dist/stores/network.d.ts.map +1 -1
  148. package/dist/stores/network.js +169 -16
  149. package/dist/stores/network.js.map +1 -1
  150. package/dist/stores/remoteChanges.d.ts +327 -52
  151. package/dist/stores/remoteChanges.d.ts.map +1 -1
  152. package/dist/stores/remoteChanges.js +337 -75
  153. package/dist/stores/remoteChanges.js.map +1 -1
  154. package/dist/stores/sync.d.ts +130 -0
  155. package/dist/stores/sync.d.ts.map +1 -1
  156. package/dist/stores/sync.js +167 -7
  157. package/dist/stores/sync.js.map +1 -1
  158. package/dist/supabase/auth.d.ts +186 -46
  159. package/dist/supabase/auth.d.ts.map +1 -1
  160. package/dist/supabase/auth.js +238 -190
  161. package/dist/supabase/auth.js.map +1 -1
  162. package/dist/supabase/client.d.ts +79 -6
  163. package/dist/supabase/client.d.ts.map +1 -1
  164. package/dist/supabase/client.js +158 -15
  165. package/dist/supabase/client.js.map +1 -1
  166. package/dist/supabase/validate.d.ts +101 -7
  167. package/dist/supabase/validate.d.ts.map +1 -1
  168. package/dist/supabase/validate.js +117 -8
  169. package/dist/supabase/validate.js.map +1 -1
  170. package/dist/sw/build/vite-plugin.d.ts +55 -10
  171. package/dist/sw/build/vite-plugin.d.ts.map +1 -1
  172. package/dist/sw/build/vite-plugin.js +77 -18
  173. package/dist/sw/build/vite-plugin.js.map +1 -1
  174. package/dist/sw/sw.js +99 -44
  175. package/dist/types.d.ts +150 -26
  176. package/dist/types.d.ts.map +1 -1
  177. package/dist/types.js +12 -10
  178. package/dist/types.js.map +1 -1
  179. package/dist/utils.d.ts +55 -13
  180. package/dist/utils.d.ts.map +1 -1
  181. package/dist/utils.js +83 -22
  182. package/dist/utils.js.map +1 -1
  183. package/package.json +1 -1
  184. package/dist/auth/admin.d.ts +0 -12
  185. package/dist/auth/admin.d.ts.map +0 -1
  186. package/dist/auth/admin.js +0 -26
  187. package/dist/auth/admin.js.map +0 -1
  188. package/dist/auth/offlineLogin.d.ts +0 -34
  189. package/dist/auth/offlineLogin.d.ts.map +0 -1
  190. package/dist/auth/offlineLogin.js +0 -75
  191. package/dist/auth/offlineLogin.js.map +0 -1
@@ -1,15 +1,60 @@
1
+ /**
2
+ * @fileoverview Supabase Authentication Module
3
+ *
4
+ * Provides core authentication utilities on top of Supabase Auth for the
5
+ * single-user PIN/password gate system:
6
+ *
7
+ * - **Sign-out & teardown**: Full 10-step teardown sequence to ensure no stale
8
+ * data leaks across sessions.
9
+ *
10
+ * - **Session management**: `getSession()` falls back to localStorage when the
11
+ * device is offline, ensuring the app can still render authenticated views
12
+ * with stale-but-usable session data.
13
+ *
14
+ * - **Profile CRUD**: Read and update user profile metadata on Supabase and
15
+ * in the offline credential cache.
16
+ *
17
+ * - **Email confirmation & OTP**: Resend confirmation emails and verify OTP
18
+ * token hashes from confirmation links.
19
+ *
20
+ * Security considerations:
21
+ * - Corrupted sessions are detected and automatically cleared to prevent
22
+ * infinite error loops.
23
+ * - Sign-out follows a strict 10-step teardown sequence to ensure no stale
24
+ * data leaks across user boundaries.
25
+ *
26
+ * Integration patterns:
27
+ * - Used internally by single-user auth (`../auth/singleUser.ts`) and the
28
+ * scaffolded confirm page (`../kit/confirm.ts`).
29
+ * - Works in tandem with `./client.ts` (lazy Supabase singleton) and
30
+ * `../engine.ts` (sync engine lifecycle).
31
+ * - Offline credential helpers live in `../auth/offlineCredentials.ts`.
32
+ *
33
+ * @module supabase/auth
34
+ */
1
35
  import { supabase } from './client';
2
- import { cacheOfflineCredentials, clearOfflineCredentials, getOfflineCredentials, updateOfflineCredentialsPassword, updateOfflineCredentialsProfile } from '../auth/offlineCredentials';
36
+ import { clearOfflineCredentials, updateOfflineCredentialsProfile } from '../auth/offlineCredentials';
3
37
  import { clearOfflineSession } from '../auth/offlineSession';
4
- import { preCheckLogin, onLoginSuccess, onLoginFailure, resetLoginGuard } from '../auth/loginGuard';
5
- import { hashValue, isAlreadyHashed } from '../auth/crypto';
38
+ import { resetLoginGuard } from '../auth/loginGuard';
6
39
  import { debugWarn, debugError } from '../debug';
7
40
  import { getEngineConfig } from '../config';
8
41
  import { syncStatusStore } from '../stores/sync';
9
42
  import { authState } from '../stores/authState';
43
+ // =============================================================================
44
+ // SECTION: Helpers
45
+ // =============================================================================
10
46
  /**
11
- * Get the email confirmation redirect URL
12
- * Points to /confirm page which handles the token verification
47
+ * Get the email confirmation redirect URL.
48
+ *
49
+ * Points to the `/confirm` page (or the path configured via
50
+ * `auth.confirmRedirectPath`) which handles the token verification flow
51
+ * after a user clicks the link in their confirmation email.
52
+ *
53
+ * @returns The fully-qualified redirect URL, e.g. `https://app.example.com/confirm`.
54
+ * Falls back to a relative `/confirm` path in SSR environments where
55
+ * `window` is unavailable.
56
+ *
57
+ * @see {@link resendConfirmationEmail} — uses this URL
13
58
  */
14
59
  function getConfirmRedirectUrl() {
15
60
  if (typeof window !== 'undefined') {
@@ -19,81 +64,42 @@ function getConfirmRedirectUrl() {
19
64
  // Fallback for SSR (shouldn't be called, but just in case)
20
65
  return '/confirm';
21
66
  }
22
- export async function signIn(email, password) {
23
- // Pre-check credentials locally before calling Supabase
24
- const preCheck = await preCheckLogin(password, 'multi-user', email);
25
- if (!preCheck.proceed) {
26
- return {
27
- user: null,
28
- session: null,
29
- error: preCheck.error,
30
- retryAfterMs: preCheck.retryAfterMs
31
- };
32
- }
33
- const strategy = preCheck.strategy;
34
- const { data, error } = await supabase.auth.signInWithPassword({
35
- email,
36
- password
37
- });
38
- if (error) {
39
- await onLoginFailure(strategy, 'multi-user');
40
- return { user: data.user, session: data.session, error: error.message };
41
- }
42
- // Successful Supabase login
43
- onLoginSuccess();
44
- // Cache credentials for offline use on successful login
45
- if (data.session && data.user) {
46
- try {
47
- await cacheOfflineCredentials(email, password, data.user, data.session);
48
- }
49
- catch (e) {
50
- debugError('[Auth] Failed to cache offline credentials:', e);
51
- }
52
- // Check device verification for multi-user mode
53
- const config = getEngineConfig();
54
- if (config.auth?.deviceVerification?.enabled) {
55
- const { isDeviceTrusted, touchTrustedDevice, sendDeviceVerification, maskEmail } = await import('../auth/deviceVerification');
56
- const trusted = await isDeviceTrusted(data.user.id);
57
- if (!trusted) {
58
- // Untrusted device — sign out, send OTP
59
- const maskedEmail = maskEmail(email);
60
- await sendDeviceVerification(email);
61
- return {
62
- user: data.user,
63
- session: null,
64
- error: null,
65
- deviceVerificationRequired: true,
66
- maskedEmail
67
- };
68
- }
69
- await touchTrustedDevice(data.user.id);
70
- }
71
- }
72
- return {
73
- user: data.user,
74
- session: data.session,
75
- error: null
76
- };
77
- }
78
- export async function signUp(email, password, profileData) {
79
- const config = getEngineConfig();
80
- const metadata = config.auth?.profileToMetadata
81
- ? config.auth.profileToMetadata(profileData)
82
- : profileData;
83
- const { data, error } = await supabase.auth.signUp({
84
- email,
85
- password,
86
- options: {
87
- emailRedirectTo: getConfirmRedirectUrl(),
88
- data: metadata
89
- }
90
- });
91
- return {
92
- user: data.user,
93
- session: data.session,
94
- error: error?.message || null
95
- };
96
- }
67
+ // =============================================================================
68
+ // SECTION: Sign Out
69
+ // =============================================================================
70
+ /**
71
+ * Sign the current user out and perform a full teardown of local state.
72
+ *
73
+ * The teardown follows a strict **10-step sequence** to ensure no stale data
74
+ * leaks between user sessions:
75
+ *
76
+ * 1. Stop the sync engine (dynamic import avoids circular deps).
77
+ * 2. Clear the pending sync queue (unless `preserveLocalData` is set).
78
+ * 3. Clear the local cache (unless `preserveLocalData` is set).
79
+ * 4. Clear the offline session token.
80
+ * 5. Clear offline credentials (only when online, to preserve offline re-login).
81
+ * 6. Call `supabase.auth.signOut()`.
82
+ * 7. Remove all `sb-*` keys from localStorage (Supabase internal storage).
83
+ * 8. Reset the login guard (brute-force counters).
84
+ * 9. Reset the sync status store.
85
+ * 10. Reset the auth state store.
86
+ *
87
+ * Each step is wrapped in its own try/catch so that a failure in one step
88
+ * does not prevent subsequent cleanup from running.
89
+ *
90
+ * @param options - Optional flags to control teardown behavior.
91
+ * @param options.preserveOfflineCredentials - When `true`, offline credentials
92
+ * are kept so the user can re-authenticate without network access.
93
+ * @param options.preserveLocalData - When `true`, pending sync queue and local
94
+ * cache are retained.
95
+ * @returns An object with an `error` field (`null` on success).
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * await signOut(); // full teardown
100
+ * await signOut({ preserveLocalData: true }); // keep cached data
101
+ * ```
102
+ */
97
103
  export async function signOut(options) {
98
104
  // 1. Stop sync engine (import dynamically to avoid circular deps)
99
105
  try {
@@ -119,6 +125,10 @@ export async function signOut(options) {
119
125
  // 5. Clear offline credentials (only if online, for offline re-login preservation)
120
126
  try {
121
127
  if (!options?.preserveOfflineCredentials) {
128
+ /* Only clear when online — if the user is offline, we want to keep
129
+ the cached credentials so they can still sign back in without
130
+ network access. This is a deliberate security trade-off favouring
131
+ availability over strict credential erasure. */
122
132
  const isOnline = typeof navigator !== 'undefined' && navigator.onLine;
123
133
  if (isOnline) {
124
134
  await clearOfflineCredentials();
@@ -148,10 +158,35 @@ export async function signOut(options) {
148
158
  authState.reset();
149
159
  return { error: error?.message || null };
150
160
  }
161
+ // =============================================================================
162
+ // SECTION: Session Management
163
+ // =============================================================================
151
164
  /**
152
- * Get current Supabase session
153
- * When offline, returns the cached session from localStorage even if expired
154
- * (the caller should handle offline mode appropriately)
165
+ * Get the current Supabase session.
166
+ *
167
+ * When the device is **online**, this delegates to `supabase.auth.getSession()`
168
+ * which may trigger a token refresh if the access token is close to expiry.
169
+ *
170
+ * When the device is **offline**, or if the Supabase call fails with a
171
+ * corrupted-session error, this falls back to reading the session directly
172
+ * from localStorage via {@link getSessionFromStorage}. The returned session
173
+ * may be expired, but callers can use {@link isSessionExpired} to check and
174
+ * should handle offline mode appropriately (e.g. show cached data, queue
175
+ * mutations for later sync).
176
+ *
177
+ * @returns The current `Session` object, or `null` if no valid session exists.
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * const session = await getSession();
182
+ * if (session && !isSessionExpired(session)) {
183
+ * // Fully authenticated
184
+ * }
185
+ * ```
186
+ *
187
+ * @see {@link getSessionFromStorage} — direct localStorage fallback
188
+ * @see {@link isSessionExpired} — expiry check helper
189
+ * @see {@link getValidSession} — combined convenience wrapper
155
190
  */
156
191
  export async function getSession() {
157
192
  const isOffline = typeof navigator !== 'undefined' && !navigator.onLine;
@@ -165,7 +200,9 @@ export async function getSession() {
165
200
  // Try to get session from localStorage directly
166
201
  return getSessionFromStorage();
167
202
  }
168
- // If session retrieval fails online, it might be corrupted - try to sign out to clear it
203
+ /* Detect corrupted session data (e.g. "can't access property 'hash'
204
+ of undefined") which can occur when localStorage is partially written.
205
+ Signing out clears the corrupt state so subsequent calls succeed. */
169
206
  if (error.message?.includes('hash') || error.message?.includes('undefined')) {
170
207
  debugWarn('[Auth] Detected corrupted session, attempting to clear');
171
208
  await supabase.auth.signOut();
@@ -192,8 +229,20 @@ export async function getSession() {
192
229
  }
193
230
  }
194
231
  /**
195
- * Get session directly from localStorage (for offline scenarios)
196
- * This bypasses Supabase's token refresh logic
232
+ * Read the session directly from localStorage, bypassing Supabase's
233
+ * built-in token refresh logic.
234
+ *
235
+ * This is used as a **fallback** when the device is offline and the normal
236
+ * `supabase.auth.getSession()` call fails. The returned session may be
237
+ * expired, but it still contains the user identity, which is sufficient for
238
+ * rendering cached offline views.
239
+ *
240
+ * Supabase stores its auth token in localStorage under a key matching the
241
+ * pattern `sb-{project-ref}-auth-token`. The internal structure has changed
242
+ * between Supabase versions, so we check for both `currentSession` (older)
243
+ * and `session` (newer) shapes.
244
+ *
245
+ * @returns The cached `Session`, or `null` if nothing usable is found.
197
246
  */
198
247
  function getSessionFromStorage() {
199
248
  try {
@@ -221,7 +270,22 @@ function getSessionFromStorage() {
221
270
  }
222
271
  }
223
272
  /**
224
- * Check if a session's access token is expired
273
+ * Check whether a session's access token has expired.
274
+ *
275
+ * The `expires_at` field on a Supabase session is a **Unix timestamp in
276
+ * seconds**. We compare it against `Date.now() / 1000` (which is in
277
+ * milliseconds, hence the division).
278
+ *
279
+ * @param session - The session to check, or `null`.
280
+ * @returns `true` if the session is `null`, missing `expires_at`, or past
281
+ * its expiry time; `false` otherwise.
282
+ *
283
+ * @example
284
+ * ```ts
285
+ * if (isSessionExpired(session)) {
286
+ * // Prompt re-authentication or attempt token refresh
287
+ * }
288
+ * ```
225
289
  */
226
290
  export function isSessionExpired(session) {
227
291
  if (!session)
@@ -232,6 +296,25 @@ export function isSessionExpired(session) {
232
296
  return true;
233
297
  return Date.now() / 1000 > expiresAt;
234
298
  }
299
+ // =============================================================================
300
+ // SECTION: User Profile
301
+ // =============================================================================
302
+ /**
303
+ * Extract the user's profile from their Supabase `user_metadata`.
304
+ *
305
+ * If the engine config provides a custom `auth.profileExtractor`, it is
306
+ * invoked to transform the raw metadata into the app's profile shape.
307
+ * Otherwise the raw `user_metadata` object is returned as-is.
308
+ *
309
+ * @param user - The Supabase `User` object (may be `null`).
310
+ * @returns A key-value record representing the user's profile fields.
311
+ *
312
+ * @example
313
+ * ```ts
314
+ * const profile = getUserProfile(session.user);
315
+ * console.log(profile.display_name);
316
+ * ```
317
+ */
235
318
  export function getUserProfile(user) {
236
319
  const config = getEngineConfig();
237
320
  if (config.auth?.profileExtractor && user) {
@@ -240,8 +323,22 @@ export function getUserProfile(user) {
240
323
  return user?.user_metadata || {};
241
324
  }
242
325
  /**
243
- * Update user profile
244
- * Also updates cached offline credentials
326
+ * Update the current user's profile metadata on Supabase.
327
+ *
328
+ * The profile data is transformed through `auth.profileToMetadata` (if
329
+ * configured) before being sent. On success the offline credential cache
330
+ * is also updated so that the profile stays consistent across online and
331
+ * offline modes.
332
+ *
333
+ * @param profile - The updated profile fields to persist.
334
+ * @returns An object with an `error` field (`null` on success).
335
+ *
336
+ * @example
337
+ * ```ts
338
+ * const { error } = await updateProfile({ display_name: 'New Name' });
339
+ * ```
340
+ *
341
+ * @see {@link updateOfflineCredentialsProfile} — keeps the offline cache in sync
245
342
  */
246
343
  export async function updateProfile(profile) {
247
344
  const config = getEngineConfig();
@@ -262,104 +359,23 @@ export async function updateProfile(profile) {
262
359
  }
263
360
  return { error: error?.message || null };
264
361
  }
362
+ // =============================================================================
363
+ // SECTION: Email Confirmation & OTP
364
+ // =============================================================================
265
365
  /**
266
- * Change user password
267
- * Verifies current password first, then updates
268
- * Also updates cached offline credentials
269
- */
270
- export async function changePassword(currentPassword, newPassword) {
271
- // Get current user email from session
272
- const { data: { session } } = await supabase.auth.getSession();
273
- const user = session?.user;
274
- if (!user?.email) {
275
- return { error: 'No authenticated user found' };
276
- }
277
- // Verify current password: prefer local hash check, fall back to Supabase
278
- const creds = await getOfflineCredentials();
279
- if (creds && creds.password && creds.email === user.email) {
280
- // Local verification against cached hash
281
- let passwordMatch;
282
- if (isAlreadyHashed(creds.password)) {
283
- const hashedInput = await hashValue(currentPassword);
284
- passwordMatch = creds.password === hashedInput;
285
- }
286
- else {
287
- passwordMatch = creds.password === currentPassword;
288
- }
289
- if (!passwordMatch) {
290
- return { error: 'Current password is incorrect' };
291
- }
292
- }
293
- else {
294
- // No cached credentials — fall back to Supabase verification
295
- const { error: verifyError } = await supabase.auth.signInWithPassword({
296
- email: user.email,
297
- password: currentPassword
298
- });
299
- if (verifyError) {
300
- return { error: 'Current password is incorrect' };
301
- }
302
- }
303
- // Update password
304
- const { error } = await supabase.auth.updateUser({
305
- password: newPassword
306
- });
307
- if (!error) {
308
- // Update offline cache with new password
309
- try {
310
- await updateOfflineCredentialsPassword(newPassword);
311
- }
312
- catch (e) {
313
- debugError('[Auth] Failed to update offline password:', e);
314
- }
315
- }
316
- return { error: error?.message || null };
317
- }
318
- /**
319
- * Initiate an email change for the current user.
320
- * Supabase sends a confirmation email to the new address.
321
- */
322
- export async function changeEmail(newEmail) {
323
- const { error } = await supabase.auth.updateUser({ email: newEmail });
324
- if (error) {
325
- return { error: error.message, confirmationRequired: false };
326
- }
327
- return { error: null, confirmationRequired: true };
328
- }
329
- /**
330
- * Complete email change after the user confirms via the email link.
331
- * Refreshes session to pick up the new email and updates offline credentials.
332
- */
333
- export async function completeEmailChange() {
334
- const { data, error: refreshError } = await supabase.auth.refreshSession();
335
- if (refreshError || !data.session) {
336
- return { error: refreshError?.message || 'Failed to refresh session', newEmail: null };
337
- }
338
- const newEmail = data.session.user.email;
339
- if (!newEmail) {
340
- return { error: 'No email found in updated session', newEmail: null };
341
- }
342
- // Update offline credentials cache
343
- try {
344
- const db = getEngineConfig().db;
345
- if (db) {
346
- const existing = await db.table('offlineCredentials').get('current_user');
347
- if (existing) {
348
- await db.table('offlineCredentials').update('current_user', {
349
- email: newEmail,
350
- cachedAt: new Date().toISOString()
351
- });
352
- }
353
- }
354
- }
355
- catch (e) {
356
- debugError('[Auth] Failed to update offline credentials after email change:', e);
357
- }
358
- return { error: null, newEmail };
359
- }
360
- /**
361
- * Resend confirmation email for signup
362
- * Should be rate-limited on the client side (30 second cooldown)
366
+ * Resend the signup confirmation email for a given address.
367
+ *
368
+ * The caller should enforce a client-side cooldown (recommended: 30 seconds)
369
+ * to prevent abuse, since Supabase may not always rate-limit resends on its
370
+ * own.
371
+ *
372
+ * @param email - The email address that needs a new confirmation link.
373
+ * @returns An object with an `error` field (`null` on success).
374
+ *
375
+ * @example
376
+ * ```ts
377
+ * const { error } = await resendConfirmationEmail('user@example.com');
378
+ * ```
363
379
  */
364
380
  export async function resendConfirmationEmail(email) {
365
381
  const { error } = await supabase.auth.resend({
@@ -372,8 +388,21 @@ export async function resendConfirmationEmail(email) {
372
388
  return { error: error?.message || null };
373
389
  }
374
390
  /**
375
- * Verify OTP token (for email confirmation).
376
- * Absorbs confirm page's direct Supabase call.
391
+ * Verify an OTP token hash received from a confirmation email link.
392
+ *
393
+ * This absorbs the direct Supabase call that would otherwise live in the
394
+ * confirm page component, keeping all auth logic centralised in this module.
395
+ *
396
+ * @param tokenHash - The `token_hash` query parameter from the confirmation URL.
397
+ * @param type - The type of OTP: `'signup'`, `'email'`, or `'email_change'`.
398
+ * @returns An object with an `error` field (`null` on success).
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * // On the /confirm page:
403
+ * const hash = new URL(location.href).searchParams.get('token_hash');
404
+ * const { error } = await verifyOtp(hash, 'signup');
405
+ * ```
377
406
  */
378
407
  export async function verifyOtp(tokenHash, type) {
379
408
  const { error } = await supabase.auth.verifyOtp({
@@ -382,9 +411,28 @@ export async function verifyOtp(tokenHash, type) {
382
411
  });
383
412
  return { error: error?.message || null };
384
413
  }
414
+ // =============================================================================
415
+ // SECTION: Convenience Wrappers
416
+ // =============================================================================
385
417
  /**
386
- * Get a valid (non-expired) session, or null.
387
- * Merges getSession() + isSessionExpired() into a single call.
418
+ * Get a valid (non-expired) session, or `null`.
419
+ *
420
+ * This is a convenience wrapper that combines {@link getSession} and
421
+ * {@link isSessionExpired} into a single call, useful when the caller only
422
+ * cares about sessions that can still be used for API requests.
423
+ *
424
+ * @returns A non-expired `Session`, or `null`.
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * const session = await getValidSession();
429
+ * if (!session) {
430
+ * redirectToLogin();
431
+ * }
432
+ * ```
433
+ *
434
+ * @see {@link getSession}
435
+ * @see {@link isSessionExpired}
388
436
  */
389
437
  export async function getValidSession() {
390
438
  const session = await getSession();
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/supabase/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/supabase/auth.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,88 @@
1
1
  /**
2
- * Supabase Client - Lazy Initialization via Proxy
2
+ * @fileoverview Supabase Client Lazy Initialization via ES Proxy
3
3
  *
4
- * Uses runtime config instead of build-time $env/static/public.
5
- * The Proxy pattern preserves the exact same API surface.
4
+ * This module exports a single `supabase` constant that looks and behaves
5
+ * exactly like a `SupabaseClient` instance, but is actually an ES `Proxy`
6
+ * that defers client creation until the **first property access**. This
7
+ * "lazy singleton" pattern solves a critical bootstrapping problem:
8
+ *
9
+ * The Supabase URL and anon key are loaded at **runtime** (via
10
+ * `getConfig()` from `../runtime/runtimeConfig`), not at build time.
11
+ * Modules that `import { supabase }` at the top level would otherwise
12
+ * crash because the config has not been initialized yet when the import
13
+ * executes.
14
+ *
15
+ * How the Proxy pattern works:
16
+ * 1. `supabase` is exported as `new Proxy({} as SupabaseClient, handler)`.
17
+ * 2. The handler's `get` trap intercepts every property access (e.g.
18
+ * `supabase.auth`, `supabase.from(...)`).
19
+ * 3. On first access, `getOrCreateClient()` reads the runtime config and
20
+ * calls `createClient(url, key, options)` to build the real client.
21
+ * 4. The real client is cached in a module-level `realClient` variable;
22
+ * subsequent accesses reuse it (standard singleton).
23
+ * 5. Function values are `.bind(client)` to preserve `this` context.
24
+ *
25
+ * Additional responsibilities:
26
+ * - **Corrupted session cleanup**: Before the client is created, any
27
+ * malformed `sb-*` entries in localStorage are detected and removed to
28
+ * prevent "can't access property 'hash'" runtime errors.
29
+ * - **Unhandled rejection handler**: A global listener catches Supabase
30
+ * auth errors that escape normal error handling, clears storage, and
31
+ * performs a single guarded page reload to recover.
32
+ * - **iOS PWA detection**: The client sends a custom `x-client-info`
33
+ * header indicating whether it is running as a standalone PWA on iOS,
34
+ * which helps with server-side debugging of session eviction issues.
35
+ *
36
+ * Security considerations:
37
+ * - The anon key is a **public** key (safe to include in client bundles).
38
+ * - PKCE flow is used instead of the implicit flow for stronger OAuth
39
+ * security and better compatibility with PWA environments.
40
+ * - Session persistence uses localStorage; the module proactively scrubs
41
+ * corrupted entries to prevent denial-of-service via bad local state.
42
+ *
43
+ * @module supabase/client
6
44
  */
7
45
  import { type SupabaseClient } from '@supabase/supabase-js';
46
+ /**
47
+ * Override the storage key prefix used by the Supabase client.
48
+ *
49
+ * Must be called **before** the first access to the `supabase` export,
50
+ * since the prefix is baked into the client options at creation time.
51
+ *
52
+ * @param prefix - The new prefix string (e.g. the app's name).
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * _setClientPrefix('myapp');
57
+ * // Later accesses will use storageKey 'myapp-auth'
58
+ * ```
59
+ */
8
60
  export declare function _setClientPrefix(prefix: string): void;
9
61
  /**
10
- * Proxy-based lazy singleton.
11
- * Delegates all property access to the real SupabaseClient,
12
- * which is created on first access using getConfig().
62
+ * The public Supabase client — a Proxy-based lazy singleton.
63
+ *
64
+ * **Why a Proxy?**
65
+ * The Supabase URL and anon key are not available at import time (they come
66
+ * from a runtime config that is loaded asynchronously). A Proxy lets every
67
+ * module `import { supabase }` at the top level without worrying about
68
+ * initialization order. The real client is created transparently on first
69
+ * property access.
70
+ *
71
+ * **How it works:**
72
+ * - The `get` trap intercepts every property read (e.g. `supabase.auth`,
73
+ * `supabase.from`).
74
+ * - It calls `getOrCreateClient()` to ensure the real client exists.
75
+ * - It forwards the property access via `Reflect.get`.
76
+ * - Function values are `.bind(client)` to keep `this` correct when the
77
+ * caller destructures methods (e.g. `const { from } = supabase`).
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * import { supabase } from './client';
82
+ *
83
+ * // Works immediately — the Proxy defers creation until this line runs:
84
+ * const { data } = await supabase.from('users').select('*');
85
+ * ```
13
86
  */
14
87
  export declare const supabase: SupabaseClient;
15
88
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM1E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,QAE9C;AAqJD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,cASrB,CAAC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/supabase/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAe1E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,QAE9C;AAwND;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,QAAQ,EAAE,cASrB,CAAC"}