@mastra/auth-studio 1.3.10-alpha.0 → 1.3.11-alpha.0
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 +1 -2
- package/dist/_types/@internal_auth/dist/session/index.d.ts +9 -0
- package/dist/index.cjs +128 -32
- 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 +127 -33
- package/dist/index.js.map +1 -1
- package/package.json +7 -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
|
@@ -316,7 +316,7 @@ var MastraAuthProvider = class extends MastraBase {
|
|
|
316
316
|
}
|
|
317
317
|
};
|
|
318
318
|
//#endregion
|
|
319
|
-
//#region ../../packages/_internals/auth/dist/ee-
|
|
319
|
+
//#region ../../packages/_internals/auth/dist/ee-XRuijAiF.js
|
|
320
320
|
/**
|
|
321
321
|
* FGA enforcement utility for checking fine-grained authorization.
|
|
322
322
|
*
|
|
@@ -427,8 +427,28 @@ function resolvePermissionsFromMapping(roles, mapping) {
|
|
|
427
427
|
*/
|
|
428
428
|
//#endregion
|
|
429
429
|
//#region src/index.ts
|
|
430
|
-
const DEFAULT_SESSION_MAX_AGE_SECONDS =
|
|
430
|
+
const DEFAULT_SESSION_MAX_AGE_SECONDS = 1209600;
|
|
431
|
+
/**
|
|
432
|
+
* Name of the sealed session cookie on the shared API. Used for server-to-server
|
|
433
|
+
* calls to the shared API, and as the unprefixed (legacy / insecure-dev /
|
|
434
|
+
* explicit-domain) browser cookie name.
|
|
435
|
+
*/
|
|
431
436
|
const COOKIE_NAME = "wos-session";
|
|
437
|
+
/** Host-only browser session cookie used on secure deployments. */
|
|
438
|
+
const HOST_SESSION_COOKIE_NAME = "__Host-wos-session";
|
|
439
|
+
/** Unprefixed session cookie name earlier releases issued (often with a shared parent `Domain`). */
|
|
440
|
+
const LEGACY_SESSION_COOKIE_NAME = COOKIE_NAME;
|
|
441
|
+
/** A `Domain` attribute value we are willing to emit in a clearing cookie. */
|
|
442
|
+
function normalizeCookieDomain(value) {
|
|
443
|
+
const domain = value?.trim().toLowerCase();
|
|
444
|
+
if (!domain) return void 0;
|
|
445
|
+
if (!/^\.?[a-z0-9-]+(\.[a-z0-9-]+)*$/.test(domain)) return void 0;
|
|
446
|
+
return domain;
|
|
447
|
+
}
|
|
448
|
+
function isLocalhostDomain(domain) {
|
|
449
|
+
const bare = domain.replace(/^\./, "");
|
|
450
|
+
return bare === "localhost" || bare.endsWith(".localhost") || /^[\d.]+$/.test(bare);
|
|
451
|
+
}
|
|
432
452
|
const PROJECT_CONFIG_FILE = ".mastra-project.json";
|
|
433
453
|
/**
|
|
434
454
|
* Read `organizationId` from a project's `.mastra-project.json` in the current
|
|
@@ -478,6 +498,10 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
478
498
|
organizationId;
|
|
479
499
|
useProductionCookies;
|
|
480
500
|
cookieDomain;
|
|
501
|
+
/** Browser cookie name this provider issues. */
|
|
502
|
+
sessionCookieName;
|
|
503
|
+
/** `Set-Cookie` values expiring legacy copies of the session cookie. */
|
|
504
|
+
legacyClearCookies;
|
|
481
505
|
sessionMaxAgeSeconds;
|
|
482
506
|
/**
|
|
483
507
|
* `userId → sealed session cookie` cache. The `IOrganizationsProvider`
|
|
@@ -527,7 +551,8 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
527
551
|
this.sharedApiUrl = explicitSharedApiUrl || "https://platform.mastra.ai/v1";
|
|
528
552
|
this.organizationId = options?.organizationId || process.env.MASTRA_ORGANIZATION_ID || readOrganizationIdFromProjectConfig();
|
|
529
553
|
if (this.sharedApiUrl.endsWith("/")) this.sharedApiUrl = this.sharedApiUrl.slice(0, -1);
|
|
530
|
-
this.cookieDomain = options?.cookieDomain
|
|
554
|
+
this.cookieDomain = normalizeCookieDomain(options?.cookieDomain);
|
|
555
|
+
const envCookieDomain = normalizeCookieDomain(process.env.MASTRA_COOKIE_DOMAIN);
|
|
531
556
|
const envMaxAge = Number(process.env.MASTRA_SESSION_MAX_AGE);
|
|
532
557
|
const maxAge = options?.sessionMaxAgeSeconds ?? (envMaxAge > 0 ? envMaxAge : void 0);
|
|
533
558
|
this.sessionMaxAgeSeconds = maxAge && Number.isFinite(maxAge) && maxAge > 0 ? Math.floor(maxAge) : DEFAULT_SESSION_MAX_AGE_SECONDS;
|
|
@@ -538,8 +563,31 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
538
563
|
} catch {
|
|
539
564
|
autoDetectMastraAi = false;
|
|
540
565
|
}
|
|
541
|
-
this.useProductionCookies = !!this.cookieDomain || autoDetectMastraAi;
|
|
542
|
-
|
|
566
|
+
this.useProductionCookies = options?.secureCookies ?? (!!(this.cookieDomain && !isLocalhostDomain(this.cookieDomain)) || !!(envCookieDomain && !isLocalhostDomain(envCookieDomain)) || autoDetectMastraAi);
|
|
567
|
+
this.sessionCookieName = this.useProductionCookies && !this.cookieDomain ? HOST_SESSION_COOKIE_NAME : LEGACY_SESSION_COOKIE_NAME;
|
|
568
|
+
const legacyDomains = /* @__PURE__ */ new Set();
|
|
569
|
+
const addLegacyDomain = (value) => {
|
|
570
|
+
const domain = normalizeCookieDomain(value);
|
|
571
|
+
if (domain && domain !== this.cookieDomain) legacyDomains.add(domain);
|
|
572
|
+
};
|
|
573
|
+
addLegacyDomain(envCookieDomain);
|
|
574
|
+
if (autoDetectMastraAi) addLegacyDomain(".mastra.ai");
|
|
575
|
+
for (const value of (process.env.MASTRA_LEGACY_COOKIE_DOMAINS ?? "").split(",")) addLegacyDomain(value);
|
|
576
|
+
for (const value of options?.legacyCookieDomains ?? []) addLegacyDomain(value);
|
|
577
|
+
const clearAttributes = [
|
|
578
|
+
"HttpOnly",
|
|
579
|
+
"SameSite=Lax",
|
|
580
|
+
"Path=/",
|
|
581
|
+
"Max-Age=0"
|
|
582
|
+
];
|
|
583
|
+
if (this.useProductionCookies) clearAttributes.push("Secure");
|
|
584
|
+
this.legacyClearCookies = [];
|
|
585
|
+
if (this.sessionCookieName !== "wos-session" || this.cookieDomain) this.legacyClearCookies.push([`${LEGACY_SESSION_COOKIE_NAME}=`, ...clearAttributes].join("; "));
|
|
586
|
+
for (const domain of legacyDomains) this.legacyClearCookies.push([
|
|
587
|
+
`${LEGACY_SESSION_COOKIE_NAME}=`,
|
|
588
|
+
...clearAttributes,
|
|
589
|
+
`Domain=${domain}`
|
|
590
|
+
].join("; "));
|
|
543
591
|
if (options) this.registerOptions(options);
|
|
544
592
|
}
|
|
545
593
|
/**
|
|
@@ -548,8 +596,12 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
548
596
|
*/
|
|
549
597
|
async authenticateToken(token, request) {
|
|
550
598
|
let user = null;
|
|
551
|
-
const
|
|
552
|
-
|
|
599
|
+
const cookieHeader = getRequestHeader(request, "Cookie");
|
|
600
|
+
const sessionCookie = this.readSessionCookie(cookieHeader);
|
|
601
|
+
if (sessionCookie) {
|
|
602
|
+
user = await this.verifySessionCookie(sessionCookie.value, request);
|
|
603
|
+
if (user && sessionCookie.legacy) this.queueSessionCookieMigration(request, sessionCookie.value);
|
|
604
|
+
}
|
|
553
605
|
if (!user && token) user = await this.verifyBearerToken(token);
|
|
554
606
|
if (!user) return null;
|
|
555
607
|
if (this.organizationId && !user.memberOrgIds?.includes(this.organizationId)) return null;
|
|
@@ -603,8 +655,7 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
603
655
|
};
|
|
604
656
|
}
|
|
605
657
|
async getLogoutUrl(_redirectUri, request) {
|
|
606
|
-
const
|
|
607
|
-
const sessionCookie = parseCookie(cookieHeader, COOKIE_NAME);
|
|
658
|
+
const sessionCookie = this.readSessionCookie(request?.headers.get("Cookie"))?.value;
|
|
608
659
|
if (!sessionCookie) return null;
|
|
609
660
|
try {
|
|
610
661
|
const res = await fetch(`${this.sharedApiUrl}/auth/logout`, {
|
|
@@ -687,39 +738,76 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
687
738
|
}
|
|
688
739
|
}
|
|
689
740
|
getSessionIdFromRequest(request) {
|
|
690
|
-
return
|
|
741
|
+
return this.readSessionCookie(request.headers.get("Cookie"))?.value ?? null;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* The browser session cookie on a request: this provider's cookie
|
|
745
|
+
* (`__Host-wos-session` on secure deployments) first, then — only to migrate
|
|
746
|
+
* sessions issued by earlier releases — the unprefixed `wos-session`.
|
|
747
|
+
*/
|
|
748
|
+
readSessionCookie(cookieHeader) {
|
|
749
|
+
const current = parseCookie(cookieHeader, this.sessionCookieName);
|
|
750
|
+
if (current) return {
|
|
751
|
+
value: current,
|
|
752
|
+
legacy: false
|
|
753
|
+
};
|
|
754
|
+
if (this.sessionCookieName === "wos-session") return null;
|
|
755
|
+
const legacy = parseCookie(cookieHeader, LEGACY_SESSION_COOKIE_NAME);
|
|
756
|
+
return legacy ? {
|
|
757
|
+
value: legacy,
|
|
758
|
+
legacy: true
|
|
759
|
+
} : null;
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* A request authenticated with a legacy `wos-session` cookie: re-issue the
|
|
763
|
+
* session under this provider's cookie so the browser stops depending on the
|
|
764
|
+
* legacy (possibly shared-domain) copy. The legacy copy itself is expired on
|
|
765
|
+
* the next sign-in, refresh or sign-out (see `getLegacySessionClearCookies`).
|
|
766
|
+
*/
|
|
767
|
+
queueSessionCookieMigration(request, sessionId) {
|
|
768
|
+
const rawRequest = getWebRequest(request);
|
|
769
|
+
if (!rawRequest || this.pendingResponseHeaders.has(rawRequest)) return;
|
|
770
|
+
this.pendingResponseHeaders.set(rawRequest, this.getSessionHeaders({
|
|
771
|
+
id: sessionId,
|
|
772
|
+
userId: "",
|
|
773
|
+
expiresAt: /* @__PURE__ */ new Date(),
|
|
774
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
775
|
+
}));
|
|
691
776
|
}
|
|
692
777
|
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("; ") };
|
|
778
|
+
return { "Set-Cookie": this.buildSessionCookie(`${this.sessionCookieName}=${session.id}`, [`Max-Age=${this.sessionMaxAgeSeconds}`]) };
|
|
705
779
|
}
|
|
706
780
|
getClearSessionHeaders() {
|
|
781
|
+
return { "Set-Cookie": this.buildSessionCookie(`${this.sessionCookieName}=`, ["Max-Age=0"]) };
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* `Set-Cookie` values expiring legacy copies of the session cookie: the
|
|
785
|
+
* unprefixed `wos-session` on this host and on every domain an earlier
|
|
786
|
+
* release (or the platform) scoped it to. Servers send these with every
|
|
787
|
+
* response that sets or clears the session cookie.
|
|
788
|
+
*/
|
|
789
|
+
getLegacySessionClearCookies() {
|
|
790
|
+
return [...this.legacyClearCookies];
|
|
791
|
+
}
|
|
792
|
+
buildSessionCookie(nameValue, extra) {
|
|
707
793
|
const parts = [
|
|
708
|
-
|
|
794
|
+
nameValue,
|
|
709
795
|
"HttpOnly",
|
|
710
796
|
"SameSite=Lax",
|
|
711
797
|
"Path=/",
|
|
712
|
-
|
|
798
|
+
...extra
|
|
713
799
|
];
|
|
714
|
-
if (this.useProductionCookies
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
}
|
|
718
|
-
return { "Set-Cookie": parts.join("; ") };
|
|
800
|
+
if (this.useProductionCookies) parts.push("Secure");
|
|
801
|
+
if (this.cookieDomain && this.sessionCookieName !== "__Host-wos-session") parts.push(`Domain=${this.cookieDomain}`);
|
|
802
|
+
return parts.join("; ");
|
|
719
803
|
}
|
|
720
804
|
async getCurrentUser(request) {
|
|
721
|
-
const sessionCookie =
|
|
722
|
-
if (sessionCookie)
|
|
805
|
+
const sessionCookie = this.readSessionCookie(request.headers.get("Cookie"));
|
|
806
|
+
if (sessionCookie) {
|
|
807
|
+
const user = await this.verifySessionCookie(sessionCookie.value, request);
|
|
808
|
+
if (user && sessionCookie.legacy) this.queueSessionCookieMigration(request, sessionCookie.value);
|
|
809
|
+
return user;
|
|
810
|
+
}
|
|
723
811
|
const authHeader = request.headers.get("Authorization");
|
|
724
812
|
if (authHeader?.startsWith("Bearer ")) return this.verifyBearerToken(authHeader.slice(7));
|
|
725
813
|
return null;
|
|
@@ -1037,7 +1125,13 @@ var MastraAuthStudio = class extends MastraAuthProvider {
|
|
|
1037
1125
|
};
|
|
1038
1126
|
function parseCookie(cookieHeader, name) {
|
|
1039
1127
|
if (!cookieHeader) return null;
|
|
1040
|
-
|
|
1128
|
+
for (const pair of cookieHeader.split(";")) {
|
|
1129
|
+
const eq = pair.indexOf("=");
|
|
1130
|
+
if (eq === -1 || pair.slice(0, eq).trim() !== name) continue;
|
|
1131
|
+
const value = pair.slice(eq + 1).trim();
|
|
1132
|
+
if (value) return value;
|
|
1133
|
+
}
|
|
1134
|
+
return null;
|
|
1041
1135
|
}
|
|
1042
1136
|
/**
|
|
1043
1137
|
* WorkOS AuthKit conventionally uses `admin` / `owner` for admin-equivalent
|
|
@@ -1096,6 +1190,6 @@ var MastraRBACStudio = class {
|
|
|
1096
1190
|
}
|
|
1097
1191
|
};
|
|
1098
1192
|
//#endregion
|
|
1099
|
-
export { MastraAuthStudio, MastraRBACStudio };
|
|
1193
|
+
export { HOST_SESSION_COOKIE_NAME, LEGACY_SESSION_COOKIE_NAME, MastraAuthStudio, MastraRBACStudio };
|
|
1100
1194
|
|
|
1101
1195
|
//# sourceMappingURL=index.js.map
|