lemma-sdk 0.2.21 → 0.2.22
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.d.ts +7 -0
- package/dist/auth.js +66 -0
- package/dist/browser/lemma-client.js +66 -0
- package/package.json +1 -1
package/dist/auth.d.ts
CHANGED
|
@@ -102,6 +102,13 @@ export declare class AuthManager {
|
|
|
102
102
|
private setState;
|
|
103
103
|
private assertBrowserContext;
|
|
104
104
|
private getCookie;
|
|
105
|
+
private getCookieDomainCandidates;
|
|
106
|
+
private expireCookie;
|
|
107
|
+
/**
|
|
108
|
+
* Defensive cleanup for stale SuperTokens frontend marker cookies/storage.
|
|
109
|
+
* This helps recover when signout/session-expiry paths leave local markers behind.
|
|
110
|
+
*/
|
|
111
|
+
private clearFrontendSessionMarkers;
|
|
105
112
|
private clearInjectedToken;
|
|
106
113
|
private rawSignOutViaBackend;
|
|
107
114
|
/**
|
package/dist/auth.js
CHANGED
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
import Session from "supertokens-web-js/recipe/session";
|
|
19
19
|
import { ensureCookieSessionSupport } from "./supertokens.js";
|
|
20
20
|
const DEFAULT_BLOCKED_REDIRECT_PATHS = ["/login", "/signup", "/auth"];
|
|
21
|
+
const SUPERTOKENS_FRONTEND_MARKER_KEYS = [
|
|
22
|
+
"sFrontToken",
|
|
23
|
+
"st-last-access-token-update",
|
|
24
|
+
"sIRTFrontend",
|
|
25
|
+
"sAntiCsrf",
|
|
26
|
+
"st-access-token",
|
|
27
|
+
"st-refresh-token",
|
|
28
|
+
];
|
|
21
29
|
const LOCALSTORAGE_TOKEN_KEY = "lemma_token";
|
|
22
30
|
function readStorageToken() {
|
|
23
31
|
if (typeof window === "undefined")
|
|
@@ -214,6 +222,62 @@ export class AuthManager {
|
|
|
214
222
|
const match = document.cookie.match(new RegExp(`(?:^|; )${escaped}=([^;]*)`));
|
|
215
223
|
return match ? decodeURIComponent(match[1]) : undefined;
|
|
216
224
|
}
|
|
225
|
+
getCookieDomainCandidates() {
|
|
226
|
+
if (typeof window === "undefined") {
|
|
227
|
+
return [undefined];
|
|
228
|
+
}
|
|
229
|
+
const host = window.location.hostname;
|
|
230
|
+
const isIpv4 = /^\d{1,3}(?:\.\d{1,3}){3}$/.test(host);
|
|
231
|
+
const isIpv6 = host.includes(":");
|
|
232
|
+
if (!host || host === "localhost" || isIpv4 || isIpv6) {
|
|
233
|
+
return [undefined];
|
|
234
|
+
}
|
|
235
|
+
const domains = new Set();
|
|
236
|
+
const parts = host.split(".").filter(Boolean);
|
|
237
|
+
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
238
|
+
const candidate = parts.slice(i).join(".");
|
|
239
|
+
if (!candidate)
|
|
240
|
+
continue;
|
|
241
|
+
domains.add(candidate);
|
|
242
|
+
domains.add(`.${candidate}`);
|
|
243
|
+
}
|
|
244
|
+
return [undefined, ...domains];
|
|
245
|
+
}
|
|
246
|
+
expireCookie(name, domain) {
|
|
247
|
+
if (typeof document === "undefined")
|
|
248
|
+
return;
|
|
249
|
+
const domainPart = domain ? `;domain=${domain}` : "";
|
|
250
|
+
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/${domainPart};samesite=lax`;
|
|
251
|
+
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/${domainPart}`;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Defensive cleanup for stale SuperTokens frontend marker cookies/storage.
|
|
255
|
+
* This helps recover when signout/session-expiry paths leave local markers behind.
|
|
256
|
+
*/
|
|
257
|
+
clearFrontendSessionMarkers() {
|
|
258
|
+
if (typeof window === "undefined")
|
|
259
|
+
return;
|
|
260
|
+
for (const key of SUPERTOKENS_FRONTEND_MARKER_KEYS) {
|
|
261
|
+
try {
|
|
262
|
+
window.localStorage.removeItem(key);
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// ignore storage errors
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
window.sessionStorage.removeItem(key);
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
// ignore storage errors
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const domains = this.getCookieDomainCandidates();
|
|
275
|
+
for (const key of SUPERTOKENS_FRONTEND_MARKER_KEYS) {
|
|
276
|
+
for (const domain of domains) {
|
|
277
|
+
this.expireCookie(key, domain);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
217
281
|
clearInjectedToken() {
|
|
218
282
|
this.injectedToken = null;
|
|
219
283
|
clearTestingToken();
|
|
@@ -322,6 +386,7 @@ export class AuthManager {
|
|
|
322
386
|
const response = await fetch(`${this.apiUrl}/users/me`, this.getRequestInit({ method: "GET" }));
|
|
323
387
|
// Only 401 means not authenticated — 403 means authenticated but forbidden
|
|
324
388
|
if (response.status === 401) {
|
|
389
|
+
this.clearFrontendSessionMarkers();
|
|
325
390
|
const next = { status: "unauthenticated", user: null };
|
|
326
391
|
this.setState(next);
|
|
327
392
|
return next;
|
|
@@ -348,6 +413,7 @@ export class AuthManager {
|
|
|
348
413
|
* Does NOT redirect — call redirectToAuth() explicitly if desired.
|
|
349
414
|
*/
|
|
350
415
|
markUnauthenticated() {
|
|
416
|
+
this.clearFrontendSessionMarkers();
|
|
351
417
|
this.setState({ status: "unauthenticated", user: null });
|
|
352
418
|
}
|
|
353
419
|
/**
|
|
@@ -204,6 +204,14 @@ exports.resolveSafeRedirectUri = resolveSafeRedirectUri;
|
|
|
204
204
|
const session_1 = require("supertokens-web-js/recipe/session");
|
|
205
205
|
const supertokens_js_1 = require("./supertokens.js");
|
|
206
206
|
const DEFAULT_BLOCKED_REDIRECT_PATHS = ["/login", "/signup", "/auth"];
|
|
207
|
+
const SUPERTOKENS_FRONTEND_MARKER_KEYS = [
|
|
208
|
+
"sFrontToken",
|
|
209
|
+
"st-last-access-token-update",
|
|
210
|
+
"sIRTFrontend",
|
|
211
|
+
"sAntiCsrf",
|
|
212
|
+
"st-access-token",
|
|
213
|
+
"st-refresh-token",
|
|
214
|
+
];
|
|
207
215
|
const LOCALSTORAGE_TOKEN_KEY = "lemma_token";
|
|
208
216
|
function readStorageToken() {
|
|
209
217
|
if (typeof window === "undefined")
|
|
@@ -397,6 +405,62 @@ class AuthManager {
|
|
|
397
405
|
const match = document.cookie.match(new RegExp(`(?:^|; )${escaped}=([^;]*)`));
|
|
398
406
|
return match ? decodeURIComponent(match[1]) : undefined;
|
|
399
407
|
}
|
|
408
|
+
getCookieDomainCandidates() {
|
|
409
|
+
if (typeof window === "undefined") {
|
|
410
|
+
return [undefined];
|
|
411
|
+
}
|
|
412
|
+
const host = window.location.hostname;
|
|
413
|
+
const isIpv4 = /^\d{1,3}(?:\.\d{1,3}){3}$/.test(host);
|
|
414
|
+
const isIpv6 = host.includes(":");
|
|
415
|
+
if (!host || host === "localhost" || isIpv4 || isIpv6) {
|
|
416
|
+
return [undefined];
|
|
417
|
+
}
|
|
418
|
+
const domains = new Set();
|
|
419
|
+
const parts = host.split(".").filter(Boolean);
|
|
420
|
+
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
421
|
+
const candidate = parts.slice(i).join(".");
|
|
422
|
+
if (!candidate)
|
|
423
|
+
continue;
|
|
424
|
+
domains.add(candidate);
|
|
425
|
+
domains.add(`.${candidate}`);
|
|
426
|
+
}
|
|
427
|
+
return [undefined, ...domains];
|
|
428
|
+
}
|
|
429
|
+
expireCookie(name, domain) {
|
|
430
|
+
if (typeof document === "undefined")
|
|
431
|
+
return;
|
|
432
|
+
const domainPart = domain ? `;domain=${domain}` : "";
|
|
433
|
+
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/${domainPart};samesite=lax`;
|
|
434
|
+
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/${domainPart}`;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Defensive cleanup for stale SuperTokens frontend marker cookies/storage.
|
|
438
|
+
* This helps recover when signout/session-expiry paths leave local markers behind.
|
|
439
|
+
*/
|
|
440
|
+
clearFrontendSessionMarkers() {
|
|
441
|
+
if (typeof window === "undefined")
|
|
442
|
+
return;
|
|
443
|
+
for (const key of SUPERTOKENS_FRONTEND_MARKER_KEYS) {
|
|
444
|
+
try {
|
|
445
|
+
window.localStorage.removeItem(key);
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
// ignore storage errors
|
|
449
|
+
}
|
|
450
|
+
try {
|
|
451
|
+
window.sessionStorage.removeItem(key);
|
|
452
|
+
}
|
|
453
|
+
catch {
|
|
454
|
+
// ignore storage errors
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
const domains = this.getCookieDomainCandidates();
|
|
458
|
+
for (const key of SUPERTOKENS_FRONTEND_MARKER_KEYS) {
|
|
459
|
+
for (const domain of domains) {
|
|
460
|
+
this.expireCookie(key, domain);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
400
464
|
clearInjectedToken() {
|
|
401
465
|
this.injectedToken = null;
|
|
402
466
|
clearTestingToken();
|
|
@@ -505,6 +569,7 @@ class AuthManager {
|
|
|
505
569
|
const response = await fetch(`${this.apiUrl}/users/me`, this.getRequestInit({ method: "GET" }));
|
|
506
570
|
// Only 401 means not authenticated — 403 means authenticated but forbidden
|
|
507
571
|
if (response.status === 401) {
|
|
572
|
+
this.clearFrontendSessionMarkers();
|
|
508
573
|
const next = { status: "unauthenticated", user: null };
|
|
509
574
|
this.setState(next);
|
|
510
575
|
return next;
|
|
@@ -531,6 +596,7 @@ class AuthManager {
|
|
|
531
596
|
* Does NOT redirect — call redirectToAuth() explicitly if desired.
|
|
532
597
|
*/
|
|
533
598
|
markUnauthenticated() {
|
|
599
|
+
this.clearFrontendSessionMarkers();
|
|
534
600
|
this.setState({ status: "unauthenticated", user: null });
|
|
535
601
|
}
|
|
536
602
|
/**
|