@mastra/auth-cloud 1.2.0 → 1.2.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/CHANGELOG.md +18 -0
- package/dist/_types/@internal_auth/dist/_types/@internal_core/dist/base/index.d.ts +31 -0
- package/dist/_types/@internal_auth/dist/_types/@internal_core/dist/logger/index.d.ts +217 -0
- package/dist/_types/@internal_auth/dist/ee/capabilities.d.ts +142 -0
- package/dist/_types/@internal_auth/dist/ee/defaults/index.d.ts +8 -0
- package/dist/_types/@internal_auth/dist/ee/defaults/rbac/index.d.ts +7 -0
- package/dist/_types/@internal_auth/dist/ee/defaults/rbac/static.d.ts +106 -0
- package/dist/_types/@internal_auth/dist/ee/defaults/roles.d.ts +92 -0
- package/dist/_types/@internal_auth/dist/ee/fga-check.d.ts +62 -0
- package/dist/_types/@internal_auth/dist/ee/index.d.ts +15 -0
- package/dist/_types/@internal_auth/dist/ee/interfaces/acl.d.ts +140 -0
- package/dist/_types/@internal_auth/dist/ee/interfaces/fga.d.ts +350 -0
- package/dist/_types/@internal_auth/dist/ee/interfaces/index.d.ts +15 -0
- package/dist/_types/@internal_auth/dist/ee/interfaces/permissions.generated.d.ts +519 -0
- package/dist/_types/@internal_auth/dist/ee/interfaces/rbac.d.ts +207 -0
- package/dist/_types/@internal_auth/dist/ee/interfaces/user.d.ts +18 -0
- package/dist/_types/@internal_auth/dist/ee/license.d.ts +171 -0
- package/dist/_types/@internal_auth/dist/index.d.ts +277 -0
- package/dist/_types/@internal_auth/dist/provider/index.d.ts +125 -0
- package/dist/_types/@internal_auth/dist/session/cookie.d.ts +82 -0
- package/dist/_types/@internal_auth/dist/session/index.d.ts +30 -0
- package/dist/_types/@internal_auth/dist/session/memory.d.ts +60 -0
- package/dist/_types/@internal_auth/dist/types/index.d.ts +52 -0
- package/dist/auth-provider.d.ts +4 -4
- package/dist/auth-provider.d.ts.map +1 -1
- package/dist/index.cjs +301 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +296 -4
- package/dist/index.js.map +1 -1
- package/dist/rbac/rbac-provider.d.ts +1 -1
- package/dist/rbac/rbac-provider.d.ts.map +1 -1
- package/package.json +6 -6
- package/LICENSE.md +0 -30
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RBAC provider interface for EE authentication.
|
|
3
|
+
* Enables role-based access control in Studio.
|
|
4
|
+
*
|
|
5
|
+
* RBAC is designed to be separate from authentication.
|
|
6
|
+
* This allows users to mix auth providers with RBAC providers:
|
|
7
|
+
* - Use Better Auth for authentication + StaticRBACProvider for RBAC
|
|
8
|
+
* - Use Clerk for both auth and RBAC via MastraRBACClerk
|
|
9
|
+
* - Use Auth0 for auth + custom RBAC provider
|
|
10
|
+
*/
|
|
11
|
+
import type { PermissionPattern } from './permissions.generated.js';
|
|
12
|
+
/**
|
|
13
|
+
* Definition of a role with its permissions.
|
|
14
|
+
* Uses type-safe permission patterns derived from SERVER_ROUTES.
|
|
15
|
+
*/
|
|
16
|
+
export interface RoleDefinition {
|
|
17
|
+
/** Unique role identifier */
|
|
18
|
+
id: string;
|
|
19
|
+
/** Human-readable role name */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Role description */
|
|
22
|
+
description?: string;
|
|
23
|
+
/** Permissions granted by this role (type-safe) */
|
|
24
|
+
permissions: PermissionPattern[];
|
|
25
|
+
/** Role IDs this role inherits from */
|
|
26
|
+
inherits?: string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Role mapping configuration for translating provider roles to Mastra permissions.
|
|
30
|
+
* Uses type-safe permission patterns derived from SERVER_ROUTES.
|
|
31
|
+
*
|
|
32
|
+
* Use this when your identity provider (WorkOS, Okta, Azure AD, etc.) has its own
|
|
33
|
+
* roles that need to be translated to Mastra's permission model.
|
|
34
|
+
*
|
|
35
|
+
* Special keys:
|
|
36
|
+
* - `_default`: Permissions for roles not explicitly mapped
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const roleMapping: RoleMapping = {
|
|
41
|
+
* "Engineering": ["agents:*", "workflows:*"],
|
|
42
|
+
* "Product": ["agents:read", "workflows:read"],
|
|
43
|
+
* "Admin": ["*"],
|
|
44
|
+
* "_default": [], // unmapped roles get no permissions
|
|
45
|
+
* };
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export type RoleMapping = {
|
|
49
|
+
/** Map role name to array of permission patterns */
|
|
50
|
+
[role: string]: PermissionPattern[];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Provider interface for role-based access control (read-only).
|
|
54
|
+
*
|
|
55
|
+
* Implement this interface to enable:
|
|
56
|
+
* - Permission-based UI gating
|
|
57
|
+
* - Role display in user menu
|
|
58
|
+
* - Access control checks
|
|
59
|
+
*
|
|
60
|
+
* RBAC providers can be used independently of auth providers:
|
|
61
|
+
*
|
|
62
|
+
* @example Using StaticRBACProvider with Better Auth
|
|
63
|
+
* ```typescript
|
|
64
|
+
* // Better Auth handles authentication only
|
|
65
|
+
* const auth = new MastraAuthBetterAuth({ betterAuth });
|
|
66
|
+
*
|
|
67
|
+
* // Static RBAC handles authorization
|
|
68
|
+
* const rbac = new StaticRBACProvider({
|
|
69
|
+
* roles: DEFAULT_ROLES,
|
|
70
|
+
* getUserRoles: (user) => [user.role],
|
|
71
|
+
* });
|
|
72
|
+
*
|
|
73
|
+
* const mastra = new Mastra({
|
|
74
|
+
* server: {
|
|
75
|
+
* auth,
|
|
76
|
+
* rbac,
|
|
77
|
+
* },
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example Using MastraRBACClerk with role mapping
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const mastra = new Mastra({
|
|
84
|
+
* server: {
|
|
85
|
+
* auth: new MastraAuthClerk({ clerk }),
|
|
86
|
+
* rbac: new MastraRBACClerk({
|
|
87
|
+
* clerk,
|
|
88
|
+
* roleMapping: {
|
|
89
|
+
* "org:admin": ["*"],
|
|
90
|
+
* "org:member": ["agents:read", "workflows:read"],
|
|
91
|
+
* },
|
|
92
|
+
* }),
|
|
93
|
+
* },
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export interface IRBACProvider<TUser = unknown> {
|
|
98
|
+
/**
|
|
99
|
+
* Optional role mapping for translating provider roles to Mastra permissions.
|
|
100
|
+
* If provided, permissions are resolved using this mapping instead of getPermissions().
|
|
101
|
+
*/
|
|
102
|
+
roleMapping?: RoleMapping;
|
|
103
|
+
/**
|
|
104
|
+
* Get all roles for a user.
|
|
105
|
+
*
|
|
106
|
+
* @param user - User to get roles for
|
|
107
|
+
* @returns Array of role IDs
|
|
108
|
+
*/
|
|
109
|
+
getRoles(user: TUser): Promise<string[]>;
|
|
110
|
+
/**
|
|
111
|
+
* Check if user has a specific role.
|
|
112
|
+
*
|
|
113
|
+
* @param user - User to check
|
|
114
|
+
* @param role - Role ID to check for
|
|
115
|
+
* @returns True if user has the role
|
|
116
|
+
*/
|
|
117
|
+
hasRole(user: TUser, role: string): Promise<boolean>;
|
|
118
|
+
/**
|
|
119
|
+
* Get all permissions for a user (resolved from roles).
|
|
120
|
+
*
|
|
121
|
+
* @param user - User to get permissions for
|
|
122
|
+
* @returns Array of permission strings
|
|
123
|
+
*/
|
|
124
|
+
getPermissions(user: TUser): Promise<string[]>;
|
|
125
|
+
/**
|
|
126
|
+
* Check if user has a specific permission.
|
|
127
|
+
*
|
|
128
|
+
* @param user - User to check
|
|
129
|
+
* @param permission - Permission to check for
|
|
130
|
+
* @returns True if user has the permission
|
|
131
|
+
*/
|
|
132
|
+
hasPermission(user: TUser, permission: string): Promise<boolean>;
|
|
133
|
+
/**
|
|
134
|
+
* Check if user has ALL of the specified permissions.
|
|
135
|
+
*
|
|
136
|
+
* @param user - User to check
|
|
137
|
+
* @param permissions - Permissions to check for
|
|
138
|
+
* @returns True if user has all permissions
|
|
139
|
+
*/
|
|
140
|
+
hasAllPermissions(user: TUser, permissions: string[]): Promise<boolean>;
|
|
141
|
+
/**
|
|
142
|
+
* Check if user has ANY of the specified permissions.
|
|
143
|
+
*
|
|
144
|
+
* @param user - User to check
|
|
145
|
+
* @param permissions - Permissions to check for
|
|
146
|
+
* @returns True if user has at least one permission
|
|
147
|
+
*/
|
|
148
|
+
hasAnyPermission(user: TUser, permissions: string[]): Promise<boolean>;
|
|
149
|
+
/**
|
|
150
|
+
* Get all available roles in the system.
|
|
151
|
+
* Used by the "View as role" feature to list roles an admin can impersonate.
|
|
152
|
+
*
|
|
153
|
+
* @returns Array of role descriptors
|
|
154
|
+
*/
|
|
155
|
+
getAvailableRoles?(): Promise<{
|
|
156
|
+
id: string;
|
|
157
|
+
name: string;
|
|
158
|
+
}[]>;
|
|
159
|
+
/**
|
|
160
|
+
* Get the resolved permissions for a specific role.
|
|
161
|
+
* Used by the "View as role" feature to override client-side permissions.
|
|
162
|
+
*
|
|
163
|
+
* @param roleId - Role ID to resolve permissions for
|
|
164
|
+
* @returns Array of permission strings
|
|
165
|
+
*/
|
|
166
|
+
getPermissionsForRole?(roleId: string): Promise<string[]>;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Extended interface for managing roles (write operations).
|
|
170
|
+
*
|
|
171
|
+
* Implement this in addition to IRBACProvider to enable role management.
|
|
172
|
+
*/
|
|
173
|
+
export interface IRBACManager<TUser = unknown> extends IRBACProvider<TUser> {
|
|
174
|
+
/**
|
|
175
|
+
* Assign a role to a user.
|
|
176
|
+
*
|
|
177
|
+
* @param userId - User to assign role to
|
|
178
|
+
* @param roleId - Role to assign
|
|
179
|
+
*/
|
|
180
|
+
assignRole(userId: string, roleId: string): Promise<void>;
|
|
181
|
+
/**
|
|
182
|
+
* Remove a role from a user.
|
|
183
|
+
*
|
|
184
|
+
* @param userId - User to remove role from
|
|
185
|
+
* @param roleId - Role to remove
|
|
186
|
+
*/
|
|
187
|
+
removeRole(userId: string, roleId: string): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* List all available roles.
|
|
190
|
+
*
|
|
191
|
+
* @returns Array of role definitions
|
|
192
|
+
*/
|
|
193
|
+
listRoles(): Promise<RoleDefinition[]>;
|
|
194
|
+
/**
|
|
195
|
+
* Optional: Create a new role.
|
|
196
|
+
*
|
|
197
|
+
* @param role - Role definition to create
|
|
198
|
+
*/
|
|
199
|
+
createRole?(role: RoleDefinition): Promise<void>;
|
|
200
|
+
/**
|
|
201
|
+
* Optional: Delete a role.
|
|
202
|
+
*
|
|
203
|
+
* @param roleId - Role ID to delete
|
|
204
|
+
*/
|
|
205
|
+
deleteRole?(roleId: string): Promise<void>;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=rbac.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise user type for EE authentication.
|
|
3
|
+
* Extends the base User type with enterprise-specific fields.
|
|
4
|
+
*
|
|
5
|
+
* @license Mastra Enterprise License - see ee/LICENSE
|
|
6
|
+
*/
|
|
7
|
+
import type { User } from '../../index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Enterprise user type with additional metadata.
|
|
10
|
+
*
|
|
11
|
+
* Extends the base `User` type with fields commonly needed
|
|
12
|
+
* for RBAC, ACL, and organizational features.
|
|
13
|
+
*/
|
|
14
|
+
export interface EEUser extends User {
|
|
15
|
+
/** Additional metadata */
|
|
16
|
+
metadata?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=user.d.ts.map
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* License validation for EE features.
|
|
3
|
+
*
|
|
4
|
+
* Validation is delegated to the Mastra license server via `LicenseClient`
|
|
5
|
+
* (POST {MASTRA_LICENSE_URL}/validate). The client validates in the
|
|
6
|
+
* background and caches the result; the synchronous helpers in this module
|
|
7
|
+
* read the cached state:
|
|
8
|
+
*
|
|
9
|
+
* - No license key configured → EE features disabled.
|
|
10
|
+
* - Key configured, validation pending → fail open (features enabled) until
|
|
11
|
+
* the first server response settles the state.
|
|
12
|
+
* - Server says invalid/revoked/expired → EE features disabled.
|
|
13
|
+
* - Server unreachable → fail open with a 72h grace period for previously
|
|
14
|
+
* validated licenses.
|
|
15
|
+
*
|
|
16
|
+
* `MASTRA_LICENSE_KEY` is the primary env var; `MASTRA_EE_LICENSE` is a
|
|
17
|
+
* supported legacy alias.
|
|
18
|
+
*/
|
|
19
|
+
interface IMastraLogger {
|
|
20
|
+
warn(message: string): void;
|
|
21
|
+
info(message: string): void;
|
|
22
|
+
error(message: string): void;
|
|
23
|
+
}
|
|
24
|
+
export interface LicenseValidationSuccess {
|
|
25
|
+
valid: true;
|
|
26
|
+
/** Feature entitlements granted by the license (e.g. 'rbac', 'sso', 'fga') */
|
|
27
|
+
entitlements: string[];
|
|
28
|
+
/** Plan tier the license was issued for (e.g. 'teams', 'enterprise') */
|
|
29
|
+
planTier: string;
|
|
30
|
+
expiresAt: string | null;
|
|
31
|
+
leaseTtlSeconds: number;
|
|
32
|
+
}
|
|
33
|
+
export interface LicenseValidationError {
|
|
34
|
+
valid: false;
|
|
35
|
+
code: 'INVALID_KEY' | 'LICENSE_EXPIRED' | 'LICENSE_REVOKED' | 'RATE_LIMITED';
|
|
36
|
+
reason: string;
|
|
37
|
+
}
|
|
38
|
+
export type LicenseValidationResponse = LicenseValidationSuccess | LicenseValidationError;
|
|
39
|
+
export type LicenseMode = 'enterprise' | 'open-source';
|
|
40
|
+
export type LicenseStatus = 'pending' | 'valid' | 'invalid';
|
|
41
|
+
export interface LicenseSnapshot {
|
|
42
|
+
mode: LicenseMode;
|
|
43
|
+
status: LicenseStatus;
|
|
44
|
+
entitlements: string[] | null;
|
|
45
|
+
planTier: string | null;
|
|
46
|
+
expiresAt: string | null;
|
|
47
|
+
}
|
|
48
|
+
export declare class LicenseClient {
|
|
49
|
+
private static instance;
|
|
50
|
+
private logger?;
|
|
51
|
+
private licenseKey?;
|
|
52
|
+
private licenseUrl?;
|
|
53
|
+
private mode;
|
|
54
|
+
private status;
|
|
55
|
+
private cachedResult;
|
|
56
|
+
private cacheExpiry;
|
|
57
|
+
private gracePeriodEnd;
|
|
58
|
+
private revalidationTimeout;
|
|
59
|
+
private readonly GRACE_PERIOD_MS;
|
|
60
|
+
private readonly DEFAULT_TTL_MS;
|
|
61
|
+
private constructor();
|
|
62
|
+
static getInstance(logger?: IMastraLogger): LicenseClient;
|
|
63
|
+
/**
|
|
64
|
+
* Reset the singleton so the next getInstance() re-reads env vars.
|
|
65
|
+
* Intended for tests.
|
|
66
|
+
*/
|
|
67
|
+
static resetInstance(): void;
|
|
68
|
+
private readonly REQUEST_TIMEOUT_MS;
|
|
69
|
+
private fetchWithRetry;
|
|
70
|
+
private validationPromise;
|
|
71
|
+
validate(): Promise<boolean>;
|
|
72
|
+
/**
|
|
73
|
+
* Contact the server regardless of cache freshness, coalescing concurrent
|
|
74
|
+
* callers (e.g. the Mastra constructor and the auth/ee helpers both kicking
|
|
75
|
+
* off validation at startup) into a single in-flight request so the server
|
|
76
|
+
* is contacted — and the outcome logged — only once. Used directly by the
|
|
77
|
+
* background revalidation timer, which must bypass the cache check.
|
|
78
|
+
*/
|
|
79
|
+
private revalidate;
|
|
80
|
+
private performValidation;
|
|
81
|
+
private scheduleRevalidation;
|
|
82
|
+
private clearCache;
|
|
83
|
+
hasFeature(featureName: string): boolean;
|
|
84
|
+
getEntitlements(): string[] | null;
|
|
85
|
+
getSnapshot(): LicenseSnapshot;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* License information.
|
|
89
|
+
*/
|
|
90
|
+
export interface LicenseInfo {
|
|
91
|
+
/** Whether the license is valid */
|
|
92
|
+
valid: boolean;
|
|
93
|
+
/** License expiration date */
|
|
94
|
+
expiresAt?: Date;
|
|
95
|
+
/** Features enabled by this license */
|
|
96
|
+
features?: string[];
|
|
97
|
+
/** Organization name */
|
|
98
|
+
organization?: string;
|
|
99
|
+
/** License plan tier (e.g. 'teams', 'enterprise') */
|
|
100
|
+
tier?: string;
|
|
101
|
+
}
|
|
102
|
+
export interface SafeLicenseSummary {
|
|
103
|
+
valid: boolean;
|
|
104
|
+
isDevEnvironment: boolean;
|
|
105
|
+
licenseHash?: string;
|
|
106
|
+
anonymousId?: string;
|
|
107
|
+
features?: string[];
|
|
108
|
+
tier?: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Start license validation against the license server.
|
|
112
|
+
*
|
|
113
|
+
* Safe to call multiple times — the underlying client caches results and
|
|
114
|
+
* schedules its own background revalidation. Resolves to whether the license
|
|
115
|
+
* is currently considered valid.
|
|
116
|
+
*/
|
|
117
|
+
export declare function startLicenseValidation(): Promise<boolean>;
|
|
118
|
+
/**
|
|
119
|
+
* Validate the configured license and return license information.
|
|
120
|
+
*
|
|
121
|
+
* Reflects the current server-backed validation state. The actual network
|
|
122
|
+
* validation happens in the background via `LicenseClient`, and only the
|
|
123
|
+
* configured key (env var) is ever validated — passing any other key
|
|
124
|
+
* returns invalid.
|
|
125
|
+
*
|
|
126
|
+
* @param licenseKey - Optional key to check; must match the configured key.
|
|
127
|
+
* @returns License information
|
|
128
|
+
*/
|
|
129
|
+
export declare function validateLicense(licenseKey?: string): LicenseInfo;
|
|
130
|
+
/**
|
|
131
|
+
* Check if EE features are enabled (valid or pending server validation).
|
|
132
|
+
*
|
|
133
|
+
* @returns True if EE features should be enabled
|
|
134
|
+
*/
|
|
135
|
+
export declare function isLicenseValid(): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* @deprecated Use `isLicenseValid()` instead. This alias is provided for backward compatibility.
|
|
138
|
+
*/
|
|
139
|
+
export declare const isEELicenseValid: typeof isLicenseValid;
|
|
140
|
+
/**
|
|
141
|
+
* Check if a specific EE feature is enabled by the license entitlements.
|
|
142
|
+
*
|
|
143
|
+
* @param feature - Feature name to check (e.g. 'rbac', 'fga', 'sso')
|
|
144
|
+
* @returns True if the feature is enabled
|
|
145
|
+
*/
|
|
146
|
+
export declare function isFeatureEnabled(feature: string): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Get the current license information.
|
|
149
|
+
*
|
|
150
|
+
* @returns License info or null if no license key is configured
|
|
151
|
+
*/
|
|
152
|
+
export declare function getLicenseInfo(): LicenseInfo | null;
|
|
153
|
+
export declare function getSafeLicenseSummary(): SafeLicenseSummary;
|
|
154
|
+
export declare function warnIfDevEENeedsLicense(): void;
|
|
155
|
+
/**
|
|
156
|
+
* Clear the license cache (useful for testing).
|
|
157
|
+
* Resets the shared client so the next check re-reads env vars.
|
|
158
|
+
*/
|
|
159
|
+
export declare function clearLicenseCache(): void;
|
|
160
|
+
/**
|
|
161
|
+
* Check if running in a development/testing environment.
|
|
162
|
+
* In dev, EE features work without a license per the ee/LICENSE terms.
|
|
163
|
+
*/
|
|
164
|
+
export declare function isDevEnvironment(): boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Check if EE features should be active.
|
|
167
|
+
* Returns true if running in dev/test environment (always allowed) or if a valid license is present.
|
|
168
|
+
*/
|
|
169
|
+
export declare function isEEEnabled(): boolean;
|
|
170
|
+
export {};
|
|
171
|
+
//# sourceMappingURL=license.d.ts.map
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User provider interface for authentication.
|
|
3
|
+
* Enables user awareness in Studio.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Base user type for authentication.
|
|
7
|
+
*/
|
|
8
|
+
export interface User {
|
|
9
|
+
/** Unique user identifier */
|
|
10
|
+
id: string;
|
|
11
|
+
/** User email address */
|
|
12
|
+
email?: string;
|
|
13
|
+
/** Display name */
|
|
14
|
+
name?: string;
|
|
15
|
+
/** Avatar URL */
|
|
16
|
+
avatarUrl?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Provider interface for user awareness in Studio.
|
|
20
|
+
*
|
|
21
|
+
* Implement this interface to enable:
|
|
22
|
+
* - Current user display in header
|
|
23
|
+
* - User menu with profile info
|
|
24
|
+
* - User context in API calls
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* class MyUserProvider implements IUserProvider {
|
|
29
|
+
* async getCurrentUser(request: Request) {
|
|
30
|
+
* const session = await this.getSession(request);
|
|
31
|
+
* if (!session) return null;
|
|
32
|
+
* return this.db.getUser(session.userId);
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* async getUser(userId: string) {
|
|
36
|
+
* return this.db.getUser(userId);
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export interface IUserProvider<TUser extends User = User> {
|
|
42
|
+
/**
|
|
43
|
+
* Get current user from request (session cookie, token, etc.)
|
|
44
|
+
*
|
|
45
|
+
* @param request - Incoming HTTP request
|
|
46
|
+
* @returns User object or null if not authenticated
|
|
47
|
+
*/
|
|
48
|
+
getCurrentUser(request: Request): Promise<TUser | null>;
|
|
49
|
+
/**
|
|
50
|
+
* Get user by ID.
|
|
51
|
+
*
|
|
52
|
+
* @param userId - User identifier
|
|
53
|
+
* @returns User object or null if not found
|
|
54
|
+
*/
|
|
55
|
+
getUser(userId: string): Promise<TUser | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Optional: Get multiple users by ID.
|
|
58
|
+
* Implement for efficient batch loading in user enrichment flows.
|
|
59
|
+
*
|
|
60
|
+
* @param userIds - User identifiers
|
|
61
|
+
* @returns User objects for the requested IDs (null for missing users, order preserved)
|
|
62
|
+
*/
|
|
63
|
+
getUsers?(userIds: string[]): Promise<Array<TUser | null>>;
|
|
64
|
+
/**
|
|
65
|
+
* Optional: Get URL to user's profile page.
|
|
66
|
+
*
|
|
67
|
+
* @param user - User object
|
|
68
|
+
* @returns URL string to profile
|
|
69
|
+
*/
|
|
70
|
+
getUserProfileUrl?(user: TUser): string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* SSO provider interface for EE authentication.
|
|
74
|
+
* Enables single sign-on flows in Studio.
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* Configuration for rendering a login button.
|
|
78
|
+
*/
|
|
79
|
+
export interface SSOLoginConfig {
|
|
80
|
+
/** Provider identifier (e.g., 'mastra', 'auth0', 'okta') */
|
|
81
|
+
provider: string;
|
|
82
|
+
/** Button text (e.g., 'Sign in with Mastra') */
|
|
83
|
+
text: string;
|
|
84
|
+
/** Optional icon URL */
|
|
85
|
+
icon?: string;
|
|
86
|
+
/** Optional description explaining the auth requirement and what credentials to use */
|
|
87
|
+
description?: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Result of an SSO callback exchange.
|
|
91
|
+
*/
|
|
92
|
+
export interface SSOCallbackResult<TUser> {
|
|
93
|
+
/** Authenticated user */
|
|
94
|
+
user: TUser;
|
|
95
|
+
/** OAuth tokens */
|
|
96
|
+
tokens: {
|
|
97
|
+
/** Access token for API calls */
|
|
98
|
+
accessToken: string;
|
|
99
|
+
/** Refresh token for token renewal */
|
|
100
|
+
refreshToken?: string;
|
|
101
|
+
/** ID token with user claims */
|
|
102
|
+
idToken?: string;
|
|
103
|
+
/** Token expiration time */
|
|
104
|
+
expiresAt?: Date;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Session cookies to set in the response.
|
|
108
|
+
* Providers using encrypted cookie sessions (like AuthKit) should populate this.
|
|
109
|
+
*/
|
|
110
|
+
cookies?: string[];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Provider interface for SSO authentication.
|
|
114
|
+
*
|
|
115
|
+
* Implement this interface to enable:
|
|
116
|
+
* - SSO login button in Studio
|
|
117
|
+
* - OAuth/OIDC redirect flows
|
|
118
|
+
* - Token exchange on callback
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* class Auth0SSOProvider implements ISSOProvider {
|
|
123
|
+
* getLoginUrl(redirectUri: string, state: string) {
|
|
124
|
+
* const params = new URLSearchParams({
|
|
125
|
+
* client_id: this.clientId,
|
|
126
|
+
* redirect_uri: redirectUri,
|
|
127
|
+
* response_type: 'code',
|
|
128
|
+
* scope: 'openid profile email',
|
|
129
|
+
* state,
|
|
130
|
+
* });
|
|
131
|
+
* return `https://${this.domain}/authorize?${params}`;
|
|
132
|
+
* }
|
|
133
|
+
*
|
|
134
|
+
* async handleCallback(code: string, state: string) {
|
|
135
|
+
* const tokens = await this.exchangeCode(code);
|
|
136
|
+
* const user = await this.getUserInfo(tokens.accessToken);
|
|
137
|
+
* return { user, tokens };
|
|
138
|
+
* }
|
|
139
|
+
*
|
|
140
|
+
* getLoginButtonConfig() {
|
|
141
|
+
* return { provider: 'auth0', text: 'Sign in with Auth0' };
|
|
142
|
+
* }
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export interface ISSOProvider<TUser = unknown> {
|
|
147
|
+
/**
|
|
148
|
+
* Get URL to redirect user to for login.
|
|
149
|
+
*
|
|
150
|
+
* @param redirectUri - Callback URL after authentication
|
|
151
|
+
* @param state - CSRF protection state parameter
|
|
152
|
+
* @returns Full URL to redirect user to
|
|
153
|
+
*/
|
|
154
|
+
getLoginUrl(redirectUri: string, state: string): string | Promise<string>;
|
|
155
|
+
/**
|
|
156
|
+
* Handle OAuth callback, exchange code for tokens and user.
|
|
157
|
+
*
|
|
158
|
+
* @param code - Authorization code from callback
|
|
159
|
+
* @param state - State parameter for CSRF validation
|
|
160
|
+
* @returns User and tokens
|
|
161
|
+
*/
|
|
162
|
+
handleCallback(code: string, state: string): Promise<SSOCallbackResult<TUser>>;
|
|
163
|
+
/**
|
|
164
|
+
* Optional: Get logout URL if provider supports it.
|
|
165
|
+
*
|
|
166
|
+
* @param redirectUri - URL to redirect to after logout
|
|
167
|
+
* @param request - Optional request to extract session info (e.g., for WorkOS sid)
|
|
168
|
+
* @returns Logout URL, null if no active session, or undefined if not implemented
|
|
169
|
+
*/
|
|
170
|
+
getLogoutUrl?(redirectUri: string, request?: Request): string | null | Promise<string | null>;
|
|
171
|
+
/**
|
|
172
|
+
* Get configuration for rendering login button in UI.
|
|
173
|
+
*
|
|
174
|
+
* @returns Login button configuration
|
|
175
|
+
*/
|
|
176
|
+
getLoginButtonConfig(): SSOLoginConfig;
|
|
177
|
+
/**
|
|
178
|
+
* Optional: Get cookies to set during login redirect.
|
|
179
|
+
* Used by PKCE-enabled providers to store code verifier.
|
|
180
|
+
*
|
|
181
|
+
* @param redirectUri - OAuth callback URL
|
|
182
|
+
* @param state - State parameter
|
|
183
|
+
* @returns Array of Set-Cookie header values, or undefined
|
|
184
|
+
*/
|
|
185
|
+
getLoginCookies?(redirectUri: string, state: string): string[] | undefined;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Credentials provider interface for authentication.
|
|
189
|
+
* Enables email/password sign-in and sign-up in Studio.
|
|
190
|
+
*/
|
|
191
|
+
/**
|
|
192
|
+
* Result of a successful credentials operation.
|
|
193
|
+
*/
|
|
194
|
+
export interface CredentialsResult<TUser = User> {
|
|
195
|
+
/** The authenticated user */
|
|
196
|
+
user: TUser;
|
|
197
|
+
/** Optional session token */
|
|
198
|
+
token?: string;
|
|
199
|
+
/** Optional cookies to set on the response (e.g., session cookies) */
|
|
200
|
+
cookies?: string[];
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Provider interface for credentials-based authentication in Studio.
|
|
204
|
+
*
|
|
205
|
+
* Implement this interface to enable:
|
|
206
|
+
* - Email/password sign-in
|
|
207
|
+
* - Email/password sign-up
|
|
208
|
+
* - Password reset (optional)
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* class MyCredentialsProvider implements ICredentialsProvider {
|
|
213
|
+
* async signIn(email: string, password: string, request: Request) {
|
|
214
|
+
* const user = await this.validateCredentials(email, password);
|
|
215
|
+
* if (!user) throw new Error('Invalid credentials');
|
|
216
|
+
* return { user };
|
|
217
|
+
* }
|
|
218
|
+
*
|
|
219
|
+
* async signUp(email: string, password: string, name: string | undefined, request: Request) {
|
|
220
|
+
* const user = await this.createUser({ email, password, name });
|
|
221
|
+
* return { user };
|
|
222
|
+
* }
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
export interface ICredentialsProvider<TUser extends User = User> {
|
|
227
|
+
/**
|
|
228
|
+
* Sign in with email and password.
|
|
229
|
+
*
|
|
230
|
+
* @param email - User email
|
|
231
|
+
* @param password - User password
|
|
232
|
+
* @param request - Incoming HTTP request (for setting cookies, etc.)
|
|
233
|
+
* @returns Result with user and optional token
|
|
234
|
+
* @throws Error if credentials are invalid
|
|
235
|
+
*/
|
|
236
|
+
signIn(email: string, password: string, request: Request): Promise<CredentialsResult<TUser>>;
|
|
237
|
+
/**
|
|
238
|
+
* Sign up with email and password.
|
|
239
|
+
*
|
|
240
|
+
* @param email - User email
|
|
241
|
+
* @param password - User password
|
|
242
|
+
* @param name - Optional display name
|
|
243
|
+
* @param request - Incoming HTTP request (for setting cookies, etc.)
|
|
244
|
+
* @returns Result with new user and optional token
|
|
245
|
+
* @throws Error if sign up fails (e.g., email already exists)
|
|
246
|
+
*/
|
|
247
|
+
signUp(email: string, password: string, name: string | undefined, request: Request): Promise<CredentialsResult<TUser>>;
|
|
248
|
+
/**
|
|
249
|
+
* Optional: Request password reset.
|
|
250
|
+
*
|
|
251
|
+
* @param email - User email
|
|
252
|
+
* @returns Promise that resolves when reset email is sent
|
|
253
|
+
*/
|
|
254
|
+
requestPasswordReset?(email: string): Promise<void>;
|
|
255
|
+
/**
|
|
256
|
+
* Optional: Reset password with token.
|
|
257
|
+
*
|
|
258
|
+
* @param token - Reset token from email
|
|
259
|
+
* @param newPassword - New password
|
|
260
|
+
* @returns Promise that resolves when password is reset
|
|
261
|
+
*/
|
|
262
|
+
resetPassword?(token: string, newPassword: string): Promise<void>;
|
|
263
|
+
/**
|
|
264
|
+
* Optional: Check if sign-up is enabled.
|
|
265
|
+
* Defaults to true if not implemented.
|
|
266
|
+
*
|
|
267
|
+
* Use this to disable public registration while still allowing sign-in.
|
|
268
|
+
*
|
|
269
|
+
* @returns Whether sign-up is enabled
|
|
270
|
+
*/
|
|
271
|
+
isSignUpEnabled?(): boolean;
|
|
272
|
+
}
|
|
273
|
+
export * from './session/index.js';
|
|
274
|
+
export * from './provider/index.js';
|
|
275
|
+
export * from './types/index.js';
|
|
276
|
+
export * from './ee/index.js';
|
|
277
|
+
//# sourceMappingURL=index.d.ts.map
|