@happyvertical/smrt-users 0.30.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/AGENTS.md +85 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +459 -0
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/chunks/TerminalAuthService-DoAMQ_yn.js +5118 -0
- package/dist/chunks/TerminalAuthService-DoAMQ_yn.js.map +1 -0
- package/dist/chunks/index-DkoYIvIu.js +169 -0
- package/dist/chunks/index-DkoYIvIu.js.map +1 -0
- package/dist/collections/CliAuthRequestCollection.d.ts +19 -0
- package/dist/collections/CliAuthRequestCollection.d.ts.map +1 -0
- package/dist/collections/GroupCollection.d.ts +17 -0
- package/dist/collections/GroupCollection.d.ts.map +1 -0
- package/dist/collections/GroupMemberCollection.d.ts +43 -0
- package/dist/collections/GroupMemberCollection.d.ts.map +1 -0
- package/dist/collections/GroupRoleCollection.d.ts +33 -0
- package/dist/collections/GroupRoleCollection.d.ts.map +1 -0
- package/dist/collections/MagicLinkTokenCollection.d.ts +26 -0
- package/dist/collections/MagicLinkTokenCollection.d.ts.map +1 -0
- package/dist/collections/MembershipCollection.d.ts +38 -0
- package/dist/collections/MembershipCollection.d.ts.map +1 -0
- package/dist/collections/MembershipOverrideCollection.d.ts +55 -0
- package/dist/collections/MembershipOverrideCollection.d.ts.map +1 -0
- package/dist/collections/PermissionCollection.d.ts +34 -0
- package/dist/collections/PermissionCollection.d.ts.map +1 -0
- package/dist/collections/RoleCollection.d.ts +29 -0
- package/dist/collections/RoleCollection.d.ts.map +1 -0
- package/dist/collections/RolePermissionCollection.d.ts +33 -0
- package/dist/collections/RolePermissionCollection.d.ts.map +1 -0
- package/dist/collections/SessionCollection.d.ts +82 -0
- package/dist/collections/SessionCollection.d.ts.map +1 -0
- package/dist/collections/TenantCollection.d.ts +119 -0
- package/dist/collections/TenantCollection.d.ts.map +1 -0
- package/dist/collections/TenantPermissionOverrideCollection.d.ts +111 -0
- package/dist/collections/TenantPermissionOverrideCollection.d.ts.map +1 -0
- package/dist/collections/UserCollection.d.ts +116 -0
- package/dist/collections/UserCollection.d.ts.map +1 -0
- package/dist/collections/index.d.ts +19 -0
- package/dist/collections/index.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1482 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +5216 -0
- package/dist/models/CliAuthRequest.d.ts +25 -0
- package/dist/models/CliAuthRequest.d.ts.map +1 -0
- package/dist/models/Group.d.ts +34 -0
- package/dist/models/Group.d.ts.map +1 -0
- package/dist/models/GroupMember.d.ts +29 -0
- package/dist/models/GroupMember.d.ts.map +1 -0
- package/dist/models/GroupRole.d.ts +29 -0
- package/dist/models/GroupRole.d.ts.map +1 -0
- package/dist/models/MagicLinkToken.d.ts +22 -0
- package/dist/models/MagicLinkToken.d.ts.map +1 -0
- package/dist/models/Membership.d.ts +48 -0
- package/dist/models/Membership.d.ts.map +1 -0
- package/dist/models/MembershipOverride.d.ts +50 -0
- package/dist/models/MembershipOverride.d.ts.map +1 -0
- package/dist/models/Permission.d.ts +79 -0
- package/dist/models/Permission.d.ts.map +1 -0
- package/dist/models/Role.d.ts +67 -0
- package/dist/models/Role.d.ts.map +1 -0
- package/dist/models/RolePermission.d.ts +29 -0
- package/dist/models/RolePermission.d.ts.map +1 -0
- package/dist/models/Session.d.ts +105 -0
- package/dist/models/Session.d.ts.map +1 -0
- package/dist/models/Tenant.d.ts +138 -0
- package/dist/models/Tenant.d.ts.map +1 -0
- package/dist/models/TenantPermissionOverride.d.ts +74 -0
- package/dist/models/TenantPermissionOverride.d.ts.map +1 -0
- package/dist/models/User.d.ts +72 -0
- package/dist/models/User.d.ts.map +1 -0
- package/dist/models/index.d.ts +19 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/playground.d.ts +2 -0
- package/dist/playground.d.ts.map +1 -0
- package/dist/playground.js +139 -0
- package/dist/playground.js.map +1 -0
- package/dist/services/MagicLinkService.d.ts +84 -0
- package/dist/services/MagicLinkService.d.ts.map +1 -0
- package/dist/services/OidcLoginService.d.ts +134 -0
- package/dist/services/OidcLoginService.d.ts.map +1 -0
- package/dist/services/PermissionCatalogService.d.ts +62 -0
- package/dist/services/PermissionCatalogService.d.ts.map +1 -0
- package/dist/services/PermissionResolver.d.ts +150 -0
- package/dist/services/PermissionResolver.d.ts.map +1 -0
- package/dist/services/PostgresPermissionPolicies.d.ts +29 -0
- package/dist/services/PostgresPermissionPolicies.d.ts.map +1 -0
- package/dist/services/SessionPermissionContext.d.ts +43 -0
- package/dist/services/SessionPermissionContext.d.ts.map +1 -0
- package/dist/services/SessionService.d.ts +139 -0
- package/dist/services/SessionService.d.ts.map +1 -0
- package/dist/services/TenantService.d.ts +135 -0
- package/dist/services/TenantService.d.ts.map +1 -0
- package/dist/services/TerminalAuthService.d.ts +189 -0
- package/dist/services/TerminalAuthService.d.ts.map +1 -0
- package/dist/services/index.d.ts +14 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +2744 -0
- package/dist/svelte/components/InviteUserModal.svelte +351 -0
- package/dist/svelte/components/InviteUserModal.svelte.d.ts +17 -0
- package/dist/svelte/components/InviteUserModal.svelte.d.ts.map +1 -0
- package/dist/svelte/components/UserAvatar.svelte +105 -0
- package/dist/svelte/components/UserAvatar.svelte.d.ts +10 -0
- package/dist/svelte/components/UserAvatar.svelte.d.ts.map +1 -0
- package/dist/svelte/components/UserCard.svelte +179 -0
- package/dist/svelte/components/UserCard.svelte.d.ts +18 -0
- package/dist/svelte/components/UserCard.svelte.d.ts.map +1 -0
- package/dist/svelte/components/UserForm.svelte +194 -0
- package/dist/svelte/components/UserForm.svelte.d.ts +18 -0
- package/dist/svelte/components/UserForm.svelte.d.ts.map +1 -0
- package/dist/svelte/components/UserList.svelte +107 -0
- package/dist/svelte/components/UserList.svelte.d.ts +20 -0
- package/dist/svelte/components/UserList.svelte.d.ts.map +1 -0
- package/dist/svelte/components/UserMenu.svelte +326 -0
- package/dist/svelte/components/UserMenu.svelte.d.ts +33 -0
- package/dist/svelte/components/UserMenu.svelte.d.ts.map +1 -0
- package/dist/svelte/components/__tests__/InviteUserModal.test.js +54 -0
- package/dist/svelte/components/__tests__/UserAvatar.test.js +31 -0
- package/dist/svelte/components/__tests__/UserCard.test.js +39 -0
- package/dist/svelte/components/__tests__/UserForm.test.js +50 -0
- package/dist/svelte/components/__tests__/UserList.test.js +48 -0
- package/dist/svelte/components/__tests__/UserMenu.test.js +38 -0
- package/dist/svelte/i18n.d.ts +15 -0
- package/dist/svelte/i18n.d.ts.map +1 -0
- package/dist/svelte/i18n.js +15 -0
- package/dist/svelte/index.d.ts +23 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +27 -0
- package/dist/svelte/playground.d.ts +151 -0
- package/dist/svelte/playground.d.ts.map +1 -0
- package/dist/svelte/playground.js +134 -0
- package/dist/sveltekit/index.d.ts +379 -0
- package/dist/sveltekit/index.d.ts.map +1 -0
- package/dist/sveltekit/resource-list-handler.d.ts +127 -0
- package/dist/sveltekit/resource-list-handler.d.ts.map +1 -0
- package/dist/sveltekit/types.d.ts +31 -0
- package/dist/sveltekit/types.d.ts.map +1 -0
- package/dist/sveltekit.d.ts +2 -0
- package/dist/sveltekit.d.ts.map +1 -0
- package/dist/sveltekit.js +978 -0
- package/dist/sveltekit.js.map +1 -0
- package/dist/types/index.d.ts +61 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/ui.d.ts +10 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +75 -0
- package/dist/ui.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { SmrtClassOptions } from '@happyvertical/smrt-core';
|
|
2
|
+
import { OidcLoginResult, OidcProviderResolutionOptions, OidcTransaction } from '../services/OidcLoginService.js';
|
|
3
|
+
import { TerminalAuthError, TerminalAuthRateLimitError, TerminalAuthService, TerminalAuthServiceOptions } from '../services/TerminalAuthService.js';
|
|
4
|
+
export { type CliResource, type CommandDefinition, type CommandKind, type CommandPolicyContext, type CommandScope, type CreateResourceListHandlerOptions, createResourceListHandler, InvalidBearerError, type ResolvedSession, type ResourceListResponseBody, } from './resource-list-handler.js';
|
|
5
|
+
export { defaultSessionLocals, type SessionLocals } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Options for session handler
|
|
8
|
+
*/
|
|
9
|
+
export interface SessionHandlerOptions extends SmrtClassOptions {
|
|
10
|
+
/** Cookie name (default: 'sid') */
|
|
11
|
+
cookieName?: string;
|
|
12
|
+
/** Session TTL in seconds (default: 7 days) */
|
|
13
|
+
ttl?: number;
|
|
14
|
+
/** Paths to skip session loading (e.g., '/api/health') */
|
|
15
|
+
skipPaths?: string[];
|
|
16
|
+
/** Whether to auto-extend sessions on each request (default: false) */
|
|
17
|
+
autoExtend?: boolean;
|
|
18
|
+
/** Cookie domain (default: undefined, uses request domain) */
|
|
19
|
+
cookieDomain?: string;
|
|
20
|
+
/** Cookie path (default: '/') */
|
|
21
|
+
cookiePath?: string;
|
|
22
|
+
/** Whether cookies are secure (default: true in production) */
|
|
23
|
+
cookieSecure?: boolean;
|
|
24
|
+
/** SameSite cookie attribute (default: 'lax') */
|
|
25
|
+
cookieSameSite?: 'strict' | 'lax' | 'none';
|
|
26
|
+
/** Whether to enter smrt-tenancy request context when tenant data exists */
|
|
27
|
+
enterTenantContext?: boolean;
|
|
28
|
+
/** Whether to enforce Postgres RLS via request-scoped transactions */
|
|
29
|
+
postgresRls?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* SvelteKit Handle type (minimal definition to avoid requiring @sveltejs/kit as dependency)
|
|
33
|
+
*/
|
|
34
|
+
type HandleInput = {
|
|
35
|
+
event: {
|
|
36
|
+
cookies: {
|
|
37
|
+
get: (name: string) => string | undefined;
|
|
38
|
+
set: (name: string, value: string, options?: Record<string, unknown>) => void;
|
|
39
|
+
delete: (name: string, options?: Record<string, unknown>) => void;
|
|
40
|
+
};
|
|
41
|
+
locals: Record<string, unknown>;
|
|
42
|
+
url: {
|
|
43
|
+
pathname: string;
|
|
44
|
+
protocol?: string;
|
|
45
|
+
};
|
|
46
|
+
request: {
|
|
47
|
+
headers: Headers;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
resolve: (event: unknown) => Promise<Response>;
|
|
51
|
+
};
|
|
52
|
+
type Handle = (input: HandleInput) => Promise<Response>;
|
|
53
|
+
type SvelteKitRequestEvent = {
|
|
54
|
+
cookies: HandleInput['event']['cookies'];
|
|
55
|
+
getClientAddress?: () => string;
|
|
56
|
+
locals?: Record<string, unknown>;
|
|
57
|
+
params?: Record<string, string | undefined>;
|
|
58
|
+
request: Request;
|
|
59
|
+
url: URL;
|
|
60
|
+
};
|
|
61
|
+
type OidcProviderResolver = string | ((event: SvelteKitRequestEvent) => string | undefined);
|
|
62
|
+
type OidcStringResolver<T> = T | ((result: OidcLoginResult, event: SvelteKitRequestEvent) => T | Promise<T>);
|
|
63
|
+
export interface OidcSvelteKitOptions extends SmrtClassOptions, OidcProviderResolutionOptions {
|
|
64
|
+
/** Optional fetch override for tests or custom runtimes. */
|
|
65
|
+
fetch?: typeof fetch;
|
|
66
|
+
/** JWT clock tolerance passed to jose. */
|
|
67
|
+
clockTolerance?: number | string;
|
|
68
|
+
/** Provider name, or a resolver. Defaults to event.params.provider. */
|
|
69
|
+
provider?: OidcProviderResolver;
|
|
70
|
+
/** Callback path used when provider.redirectUri is omitted. */
|
|
71
|
+
callbackPath?: string | ((providerName: string) => string);
|
|
72
|
+
/** Query parameter used to preserve post-login redirects. */
|
|
73
|
+
returnToParam?: string;
|
|
74
|
+
/** Prefix for the temporary OIDC transaction cookie. */
|
|
75
|
+
transactionCookiePrefix?: string;
|
|
76
|
+
/** Temporary transaction cookie TTL in seconds. Default: 10 minutes. */
|
|
77
|
+
transactionTtl?: number;
|
|
78
|
+
/** Cookie path for the temporary OIDC transaction. */
|
|
79
|
+
transactionCookiePath?: string;
|
|
80
|
+
/** Secure flag for the temporary OIDC transaction cookie. */
|
|
81
|
+
transactionCookieSecure?: boolean;
|
|
82
|
+
/** SameSite value for the temporary OIDC transaction cookie. */
|
|
83
|
+
transactionCookieSameSite?: 'strict' | 'lax' | 'none';
|
|
84
|
+
/** HMAC secret for transaction cookie integrity. Defaults to clientSecret. */
|
|
85
|
+
transactionCookieSecret?: string;
|
|
86
|
+
/** Session cookie name. Defaults to sid. */
|
|
87
|
+
sessionCookieName?: string;
|
|
88
|
+
/** Session cookie path. Defaults to /. */
|
|
89
|
+
sessionCookiePath?: string;
|
|
90
|
+
/** Secure flag for the session cookie. Defaults to true on HTTPS. */
|
|
91
|
+
sessionCookieSecure?: boolean;
|
|
92
|
+
/** SameSite value for the session cookie. */
|
|
93
|
+
sessionCookieSameSite?: 'strict' | 'lax' | 'none';
|
|
94
|
+
/** Session TTL in seconds. Defaults to the package session default. */
|
|
95
|
+
sessionTtl?: number;
|
|
96
|
+
/** Optional tenant to bind to the session. */
|
|
97
|
+
tenantId?: OidcStringResolver<string | null | undefined>;
|
|
98
|
+
/** Redirect target after successful callback. */
|
|
99
|
+
successRedirect?: OidcStringResolver<string>;
|
|
100
|
+
/** Redirect target after failed callback. If omitted, failures return 401. */
|
|
101
|
+
failureRedirect?: string | ((error: unknown, event: SvelteKitRequestEvent) => string);
|
|
102
|
+
}
|
|
103
|
+
export interface BeginOidcLoginResult {
|
|
104
|
+
providerName: string;
|
|
105
|
+
transaction: OidcTransaction;
|
|
106
|
+
url: URL;
|
|
107
|
+
}
|
|
108
|
+
export interface CompleteOidcLoginResult extends OidcLoginResult {
|
|
109
|
+
providerName: string;
|
|
110
|
+
returnTo?: string;
|
|
111
|
+
sessionId: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Creates a SvelteKit handle hook for session management.
|
|
115
|
+
*
|
|
116
|
+
* This hook:
|
|
117
|
+
* 1. Reads the session cookie
|
|
118
|
+
* 2. Loads session context (user + permissions) if valid
|
|
119
|
+
* 3. Populates event.locals with user, permissions, tenantId, sessionId
|
|
120
|
+
* 4. Optionally extends session on each request
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* // hooks.server.ts
|
|
125
|
+
* import { createSessionHandler } from '@happyvertical/smrt-users/sveltekit';
|
|
126
|
+
*
|
|
127
|
+
* const sessionHandler = createSessionHandler({
|
|
128
|
+
* db: { type: 'sqlite', url: 'app.db' },
|
|
129
|
+
* cookieName: 'sid',
|
|
130
|
+
* ttl: 7 * 24 * 60 * 60, // 7 days
|
|
131
|
+
* skipPaths: ['/api/health', '/api/public'],
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* export const handle = sessionHandler;
|
|
135
|
+
* // Or with sequence:
|
|
136
|
+
* // export const handle = sequence(sessionHandler, otherHandler);
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export declare function createSessionHandler(options: SessionHandlerOptions): Handle;
|
|
140
|
+
/**
|
|
141
|
+
* Options for creating a session cookie
|
|
142
|
+
*/
|
|
143
|
+
export interface CreateSessionCookieOptions {
|
|
144
|
+
/** Session TTL in seconds (default: 7 days) */
|
|
145
|
+
ttl?: number;
|
|
146
|
+
/** User agent string */
|
|
147
|
+
userAgent?: string;
|
|
148
|
+
/** Client IP address */
|
|
149
|
+
ipAddress?: string;
|
|
150
|
+
/** Custom session data */
|
|
151
|
+
data?: Record<string, unknown>;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Helper to create a session and set the cookie after login.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* // +page.server.ts
|
|
159
|
+
* import { createSessionCookie } from '@happyvertical/smrt-users/sveltekit';
|
|
160
|
+
* import { redirect } from '@sveltejs/kit';
|
|
161
|
+
*
|
|
162
|
+
* export const actions = {
|
|
163
|
+
* login: async (event) => {
|
|
164
|
+
* // Validate credentials...
|
|
165
|
+
* const user = await validateLogin(email, password);
|
|
166
|
+
*
|
|
167
|
+
* await createSessionCookie(event, user.id, tenantId, {
|
|
168
|
+
* db: { type: 'sqlite', url: 'app.db' },
|
|
169
|
+
* ipAddress: event.getClientAddress(),
|
|
170
|
+
* userAgent: event.request.headers.get('user-agent') ?? '',
|
|
171
|
+
* });
|
|
172
|
+
*
|
|
173
|
+
* throw redirect(303, '/dashboard');
|
|
174
|
+
* }
|
|
175
|
+
* };
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
export declare function createSessionCookie(event: HandleInput['event'], userId: string, tenantId: string | undefined, options: SmrtClassOptions & CreateSessionCookieOptions & {
|
|
179
|
+
cookieName?: string;
|
|
180
|
+
cookiePath?: string;
|
|
181
|
+
cookieSecure?: boolean;
|
|
182
|
+
cookieSameSite?: 'strict' | 'lax' | 'none';
|
|
183
|
+
}): Promise<string>;
|
|
184
|
+
/**
|
|
185
|
+
* Helper to destroy a session and delete the cookie on logout.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* // +page.server.ts
|
|
190
|
+
* import { destroySessionCookie } from '@happyvertical/smrt-users/sveltekit';
|
|
191
|
+
* import { redirect } from '@sveltejs/kit';
|
|
192
|
+
*
|
|
193
|
+
* export const actions = {
|
|
194
|
+
* logout: async (event) => {
|
|
195
|
+
* await destroySessionCookie(event, {
|
|
196
|
+
* db: { type: 'sqlite', url: 'app.db' }
|
|
197
|
+
* });
|
|
198
|
+
* throw redirect(303, '/');
|
|
199
|
+
* }
|
|
200
|
+
* };
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
export declare function destroySessionCookie(event: HandleInput['event'], options: SmrtClassOptions & {
|
|
204
|
+
cookieName?: string;
|
|
205
|
+
cookiePath?: string;
|
|
206
|
+
ttl?: number;
|
|
207
|
+
}): Promise<void>;
|
|
208
|
+
/**
|
|
209
|
+
* Helper to switch tenant context for the current session.
|
|
210
|
+
*
|
|
211
|
+
* Returns `false` without switching when there is no session, or — fail-closed
|
|
212
|
+
* (#1400) — when the session's user is not an active member of `tenantId`. The
|
|
213
|
+
* target tenant id is therefore safe to take straight from untrusted form data,
|
|
214
|
+
* but callers MUST honour the boolean result rather than assuming success.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* // +page.server.ts
|
|
219
|
+
* import { switchSessionTenant } from '@happyvertical/smrt-users/sveltekit';
|
|
220
|
+
* import { fail } from '@sveltejs/kit';
|
|
221
|
+
*
|
|
222
|
+
* export const actions = {
|
|
223
|
+
* switchTenant: async (event) => {
|
|
224
|
+
* const data = await event.request.formData();
|
|
225
|
+
* const tenantId = data.get('tenantId') as string;
|
|
226
|
+
*
|
|
227
|
+
* const switched = await switchSessionTenant(event, tenantId, {
|
|
228
|
+
* db: { type: 'sqlite', url: 'app.db' }
|
|
229
|
+
* });
|
|
230
|
+
* if (!switched) {
|
|
231
|
+
* return fail(403, { error: 'Not a member of that tenant.' });
|
|
232
|
+
* }
|
|
233
|
+
*
|
|
234
|
+
* return { success: true };
|
|
235
|
+
* }
|
|
236
|
+
* };
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export declare function switchSessionTenant(event: HandleInput['event'], tenantId: string | null, options: SmrtClassOptions & {
|
|
240
|
+
cookieName?: string;
|
|
241
|
+
ttl?: number;
|
|
242
|
+
}): Promise<boolean>;
|
|
243
|
+
/**
|
|
244
|
+
* Start an OIDC login from a SvelteKit route.
|
|
245
|
+
*
|
|
246
|
+
* Sets a short-lived, HTTP-only transaction cookie containing state, nonce,
|
|
247
|
+
* and PKCE verifier, then returns the provider authorization URL.
|
|
248
|
+
*/
|
|
249
|
+
export declare function beginOidcLogin(event: SvelteKitRequestEvent, options: OidcSvelteKitOptions): Promise<BeginOidcLoginResult>;
|
|
250
|
+
/**
|
|
251
|
+
* Complete an OIDC callback, create or update the SMRT user/profile, and set
|
|
252
|
+
* the session cookie.
|
|
253
|
+
*/
|
|
254
|
+
export declare function completeOidcLogin(event: SvelteKitRequestEvent, options: OidcSvelteKitOptions): Promise<CompleteOidcLoginResult>;
|
|
255
|
+
/**
|
|
256
|
+
* Create a SvelteKit GET handler that redirects to an OIDC provider.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* // src/routes/auth/[provider]/login/+server.ts
|
|
261
|
+
* import { createOidcLoginHandler } from '@happyvertical/smrt-users/sveltekit';
|
|
262
|
+
*
|
|
263
|
+
* export const GET = createOidcLoginHandler({
|
|
264
|
+
* db: { type: 'postgres', url: process.env.DATABASE_URL! },
|
|
265
|
+
* });
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
export declare function createOidcLoginHandler(options: OidcSvelteKitOptions): (event: SvelteKitRequestEvent) => Promise<Response>;
|
|
269
|
+
/**
|
|
270
|
+
* Create a SvelteKit GET handler for the provider callback.
|
|
271
|
+
*/
|
|
272
|
+
export declare function createOidcCallbackHandler(options: OidcSvelteKitOptions): (event: SvelteKitRequestEvent) => Promise<Response>;
|
|
273
|
+
/**
|
|
274
|
+
* Pull `Bearer <token>` out of an `Authorization` header. Returns `null` if
|
|
275
|
+
* the header is missing or malformed.
|
|
276
|
+
*/
|
|
277
|
+
export declare function parseBearerToken(authorization: string | null): string | null;
|
|
278
|
+
/** Options for the terminal-auth start handler. */
|
|
279
|
+
export interface CreateTerminalAuthStartHandlerOptions extends TerminalAuthServiceOptions {
|
|
280
|
+
/**
|
|
281
|
+
* Override the verification origin returned to the CLI (e.g. when the
|
|
282
|
+
* public origin differs from the request origin behind a proxy). Defaults
|
|
283
|
+
* to `event.url.origin`.
|
|
284
|
+
*/
|
|
285
|
+
verificationOrigin?: string | ((event: SvelteKitRequestEvent) => string);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Create a SvelteKit POST handler that starts a new terminal-auth request.
|
|
289
|
+
* Mount under `/api/cli/auth/start/+server.ts`:
|
|
290
|
+
*
|
|
291
|
+
* ```ts
|
|
292
|
+
* export const POST = createTerminalAuthStartHandler({
|
|
293
|
+
* db: { type: 'postgres', url: process.env.DATABASE_URL! },
|
|
294
|
+
* userCodePrefix: 'WG',
|
|
295
|
+
* });
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
export declare function createTerminalAuthStartHandler(options: CreateTerminalAuthStartHandlerOptions): (event: SvelteKitRequestEvent) => Promise<Response>;
|
|
299
|
+
/**
|
|
300
|
+
* Create a SvelteKit POST handler that exchanges a polling device code for a
|
|
301
|
+
* bearer token once the request has been approved. Mount under
|
|
302
|
+
* `/api/cli/auth/token/+server.ts`.
|
|
303
|
+
*/
|
|
304
|
+
export declare function createTerminalAuthTokenHandler(options: TerminalAuthServiceOptions): (event: SvelteKitRequestEvent) => Promise<Response>;
|
|
305
|
+
/**
|
|
306
|
+
* Create a SvelteKit DELETE handler that revokes the bearer token in the
|
|
307
|
+
* request's `Authorization` header. Always returns `{ authenticated: false }`
|
|
308
|
+
* — does not leak whether the token was actually live, by design.
|
|
309
|
+
*/
|
|
310
|
+
export declare function createBearerSessionDeleteHandler(options: TerminalAuthServiceOptions): (event: SvelteKitRequestEvent) => Promise<Response>;
|
|
311
|
+
/**
|
|
312
|
+
* Look up the session associated with a bearer token. Use from
|
|
313
|
+
* `hooks.server.ts` to resolve `Authorization: Bearer <sid>` headers
|
|
314
|
+
* alongside cookie-based sessions.
|
|
315
|
+
*/
|
|
316
|
+
export declare function loadBearerSessionContext(token: string, options: TerminalAuthServiceOptions): Promise<import('../index.js').SessionContext | null>;
|
|
317
|
+
/** Shape passed back to `+page.server.ts` `load`. */
|
|
318
|
+
export interface TerminalLoginPageData {
|
|
319
|
+
userCode: string;
|
|
320
|
+
requestStatus: string | null;
|
|
321
|
+
}
|
|
322
|
+
/** Shape returned by the approve action on success. */
|
|
323
|
+
export interface TerminalLoginApproveSuccess {
|
|
324
|
+
approved: true;
|
|
325
|
+
requestStatus: string;
|
|
326
|
+
userCode: string;
|
|
327
|
+
}
|
|
328
|
+
/** Shape returned by the approve action on failure (HTTP 4xx). */
|
|
329
|
+
export interface TerminalLoginApproveFailure {
|
|
330
|
+
status: number;
|
|
331
|
+
error: string;
|
|
332
|
+
userCode: string;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Page-server helper for the terminal-login approval page. Returns
|
|
336
|
+
* `{ load, approve }` you can spread into a `+page.server.ts` module.
|
|
337
|
+
*
|
|
338
|
+
* `approve` is the action implementation, not a wrapped object — wire it up
|
|
339
|
+
* as you like, e.g. `export const actions = { approve: handler.approve }`.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```ts
|
|
343
|
+
* // src/routes/terminal-login/+page.server.ts
|
|
344
|
+
* import { mountTerminalLoginPage } from '@happyvertical/smrt-users/sveltekit';
|
|
345
|
+
*
|
|
346
|
+
* const handlers = mountTerminalLoginPage({
|
|
347
|
+
* db: { type: 'postgres', url: process.env.DATABASE_URL! },
|
|
348
|
+
* userCodePrefix: 'WG',
|
|
349
|
+
* requireUser: (event) => Boolean(event.locals.user),
|
|
350
|
+
* resolveUser: (event) => event.locals.user,
|
|
351
|
+
* resolveTenantId: (event) => event.locals.tenantId,
|
|
352
|
+
* });
|
|
353
|
+
*
|
|
354
|
+
* export const load = handlers.load;
|
|
355
|
+
* export const actions = { approve: handlers.approve };
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
export interface MountTerminalLoginPageOptions extends TerminalAuthServiceOptions {
|
|
359
|
+
/** Resolve the authenticated user from `event.locals`. */
|
|
360
|
+
resolveUser: (event: SvelteKitRequestEvent) => {
|
|
361
|
+
id?: string | null;
|
|
362
|
+
email?: string | null;
|
|
363
|
+
} | null | undefined;
|
|
364
|
+
/** Resolve the tenant id from `event.locals`. */
|
|
365
|
+
resolveTenantId: (event: SvelteKitRequestEvent) => string | null | undefined;
|
|
366
|
+
/** Query-string parameter holding the user code on the page URL. */
|
|
367
|
+
codeQueryParam?: string;
|
|
368
|
+
}
|
|
369
|
+
export interface MountedTerminalLoginPage {
|
|
370
|
+
load: (event: SvelteKitRequestEvent) => Promise<TerminalLoginPageData>;
|
|
371
|
+
approve: (event: SvelteKitRequestEvent) => Promise<TerminalLoginApproveSuccess | {
|
|
372
|
+
type: 'failure';
|
|
373
|
+
status: number;
|
|
374
|
+
data: TerminalLoginApproveFailure;
|
|
375
|
+
}>;
|
|
376
|
+
}
|
|
377
|
+
export declare function mountTerminalLoginPage(options: MountTerminalLoginPageOptions): MountedTerminalLoginPage;
|
|
378
|
+
export { TerminalAuthError, TerminalAuthRateLimitError, TerminalAuthService, type TerminalAuthServiceOptions, };
|
|
379
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sveltekit/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { SmartObjectConfig } from '@happyvertical/smrt-core';
|
|
2
|
+
import { TerminalAuthServiceOptions } from '../services/TerminalAuthService.js';
|
|
3
|
+
import { SessionLocals } from './types.js';
|
|
4
|
+
type ApiHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
5
|
+
export type CommandKind = 'crud' | 'custom';
|
|
6
|
+
export type CommandScope = 'item' | 'collection';
|
|
7
|
+
export interface CommandDefinition {
|
|
8
|
+
/** Method name in source casing — source of truth for HTTP routing. */
|
|
9
|
+
methodName: string;
|
|
10
|
+
/** Kebab-case identifier used by the CLI argv parser. */
|
|
11
|
+
commandName: string;
|
|
12
|
+
kind: CommandKind;
|
|
13
|
+
scope: CommandScope;
|
|
14
|
+
httpMethod: ApiHttpMethod;
|
|
15
|
+
/** URL path segments after `/<apiPath>[/<id>]/`. May be empty. */
|
|
16
|
+
pathSegments: string[];
|
|
17
|
+
description?: string;
|
|
18
|
+
/** JSONSchema describing the command's argv-flag surface. */
|
|
19
|
+
parameters?: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
export interface CliResource {
|
|
22
|
+
/** Kebab-case identifier; the first positional argument after the CLI name. */
|
|
23
|
+
slug: string;
|
|
24
|
+
className: string;
|
|
25
|
+
qualifiedName?: string;
|
|
26
|
+
packageName?: string;
|
|
27
|
+
label: string;
|
|
28
|
+
/** Collection segment, no leading slash, no `/api` prefix. */
|
|
29
|
+
apiPath: string;
|
|
30
|
+
commands: CommandDefinition[];
|
|
31
|
+
}
|
|
32
|
+
export interface ResolvedSession {
|
|
33
|
+
user: SessionLocals['user'];
|
|
34
|
+
membership?: SessionLocals['membership'];
|
|
35
|
+
permissions: string[];
|
|
36
|
+
tenantId: string | null;
|
|
37
|
+
sessionId: string | null;
|
|
38
|
+
}
|
|
39
|
+
export interface CommandPolicyContext {
|
|
40
|
+
resource: Omit<CliResource, 'commands'>;
|
|
41
|
+
command: CommandDefinition;
|
|
42
|
+
session: ResolvedSession;
|
|
43
|
+
/**
|
|
44
|
+
* Stable identifiers for policy authors that need more than the
|
|
45
|
+
* caller-facing `resource` view (e.g. package-scoped role checks).
|
|
46
|
+
*/
|
|
47
|
+
classMeta: {
|
|
48
|
+
name: string;
|
|
49
|
+
qualifiedName?: string;
|
|
50
|
+
packageName?: string;
|
|
51
|
+
decoratorConfig: SmartObjectConfig;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export interface ResourceListResponseBody {
|
|
55
|
+
user: {
|
|
56
|
+
authenticated: boolean;
|
|
57
|
+
id?: string;
|
|
58
|
+
};
|
|
59
|
+
warnings: string[];
|
|
60
|
+
resources: CliResource[];
|
|
61
|
+
}
|
|
62
|
+
export interface CreateResourceListHandlerOptions extends TerminalAuthServiceOptions {
|
|
63
|
+
/**
|
|
64
|
+
* Ensures `ObjectRegistry` is populated before the handler walks it.
|
|
65
|
+
*
|
|
66
|
+
* v0.1 escape hatch: the consumer app must trigger its `@smrt()` side
|
|
67
|
+
* effects (typically by importing the generated `smrt-register.ts`).
|
|
68
|
+
* Without this, a fresh request handler process may see an empty
|
|
69
|
+
* registry and return zero resources.
|
|
70
|
+
*/
|
|
71
|
+
ensureRegistry: () => void | Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the caller's session. Defaults to `event.locals` (set by
|
|
74
|
+
* `createSessionHandler` in `hooks.server.ts`) with a `Bearer <token>`
|
|
75
|
+
* fallback for terminal-auth CLI clients.
|
|
76
|
+
*
|
|
77
|
+
* If a bearer token is present but doesn't resolve to a live session,
|
|
78
|
+
* the handler responds 401 — NOT silent anonymous, so a stale CLI token
|
|
79
|
+
* gets a clear signal to re-authenticate.
|
|
80
|
+
*/
|
|
81
|
+
resolveSession?: (event: SveltekitEvent) => Promise<ResolvedSession>;
|
|
82
|
+
/**
|
|
83
|
+
* Per-command permission filter. Default: deny everything when the
|
|
84
|
+
* caller is anonymous; allow everything when authenticated.
|
|
85
|
+
*
|
|
86
|
+
* Note: this is _capability filtering_, not row-level authorization.
|
|
87
|
+
* Per-route handlers remain authoritative for `can user X update record Y`.
|
|
88
|
+
*/
|
|
89
|
+
commandPolicy?: (ctx: CommandPolicyContext) => boolean | Promise<boolean>;
|
|
90
|
+
/**
|
|
91
|
+
* Override the slug derivation. Default: kebab-case of `collection`
|
|
92
|
+
* (which is already plural+lowercase from the manifest generator).
|
|
93
|
+
*/
|
|
94
|
+
resourceSlug?: (meta: {
|
|
95
|
+
className: string;
|
|
96
|
+
collection: string;
|
|
97
|
+
qualifiedName?: string;
|
|
98
|
+
packageName?: string;
|
|
99
|
+
}) => string;
|
|
100
|
+
/**
|
|
101
|
+
* Match the vite plugin's `svelteKit.kebabRoutes` setting. When `true`,
|
|
102
|
+
* custom method URL segments are kebab-cased on the wire (the CLI sends
|
|
103
|
+
* `/discover-from-url`); when `false`, source-cased (`/discoverFromUrl`).
|
|
104
|
+
* Defaults to `false` to match the vite plugin default.
|
|
105
|
+
*/
|
|
106
|
+
kebabRoutes?: boolean;
|
|
107
|
+
}
|
|
108
|
+
type SveltekitEvent = {
|
|
109
|
+
cookies: {
|
|
110
|
+
get: (name: string) => string | undefined;
|
|
111
|
+
};
|
|
112
|
+
locals?: Record<string, unknown>;
|
|
113
|
+
request: Request;
|
|
114
|
+
url: URL;
|
|
115
|
+
};
|
|
116
|
+
export declare function createResourceListHandler(options: CreateResourceListHandlerOptions): (event: SveltekitEvent) => Promise<Response>;
|
|
117
|
+
/**
|
|
118
|
+
* Thrown by the default `resolveSession` when a bearer token is present in
|
|
119
|
+
* the request but doesn't resolve to a live session. The handler catches
|
|
120
|
+
* this and responds 401. Exported so custom `resolveSession` implementations
|
|
121
|
+
* can opt in to the same semantics.
|
|
122
|
+
*/
|
|
123
|
+
export declare class InvalidBearerError extends Error {
|
|
124
|
+
constructor(message?: string);
|
|
125
|
+
}
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=resource-list-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-list-handler.d.ts","sourceRoot":"","sources":["../../src/sveltekit/resource-list-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Membership } from '../models/Membership.js';
|
|
2
|
+
import { User } from '../models/User.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extended locals interface for SvelteKit
|
|
5
|
+
*
|
|
6
|
+
* Add to your app.d.ts:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* declare global {
|
|
9
|
+
* namespace App {
|
|
10
|
+
* interface Locals extends SessionLocals {}
|
|
11
|
+
* }
|
|
12
|
+
* }
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export interface SessionLocals {
|
|
16
|
+
/** The authenticated user (null if not authenticated) */
|
|
17
|
+
user: User | null;
|
|
18
|
+
/** Active membership for the current tenant (null if none) */
|
|
19
|
+
membership?: Membership | null;
|
|
20
|
+
/** User's resolved permissions */
|
|
21
|
+
permissions: string[];
|
|
22
|
+
/** Current tenant context (null if no tenant selected) */
|
|
23
|
+
tenantId: string | null;
|
|
24
|
+
/** Session ID (null if no session) */
|
|
25
|
+
sessionId: string | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Default session locals values
|
|
29
|
+
*/
|
|
30
|
+
export declare const defaultSessionLocals: SessionLocals;
|
|
31
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sveltekit/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,kCAAkC;IAClC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sCAAsC;IACtC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAMlC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sveltekit.d.ts","sourceRoot":"","sources":["../src/sveltekit.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|