@mastra/auth-studio 1.3.10 → 1.3.11-alpha.1
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/_types/@internal_auth/dist/_types/@internal_core/dist/base/index.d.ts +2 -5
- package/dist/_types/@internal_auth/dist/_types/@internal_core/dist/{index-Biaf3BmX.d.ts → index-TNVgGNjs.d.ts} +1 -5
- package/dist/_types/@internal_auth/dist/session/index.d.ts +9 -0
- package/dist/index.cjs +133 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +56 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +132 -44
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.d.ts
CHANGED
|
@@ -26,12 +26,35 @@ export interface MastraAuthStudioOptions extends MastraAuthProviderOptions<Studi
|
|
|
26
26
|
*/
|
|
27
27
|
organizationId?: string;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
29
|
+
* Explicit cookie domain for the session cookie (e.g. '.example.com').
|
|
30
|
+
*
|
|
31
|
+
* Unset by default, and you almost certainly want it unset: the session
|
|
32
|
+
* cookie is then **host-only** — `__Host-wos-session` (`Secure`, `Path=/`, no
|
|
33
|
+
* `Domain`) on secure deployments — so the browser never presents it to any
|
|
34
|
+
* other host. A `Domain` shares the account-scoped session with every host
|
|
35
|
+
* under that domain; only set it when every such host is trusted. A domain
|
|
36
|
+
* cookie cannot use the `__Host-` prefix, so it is issued as `wos-session`.
|
|
37
|
+
*
|
|
38
|
+
* The `MASTRA_COOKIE_DOMAIN` environment variable is **not** used as a
|
|
39
|
+
* `Domain`: older releases did, and the platform injected a shared parent
|
|
40
|
+
* domain through it. It now only marks the deployment as secure (unless it is
|
|
41
|
+
* a `localhost` host) and names a domain whose legacy cookie is expired.
|
|
33
42
|
*/
|
|
34
43
|
cookieDomain?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Extra domains whose legacy `wos-session` cookie is expired whenever this
|
|
46
|
+
* provider writes or clears the session cookie (sign-in, refresh, sign-out).
|
|
47
|
+
* Merged with the comma-separated `MASTRA_LEGACY_COOKIE_DOMAINS` env var.
|
|
48
|
+
*/
|
|
49
|
+
legacyCookieDomains?: string[];
|
|
50
|
+
/**
|
|
51
|
+
* Force the secure (`__Host-`) cookie on or off. Defaults to on when the
|
|
52
|
+
* deployment looks like a production one (`MASTRA_COOKIE_DOMAIN` set to a
|
|
53
|
+
* non-localhost host, or an explicit `sharedApiUrl` on `mastra.ai`) and off
|
|
54
|
+
* otherwise, so plain-http `localhost` dev keeps an unprefixed, host-only
|
|
55
|
+
* `wos-session` cookie that browsers accept without HTTPS.
|
|
56
|
+
*/
|
|
57
|
+
secureCookies?: boolean;
|
|
35
58
|
/**
|
|
36
59
|
* Lifetime of the session cookie (and Session.expiresAt) in seconds.
|
|
37
60
|
* Should match the identity provider's maximum session length.
|
|
@@ -40,6 +63,10 @@ export interface MastraAuthStudioOptions extends MastraAuthProviderOptions<Studi
|
|
|
40
63
|
*/
|
|
41
64
|
sessionMaxAgeSeconds?: number;
|
|
42
65
|
}
|
|
66
|
+
/** Host-only browser session cookie used on secure deployments. */
|
|
67
|
+
export declare const HOST_SESSION_COOKIE_NAME = "__Host-wos-session";
|
|
68
|
+
/** Unprefixed session cookie name earlier releases issued (often with a shared parent `Domain`). */
|
|
69
|
+
export declare const LEGACY_SESSION_COOKIE_NAME = "wos-session";
|
|
43
70
|
/**
|
|
44
71
|
* Auth provider for Mastra Studio deployed instances.
|
|
45
72
|
*
|
|
@@ -57,6 +84,10 @@ export declare class MastraAuthStudio extends MastraAuthProvider<StudioUser> imp
|
|
|
57
84
|
private organizationId;
|
|
58
85
|
private useProductionCookies;
|
|
59
86
|
private cookieDomain;
|
|
87
|
+
/** Browser cookie name this provider issues. */
|
|
88
|
+
private sessionCookieName;
|
|
89
|
+
/** `Set-Cookie` values expiring legacy copies of the session cookie. */
|
|
90
|
+
private legacyClearCookies;
|
|
60
91
|
private sessionMaxAgeSeconds;
|
|
61
92
|
/**
|
|
62
93
|
* `userId → sealed session cookie` cache. The `IOrganizationsProvider`
|
|
@@ -115,8 +146,29 @@ export declare class MastraAuthStudio extends MastraAuthProvider<StudioUser> imp
|
|
|
115
146
|
destroySession(sessionId: string): Promise<void>;
|
|
116
147
|
refreshSession(sessionId: string): Promise<Session | null>;
|
|
117
148
|
getSessionIdFromRequest(request: Request): string | null;
|
|
149
|
+
/**
|
|
150
|
+
* The browser session cookie on a request: this provider's cookie
|
|
151
|
+
* (`__Host-wos-session` on secure deployments) first, then — only to migrate
|
|
152
|
+
* sessions issued by earlier releases — the unprefixed `wos-session`.
|
|
153
|
+
*/
|
|
154
|
+
private readSessionCookie;
|
|
155
|
+
/**
|
|
156
|
+
* A request authenticated with a legacy `wos-session` cookie: re-issue the
|
|
157
|
+
* session under this provider's cookie so the browser stops depending on the
|
|
158
|
+
* legacy (possibly shared-domain) copy. The legacy copy itself is expired on
|
|
159
|
+
* the next sign-in, refresh or sign-out (see `getLegacySessionClearCookies`).
|
|
160
|
+
*/
|
|
161
|
+
private queueSessionCookieMigration;
|
|
118
162
|
getSessionHeaders(session: Session): Record<string, string>;
|
|
119
163
|
getClearSessionHeaders(): Record<string, string>;
|
|
164
|
+
/**
|
|
165
|
+
* `Set-Cookie` values expiring legacy copies of the session cookie: the
|
|
166
|
+
* unprefixed `wos-session` on this host and on every domain an earlier
|
|
167
|
+
* release (or the platform) scoped it to. Servers send these with every
|
|
168
|
+
* response that sets or clears the session cookie.
|
|
169
|
+
*/
|
|
170
|
+
getLegacySessionClearCookies(): string[];
|
|
171
|
+
private buildSessionCookie;
|
|
120
172
|
getCurrentUser(request: Request): Promise<StudioUser | null>;
|
|
121
173
|
getUser(_userId: string): Promise<StudioUser | null>;
|
|
122
174
|
/**
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,iBAAiB,EACjB,cAAc,EACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,MAAM,WAAW,UAAW,SAAQ,MAAM;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,uBAAwB,SAAQ,yBAAyB,CAAC,UAAU,CAAC;IACpF,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
|
-
|
|
3
|
+
// ../../packages/_internals/auth/dist/types/index.js
|
|
4
4
|
function headerFromPlainObject(headers, name) {
|
|
5
5
|
const normalizedName = name.toLowerCase();
|
|
6
6
|
const matchingKey = Object.keys(headers).find((key) => key.toLowerCase() === normalizedName);
|
|
@@ -24,8 +24,7 @@ function getWebRequest(request) {
|
|
|
24
24
|
if (request instanceof Request) return request;
|
|
25
25
|
return request.raw instanceof Request ? request.raw : void 0;
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
//#region ../../packages/_internal-core/dist/logger/index.js
|
|
27
|
+
// ../../packages/_internal-core/dist/logger/index.js
|
|
29
28
|
/**
|
|
30
29
|
* Export a tracked exception through the adapter sink, mirroring the
|
|
31
30
|
* DualLogger dual-write shape (`errorId`/`domain`/`category`/`details`/`cause`
|
|
@@ -258,8 +257,7 @@ var ConsoleLogger = class ConsoleLogger extends MastraLogger {
|
|
|
258
257
|
};
|
|
259
258
|
}
|
|
260
259
|
};
|
|
261
|
-
|
|
262
|
-
//#region ../../packages/_internal-core/dist/base/index.js
|
|
260
|
+
// ../../packages/_internal-core/dist/base/index.js
|
|
263
261
|
var MastraBase = class {
|
|
264
262
|
component = RegisteredLogger.LLM;
|
|
265
263
|
logger;
|
|
@@ -293,8 +291,7 @@ var MastraBase = class {
|
|
|
293
291
|
this.logger = "child" in logger && typeof logger.child === "function" ? logger.child({ component: this.component }) : logger;
|
|
294
292
|
}
|
|
295
293
|
};
|
|
296
|
-
|
|
297
|
-
//#region ../../packages/_internals/auth/dist/provider/index.js
|
|
294
|
+
// ../../packages/_internals/auth/dist/provider/index.js
|
|
298
295
|
var MastraAuthProvider = class extends MastraBase {
|
|
299
296
|
protected;
|
|
300
297
|
public;
|
|
@@ -306,7 +303,7 @@ var MastraAuthProvider = class extends MastraBase {
|
|
|
306
303
|
if (options?.authorizeUser) this.authorizeUser = options.authorizeUser.bind(this);
|
|
307
304
|
this.protected = options?.protected;
|
|
308
305
|
this.public = options?.public;
|
|
309
|
-
this.mapUserToResourceId = options
|
|
306
|
+
if (options?.mapUserToResourceId) this.mapUserToResourceId = options.mapUserToResourceId;
|
|
310
307
|
}
|
|
311
308
|
registerOptions(opts) {
|
|
312
309
|
if (opts?.authorizeUser) this.authorizeUser = opts.authorizeUser.bind(this);
|
|
@@ -315,8 +312,7 @@ var MastraAuthProvider = class extends MastraBase {
|
|
|
315
312
|
if (opts?.public) this.public = opts.public;
|
|
316
313
|
}
|
|
317
314
|
};
|
|
318
|
-
|
|
319
|
-
//#region ../../packages/_internals/auth/dist/ee-XRuijAiF.js
|
|
315
|
+
// ../../packages/_internals/auth/dist/ee-CnZdF0Vm.js
|
|
320
316
|
/**
|
|
321
317
|
* FGA enforcement utility for checking fine-grained authorization.
|
|
322
318
|
*
|
|
@@ -425,10 +421,29 @@ function resolvePermissionsFromMapping(roles, mapping) {
|
|
|
425
421
|
* @license Mastra Enterprise License - see ee/LICENSE
|
|
426
422
|
* @packageDocumentation
|
|
427
423
|
*/
|
|
428
|
-
|
|
429
|
-
//#region src/index.ts
|
|
424
|
+
// src/index.ts
|
|
430
425
|
const DEFAULT_SESSION_MAX_AGE_SECONDS = 1209600;
|
|
426
|
+
/**
|
|
427
|
+
* Name of the sealed session cookie on the shared API. Used for server-to-server
|
|
428
|
+
* calls to the shared API, and as the unprefixed (legacy / insecure-dev /
|
|
429
|
+
* explicit-domain) browser cookie name.
|
|
430
|
+
*/
|
|
431
431
|
const COOKIE_NAME = "wos-session";
|
|
432
|
+
/** Host-only browser session cookie used on secure deployments. */
|
|
433
|
+
const HOST_SESSION_COOKIE_NAME = "__Host-wos-session";
|
|
434
|
+
/** Unprefixed session cookie name earlier releases issued (often with a shared parent `Domain`). */
|
|
435
|
+
const LEGACY_SESSION_COOKIE_NAME = COOKIE_NAME;
|
|
436
|
+
/** A `Domain` attribute value we are willing to emit in a clearing cookie. */
|
|
437
|
+
function normalizeCookieDomain(value) {
|
|
438
|
+
const domain = value?.trim().toLowerCase();
|
|
439
|
+
if (!domain) return void 0;
|
|
440
|
+
if (!/^\.?[a-z0-9-]+(\.[a-z0-9-]+)*$/.test(domain)) return void 0;
|
|
441
|
+
return domain;
|
|
442
|
+
}
|
|
443
|
+
function isLocalhostDomain(domain) {
|
|
444
|
+
const bare = domain.replace(/^\./, "");
|
|
445
|
+
return bare === "localhost" || bare.endsWith(".localhost") || /^[\d.]+$/.test(bare);
|
|
446
|
+
}
|
|
432
447
|
const PROJECT_CONFIG_FILE = ".mastra-project.json";
|
|
433
448
|
/**
|
|
434
449
|
* Read `organizationId` from a project's `.mastra-project.json` in the current
|
|
@@ -478,6 +493,10 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
478
493
|
organizationId;
|
|
479
494
|
useProductionCookies;
|
|
480
495
|
cookieDomain;
|
|
496
|
+
/** Browser cookie name this provider issues. */
|
|
497
|
+
sessionCookieName;
|
|
498
|
+
/** `Set-Cookie` values expiring legacy copies of the session cookie. */
|
|
499
|
+
legacyClearCookies;
|
|
481
500
|
sessionMaxAgeSeconds;
|
|
482
501
|
/**
|
|
483
502
|
* `userId → sealed session cookie` cache. The `IOrganizationsProvider`
|
|
@@ -527,7 +546,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
527
546
|
this.sharedApiUrl = explicitSharedApiUrl || "https://platform.mastra.ai/v1";
|
|
528
547
|
this.organizationId = options?.organizationId || process.env.MASTRA_ORGANIZATION_ID || readOrganizationIdFromProjectConfig();
|
|
529
548
|
if (this.sharedApiUrl.endsWith("/")) this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);
|
|
530
|
-
this.cookieDomain = options?.cookieDomain
|
|
549
|
+
this.cookieDomain = normalizeCookieDomain(options?.cookieDomain);
|
|
550
|
+
const envCookieDomain = normalizeCookieDomain(process.env.MASTRA_COOKIE_DOMAIN);
|
|
531
551
|
const envMaxAge = Number(process.env.MASTRA_SESSION_MAX_AGE);
|
|
532
552
|
const maxAge = options?.sessionMaxAgeSeconds ?? (envMaxAge > 0 ? envMaxAge : void 0);
|
|
533
553
|
this.sessionMaxAgeSeconds = maxAge && Number.isFinite(maxAge) && maxAge > 0 ? Math.floor(maxAge) : DEFAULT_SESSION_MAX_AGE_SECONDS;
|
|
@@ -538,8 +558,31 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
538
558
|
} catch {
|
|
539
559
|
autoDetectMastraAi = false;
|
|
540
560
|
}
|
|
541
|
-
this.useProductionCookies = !!this.cookieDomain || autoDetectMastraAi;
|
|
542
|
-
|
|
561
|
+
this.useProductionCookies = options?.secureCookies ?? (!!(this.cookieDomain && !isLocalhostDomain(this.cookieDomain)) || !!(envCookieDomain && !isLocalhostDomain(envCookieDomain)) || autoDetectMastraAi);
|
|
562
|
+
this.sessionCookieName = this.useProductionCookies && !this.cookieDomain ? HOST_SESSION_COOKIE_NAME : LEGACY_SESSION_COOKIE_NAME;
|
|
563
|
+
const legacyDomains = /* @__PURE__ */ new Set();
|
|
564
|
+
const addLegacyDomain = (value) => {
|
|
565
|
+
const domain = normalizeCookieDomain(value);
|
|
566
|
+
if (domain && domain !== this.cookieDomain) legacyDomains.add(domain);
|
|
567
|
+
};
|
|
568
|
+
addLegacyDomain(envCookieDomain);
|
|
569
|
+
if (autoDetectMastraAi) addLegacyDomain(".mastra.ai");
|
|
570
|
+
for (const value of (process.env.MASTRA_LEGACY_COOKIE_DOMAINS ?? "").split(",")) addLegacyDomain(value);
|
|
571
|
+
for (const value of options?.legacyCookieDomains ?? []) addLegacyDomain(value);
|
|
572
|
+
const clearAttributes = [
|
|
573
|
+
"HttpOnly",
|
|
574
|
+
"SameSite=Lax",
|
|
575
|
+
"Path=/",
|
|
576
|
+
"Max-Age=0"
|
|
577
|
+
];
|
|
578
|
+
if (this.useProductionCookies) clearAttributes.push("Secure");
|
|
579
|
+
this.legacyClearCookies = [];
|
|
580
|
+
if (this.sessionCookieName !== "wos-session" || this.cookieDomain) this.legacyClearCookies.push([`${LEGACY_SESSION_COOKIE_NAME}=`, ...clearAttributes].join("; "));
|
|
581
|
+
for (const domain of legacyDomains) this.legacyClearCookies.push([
|
|
582
|
+
`${LEGACY_SESSION_COOKIE_NAME}=`,
|
|
583
|
+
...clearAttributes,
|
|
584
|
+
`Domain=${domain}`
|
|
585
|
+
].join("; "));
|
|
543
586
|
if (options) this.registerOptions(options);
|
|
544
587
|
}
|
|
545
588
|
/**
|
|
@@ -548,8 +591,12 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
548
591
|
*/
|
|
549
592
|
async authenticateToken(token, request) {
|
|
550
593
|
let user = null;
|
|
551
|
-
const
|
|
552
|
-
|
|
594
|
+
const cookieHeader = getRequestHeader(request, "Cookie");
|
|
595
|
+
const sessionCookie = this.readSessionCookie(cookieHeader);
|
|
596
|
+
if (sessionCookie) {
|
|
597
|
+
user = await this.verifySessionCookie(sessionCookie.value, request);
|
|
598
|
+
if (user && sessionCookie.legacy) this.queueSessionCookieMigration(request, sessionCookie.value);
|
|
599
|
+
}
|
|
553
600
|
if (!user && token) user = await this.verifyBearerToken(token);
|
|
554
601
|
if (!user) return null;
|
|
555
602
|
if (this.organizationId && !user.memberOrgIds?.includes(this.organizationId)) return null;
|
|
@@ -603,8 +650,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
603
650
|
};
|
|
604
651
|
}
|
|
605
652
|
async getLogoutUrl(_redirectUri, request) {
|
|
606
|
-
const
|
|
607
|
-
const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);
|
|
653
|
+
const sessionCookie = this.readSessionCookie(request?.headers.get("Cookie"))?.value;
|
|
608
654
|
if (!sessionCookie) return null;
|
|
609
655
|
try {
|
|
610
656
|
const res = await fetch(`${this.sharedApiUrl}/auth/logout`, {
|
|
@@ -687,39 +733,76 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
687
733
|
}
|
|
688
734
|
}
|
|
689
735
|
getSessionIdFromRequest(request) {
|
|
690
|
-
return
|
|
736
|
+
return this.readSessionCookie(request.headers.get("Cookie"))?.value ?? null;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* The browser session cookie on a request: this provider's cookie
|
|
740
|
+
* (`__Host-wos-session` on secure deployments) first, then — only to migrate
|
|
741
|
+
* sessions issued by earlier releases — the unprefixed `wos-session`.
|
|
742
|
+
*/
|
|
743
|
+
readSessionCookie(cookieHeader) {
|
|
744
|
+
const current = parseCookie(cookieHeader, this.sessionCookieName);
|
|
745
|
+
if (current) return {
|
|
746
|
+
value: current,
|
|
747
|
+
legacy: false
|
|
748
|
+
};
|
|
749
|
+
if (this.sessionCookieName === "wos-session") return null;
|
|
750
|
+
const legacy = parseCookie(cookieHeader, LEGACY_SESSION_COOKIE_NAME);
|
|
751
|
+
return legacy ? {
|
|
752
|
+
value: legacy,
|
|
753
|
+
legacy: true
|
|
754
|
+
} : null;
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* A request authenticated with a legacy `wos-session` cookie: re-issue the
|
|
758
|
+
* session under this provider's cookie so the browser stops depending on the
|
|
759
|
+
* legacy (possibly shared-domain) copy. The legacy copy itself is expired on
|
|
760
|
+
* the next sign-in, refresh or sign-out (see `getLegacySessionClearCookies`).
|
|
761
|
+
*/
|
|
762
|
+
queueSessionCookieMigration(request, sessionId) {
|
|
763
|
+
const rawRequest = getWebRequest(request);
|
|
764
|
+
if (!rawRequest || this.pendingResponseHeaders.has(rawRequest)) return;
|
|
765
|
+
this.pendingResponseHeaders.set(rawRequest, this.getSessionHeaders({
|
|
766
|
+
id: sessionId,
|
|
767
|
+
userId: "",
|
|
768
|
+
expiresAt: /* @__PURE__ */ new Date(),
|
|
769
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
770
|
+
}));
|
|
691
771
|
}
|
|
692
772
|
getSessionHeaders(session) {
|
|
693
|
-
|
|
694
|
-
`${COOKIE_NAME}=${session.id}`,
|
|
695
|
-
"HttpOnly",
|
|
696
|
-
"SameSite=Lax",
|
|
697
|
-
"Path=/",
|
|
698
|
-
`Max-Age=${this.sessionMaxAgeSeconds}`
|
|
699
|
-
];
|
|
700
|
-
if (this.useProductionCookies && this.cookieDomain) {
|
|
701
|
-
parts.push("Secure");
|
|
702
|
-
parts.push(`Domain=${this.cookieDomain}`);
|
|
703
|
-
}
|
|
704
|
-
return { "Set-Cookie": parts.join("; ") };
|
|
773
|
+
return { "Set-Cookie": this.buildSessionCookie(`${this.sessionCookieName}=${session.id}`, [`Max-Age=${this.sessionMaxAgeSeconds}`]) };
|
|
705
774
|
}
|
|
706
775
|
getClearSessionHeaders() {
|
|
776
|
+
return { "Set-Cookie": this.buildSessionCookie(`${this.sessionCookieName}=`, ["Max-Age=0"]) };
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* `Set-Cookie` values expiring legacy copies of the session cookie: the
|
|
780
|
+
* unprefixed `wos-session` on this host and on every domain an earlier
|
|
781
|
+
* release (or the platform) scoped it to. Servers send these with every
|
|
782
|
+
* response that sets or clears the session cookie.
|
|
783
|
+
*/
|
|
784
|
+
getLegacySessionClearCookies() {
|
|
785
|
+
return [...this.legacyClearCookies];
|
|
786
|
+
}
|
|
787
|
+
buildSessionCookie(nameValue, extra) {
|
|
707
788
|
const parts = [
|
|
708
|
-
|
|
789
|
+
nameValue,
|
|
709
790
|
"HttpOnly",
|
|
710
791
|
"SameSite=Lax",
|
|
711
792
|
"Path=/",
|
|
712
|
-
|
|
793
|
+
...extra
|
|
713
794
|
];
|
|
714
|
-
if (this.useProductionCookies
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
}
|
|
718
|
-
return { "Set-Cookie": parts.join("; ") };
|
|
795
|
+
if (this.useProductionCookies) parts.push("Secure");
|
|
796
|
+
if (this.cookieDomain && this.sessionCookieName !== "__Host-wos-session") parts.push(`Domain=${this.cookieDomain}`);
|
|
797
|
+
return parts.join("; ");
|
|
719
798
|
}
|
|
720
799
|
async getCurrentUser(request) {
|
|
721
|
-
const sessionCookie =
|
|
722
|
-
if (sessionCookie)
|
|
800
|
+
const sessionCookie = this.readSessionCookie(request.headers.get("Cookie"));
|
|
801
|
+
if (sessionCookie) {
|
|
802
|
+
const user = await this.verifySessionCookie(sessionCookie.value, request);
|
|
803
|
+
if (user && sessionCookie.legacy) this.queueSessionCookieMigration(request, sessionCookie.value);
|
|
804
|
+
return user;
|
|
805
|
+
}
|
|
723
806
|
const authHeader = request.headers.get("Authorization");
|
|
724
807
|
if (authHeader?.startsWith("Bearer ")) return this.verifyBearerToken(authHeader.slice(7));
|
|
725
808
|
return null;
|
|
@@ -1037,7 +1120,13 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
1037
1120
|
};
|
|
1038
1121
|
function parseCookie(cookieHeader, name) {
|
|
1039
1122
|
if (!cookieHeader) return null;
|
|
1040
|
-
|
|
1123
|
+
for (const pair of cookieHeader.split(";")) {
|
|
1124
|
+
const eq = pair.indexOf("=");
|
|
1125
|
+
if (eq === -1 || pair.slice(0, eq).trim() !== name) continue;
|
|
1126
|
+
const value = pair.slice(eq + 1).trim();
|
|
1127
|
+
if (value) return value;
|
|
1128
|
+
}
|
|
1129
|
+
return null;
|
|
1041
1130
|
}
|
|
1042
1131
|
/**
|
|
1043
1132
|
* WorkOS AuthKit conventionally uses `admin` / `owner` for admin-equivalent
|
|
@@ -1095,7 +1184,6 @@ var MastraRBACStudio = class {
|
|
|
1095
1184
|
return permissions.some((required) => userPermissions.some((p) => matchesPermission(p, required)));
|
|
1096
1185
|
}
|
|
1097
1186
|
};
|
|
1098
|
-
|
|
1099
|
-
export { MastraAuthStudio, MastraRBACStudio };
|
|
1187
|
+
export { HOST_SESSION_COOKIE_NAME, LEGACY_SESSION_COOKIE_NAME, MastraAuthStudio, MastraRBACStudio };
|
|
1100
1188
|
|
|
1101
1189
|
//# sourceMappingURL=index.js.map
|