@mastra/core
Version:
444 lines (441 loc) • 14.8 kB
JavaScript
import { MastraBase } from './chunk-77VL4DNS.js';
// ../_internals/auth/dist/chunk-N7AFRB23.js
function getRequestHeader(request, name) {
if (request instanceof Request) {
return request.headers.get(name);
}
return request.raw?.headers.get(name) ?? request.headers?.get(name) ?? request.header(name) ?? null;
}
function getWebRequest(request) {
if (request instanceof Request) {
return request;
}
return request.raw instanceof Request ? request.raw : void 0;
}
// ../_internals/auth/dist/chunk-7GLKLOU3.js
var MastraAuthProvider = class extends MastraBase {
protected;
public;
constructor(options) {
super({ component: "AUTH", name: options?.name });
if (options?.authorizeUser) {
this.authorizeUser = options.authorizeUser.bind(this);
}
this.protected = options?.protected;
this.public = options?.public;
this.mapUserToResourceId = options?.mapUserToResourceId;
}
registerOptions(opts) {
if (opts?.authorizeUser) {
this.authorizeUser = opts.authorizeUser.bind(this);
}
if (opts?.mapUserToResourceId) {
this.mapUserToResourceId = opts.mapUserToResourceId;
}
if (opts?.protected) {
this.protected = opts.protected;
}
if (opts?.public) {
this.public = opts.public;
}
}
};
function isSSOProvider(p) {
return p !== null && typeof p === "object" && typeof p.getLoginUrl === "function" && typeof p.handleCallback === "function";
}
function isSessionProvider(p) {
return p !== null && typeof p === "object" && typeof p.validateSession === "function" && typeof p.createSession === "function";
}
function isUserProvider(p) {
return p !== null && typeof p === "object" && typeof p.getCurrentUser === "function";
}
function isCredentialsProvider(p) {
return p !== null && typeof p === "object" && typeof p.signIn === "function";
}
function isObjectLike(value) {
return typeof value === "object" && value !== null || typeof value === "function";
}
var CompositeAuth = class extends MastraAuthProvider {
providers;
authenticatedProviderByObject = /* @__PURE__ */ new WeakMap();
authenticatedProviderByPrimitive = /* @__PURE__ */ new Map();
constructor(providers) {
const combinedPublic = providers.flatMap((provider) => provider.public ?? []);
const combinedProtected = providers.flatMap((provider) => provider.protected ?? []);
super({
public: combinedPublic,
protected: combinedProtected
});
this.providers = providers;
if (providers.some((provider) => typeof provider.mapUserToResourceId === "function")) {
this.mapUserToResourceId = (user) => this.mapAuthenticatedUserToResourceId(user);
}
if (!providers.some(isSSOProvider)) {
this.getLoginUrl = void 0;
this.handleCallback = void 0;
this.getLoginButtonConfig = void 0;
}
if (!providers.some(isSessionProvider)) {
this.createSession = void 0;
this.validateSession = void 0;
this.getSessionIdFromRequest = void 0;
}
if (!providers.some(isUserProvider)) {
this.getCurrentUser = void 0;
this.getUser = void 0;
this.getUsers = void 0;
}
const credProvider = this.findProvider(isCredentialsProvider);
if (credProvider) {
this.signIn = credProvider.signIn.bind(credProvider);
if (typeof credProvider.signUp === "function") {
this.signUp = credProvider.signUp.bind(credProvider);
}
if (typeof credProvider.requestPasswordReset === "function") {
this.requestPasswordReset = credProvider.requestPasswordReset.bind(credProvider);
}
if (typeof credProvider.resetPassword === "function") {
this.resetPassword = credProvider.resetPassword.bind(credProvider);
}
this.isSignUpEnabled = typeof credProvider.isSignUpEnabled === "function" ? credProvider.isSignUpEnabled.bind(credProvider) : () => true;
} else {
this.signIn = void 0;
this.signUp = void 0;
this.requestPasswordReset = void 0;
this.resetPassword = void 0;
this.isSignUpEnabled = void 0;
}
}
// Find first provider implementing an interface
findProvider(check) {
return this.providers.find(check);
}
rememberAuthenticatedProvider(user, provider) {
if (isObjectLike(user)) {
this.authenticatedProviderByObject.set(user, provider);
return;
}
this.authenticatedProviderByPrimitive.set(user, provider);
}
takeAuthenticatedProvider(user) {
if (isObjectLike(user)) {
const provider2 = this.authenticatedProviderByObject.get(user);
this.authenticatedProviderByObject.delete(user);
return provider2;
}
const primitiveUser = user;
const provider = this.authenticatedProviderByPrimitive.get(primitiveUser);
this.authenticatedProviderByPrimitive.delete(primitiveUser);
return provider;
}
mapAuthenticatedUserToResourceId(user) {
const provider = this.takeAuthenticatedProvider(user);
return provider?.mapUserToResourceId?.(user);
}
// ============================================================================
// License Exemption Markers
// Expose these if any underlying provider has them
// ============================================================================
/**
* True if any provider is MastraCloudAuth (exempt from license requirement).
*/
get isMastraCloudAuth() {
return this.providers.some(
(p) => "isMastraCloudAuth" in p && p.isMastraCloudAuth === true
);
}
/**
* True if any provider is SimpleAuth (exempt from license requirement).
*/
get isSimpleAuth() {
return this.providers.some((p) => "isSimpleAuth" in p && p.isSimpleAuth === true);
}
// ============================================================================
// MastraAuthProvider Implementation
// ============================================================================
async authenticateToken(token, request) {
for (const provider of this.providers) {
try {
const user = await provider.authenticateToken(token, request);
if (user) {
this.rememberAuthenticatedProvider(user, provider);
return user;
}
} catch {
}
}
return null;
}
async authorizeUser(user, request) {
for (const provider of this.providers) {
const authorized = await provider.authorizeUser(user, request);
if (authorized) {
return true;
}
}
return false;
}
// ============================================================================
// ISSOProvider Implementation
// ============================================================================
/**
* Forward cookie header to SSO provider for PKCE validation.
* Called by auth handler before handleCallback().
*/
setCallbackCookieHeader(cookieHeader) {
const sso = this.findProvider(isSSOProvider);
if (sso && typeof sso.setCallbackCookieHeader === "function") {
sso.setCallbackCookieHeader(cookieHeader);
}
}
getLoginUrl(redirectUri, state) {
const sso = this.findProvider(isSSOProvider);
if (!sso) throw new Error("No SSO provider configured in CompositeAuth");
return sso.getLoginUrl(redirectUri, state);
}
getLoginCookies(redirectUri, state) {
const sso = this.findProvider(isSSOProvider);
return sso?.getLoginCookies?.(redirectUri, state);
}
async handleCallback(code, state) {
const sso = this.findProvider(isSSOProvider);
if (!sso) throw new Error("No SSO provider configured in CompositeAuth");
return sso.handleCallback(code, state);
}
getLoginButtonConfig() {
const sso = this.findProvider(isSSOProvider);
if (!sso) return { provider: "unknown", text: "Sign in" };
return sso.getLoginButtonConfig();
}
async getLogoutUrl(redirectUri, request) {
for (const provider of this.providers) {
if (isSSOProvider(provider) && provider.getLogoutUrl) {
try {
const url = await provider.getLogoutUrl(redirectUri, request);
if (url) return url;
} catch {
}
}
}
return null;
}
// ============================================================================
// ISessionProvider Implementation
// ============================================================================
async createSession(userId, metadata) {
const session = this.findProvider(isSessionProvider);
if (!session) throw new Error("No session provider configured in CompositeAuth");
return session.createSession(userId, metadata);
}
async validateSession(sessionId) {
for (const provider of this.providers) {
if (isSessionProvider(provider)) {
try {
const session = await provider.validateSession(sessionId);
if (session) return session;
} catch {
}
}
}
return null;
}
async destroySession(sessionId) {
const destroyPromises = [];
for (const provider of this.providers) {
if (isSessionProvider(provider)) {
destroyPromises.push(
provider.destroySession(sessionId).catch(() => {
})
);
}
}
await Promise.all(destroyPromises);
}
async refreshSession(sessionId) {
for (const provider of this.providers) {
if (isSessionProvider(provider)) {
try {
const session = await provider.refreshSession(sessionId);
if (session) return session;
} catch {
}
}
}
return null;
}
getSessionIdFromRequest(request) {
for (const provider of this.providers) {
if (isSessionProvider(provider)) {
try {
const sessionId = provider.getSessionIdFromRequest(request);
if (sessionId) return sessionId;
} catch {
}
}
}
return null;
}
getSessionHeaders(session) {
const sessionProvider = this.findProvider(isSessionProvider);
return sessionProvider?.getSessionHeaders(session) ?? {};
}
getClearSessionHeaders() {
const headers = {};
for (const provider of this.providers) {
if (isSessionProvider(provider)) {
try {
const providerHeaders = provider.getClearSessionHeaders();
Object.assign(headers, providerHeaders);
} catch {
}
}
}
return headers;
}
// ============================================================================
// IUserProvider Implementation
// Try each provider until one returns a user (like authenticateToken)
// ============================================================================
async getCurrentUser(request) {
for (const provider of this.providers) {
if (isUserProvider(provider)) {
try {
const user = await provider.getCurrentUser(request);
if (user) return user;
} catch {
}
}
}
return null;
}
async getUser(userId) {
for (const provider of this.providers) {
if (isUserProvider(provider)) {
try {
const user = await provider.getUser(userId);
if (user) return user;
} catch {
}
}
}
return null;
}
async getUsers(userIds) {
return Promise.all(userIds.map((userId) => this.getUser(userId)));
}
};
var DEFAULT_HEADERS = ["Authorization", "X-Playground-Access"];
var SimpleAuth = class extends MastraAuthProvider {
/**
* Marker to exempt SimpleAuth from EE license requirement.
* SimpleAuth is for development/testing and should work without a license.
*/
isSimpleAuth = true;
tokens;
headers;
users;
userById;
constructor(options) {
super(options);
this.tokens = options.tokens;
this.users = Object.values(this.tokens);
this.headers = [...DEFAULT_HEADERS].concat(options.headers || []);
this.userById = new Map(this.users.map((u) => [String(u?.id), u]));
}
async authenticateToken(token, request) {
const requestTokens = this.getTokensFromHeaders(token, request);
for (const requestToken of requestTokens) {
const tokenToUser = this.tokens[requestToken];
if (tokenToUser) {
return tokenToUser;
}
}
return this.getUserFromCookie(getRequestHeader(request, "Cookie"));
}
async authorizeUser(user, _request) {
return this.users.includes(user);
}
/** Get current user from request headers or cookie. */
async getCurrentUser(request) {
for (const headerName of this.headers) {
const headerValue = request.headers.get(headerName);
if (headerValue) {
const token = this.stripBearerPrefix(headerValue);
const user = this.tokens[token];
if (user) {
return user;
}
}
}
return this.getUserFromCookie(request.headers.get("Cookie"));
}
getUserFromCookie(cookieHeader) {
if (!cookieHeader) return null;
const cookies = cookieHeader.split(";").map((c) => c.trim());
for (const cookie of cookies) {
if (cookie.startsWith("mastra-token=")) {
const token = cookie.slice("mastra-token=".length);
const user = this.tokens[token];
if (user) {
return user;
}
}
}
return null;
}
/** Get user by ID. */
async getUser(userId) {
return this.userById.get(userId) ?? null;
}
async getUsers(userIds) {
return userIds.map((userId) => this.userById.get(userId) ?? null);
}
/**
* Sign in with token (passed as password field).
* The email field is ignored - only the token matters.
*/
async signIn(_email, password, _request) {
const token = password;
const user = this.tokens[token];
if (!user) {
throw new Error("Invalid token");
}
const cookie = `mastra-token=${token}; Path=/; HttpOnly; SameSite=Lax; Max-Age=86400`;
return {
user,
token,
cookies: [cookie]
};
}
async signUp() {
throw new Error("Sign up is not supported with SimpleAuth. Use pre-configured tokens.");
}
isSignUpEnabled() {
return false;
}
/**
* Get headers to clear the session cookie on logout.
* Partial ISessionProvider implementation for logout support.
*/
getClearSessionHeaders() {
return {
"Set-Cookie": "mastra-token=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0"
};
}
stripBearerPrefix(token) {
return token.startsWith("Bearer ") ? token.slice(7) : token;
}
getTokensFromHeaders(token, request) {
const tokens = [token];
for (const headerName of this.headers) {
const headerValue = getRequestHeader(request, headerName);
if (headerValue) {
tokens.push(this.stripBearerPrefix(headerValue));
}
}
return tokens;
}
};
export { CompositeAuth, MastraAuthProvider, SimpleAuth, getRequestHeader, getWebRequest };
//# sourceMappingURL=chunk-PETV6YNX.js.map
//# sourceMappingURL=chunk-PETV6YNX.js.map