@happyvertical/smrt-users 0.31.0 → 0.32.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 +40 -15
- package/dist/chunks/{TerminalAuthService-DoAMQ_yn.js → TerminalAuthService-D5VVPG9e.js} +247 -89
- package/dist/chunks/TerminalAuthService-D5VVPG9e.js.map +1 -0
- package/dist/chunks/{index-DkoYIvIu.js → index-CitgZk-4.js} +10 -10
- package/dist/chunks/{index-DkoYIvIu.js.map → index-CitgZk-4.js.map} +1 -1
- package/dist/collections/GroupMemberCollection.d.ts +9 -0
- package/dist/collections/GroupMemberCollection.d.ts.map +1 -1
- package/dist/collections/SessionCollection.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -100
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +2 -2
- package/dist/services/PermissionResolver.d.ts +24 -3
- package/dist/services/PermissionResolver.d.ts.map +1 -1
- package/dist/services/SessionService.d.ts +42 -5
- package/dist/services/SessionService.d.ts.map +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +6 -6
- package/dist/svelte/components/InviteUserModal.svelte +72 -169
- package/dist/svelte/components/InviteUserModal.svelte.d.ts.map +1 -1
- package/dist/svelte/components/UserCard.svelte +2 -1
- package/dist/svelte/components/UserCard.svelte.d.ts.map +1 -1
- package/dist/svelte/components/UserForm.svelte +11 -4
- package/dist/svelte/components/UserForm.svelte.d.ts.map +1 -1
- package/dist/svelte/components/UserMenu.svelte +100 -25
- package/dist/svelte/components/UserMenu.svelte.d.ts +5 -4
- package/dist/svelte/components/UserMenu.svelte.d.ts.map +1 -1
- package/dist/svelte/components/__tests__/InviteUserModal.test.js +11 -0
- package/dist/svelte/components/__tests__/UserMenu.test.js +45 -0
- package/dist/svelte/components/__tests__/UserStatus.test.js +36 -0
- package/dist/sveltekit/index.d.ts +17 -1
- package/dist/sveltekit/index.d.ts.map +1 -1
- package/dist/sveltekit.js +37 -9
- package/dist/sveltekit.js.map +1 -1
- package/package.json +8 -8
- package/dist/chunks/TerminalAuthService-DoAMQ_yn.js.map +0 -1
|
@@ -35,4 +35,49 @@ describe('UserMenu', () => {
|
|
|
35
35
|
expect(screen.getByRole('menu')).toBeInTheDocument();
|
|
36
36
|
await expectNoA11yViolations(container);
|
|
37
37
|
});
|
|
38
|
+
// Regression for #1399 blocker #1: the menu items were keyboard-unreachable
|
|
39
|
+
// (role="menu" with no roving tabindex / arrow navigation). These assert the
|
|
40
|
+
// WAI-ARIA menu-button keyboard contract end to end.
|
|
41
|
+
const kbProps = {
|
|
42
|
+
user: { name: 'Ada Lovelace', email: 'ada@example.com' },
|
|
43
|
+
};
|
|
44
|
+
it('opens from the trigger and focuses the first item on ArrowDown', async () => {
|
|
45
|
+
render(UserMenu, { props: kbProps });
|
|
46
|
+
screen.getByRole('button', { name: 'User menu' }).focus();
|
|
47
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
48
|
+
const items = screen.getAllByRole('menuitem');
|
|
49
|
+
expect(items).toHaveLength(3);
|
|
50
|
+
expect(document.activeElement).toBe(items[0]);
|
|
51
|
+
});
|
|
52
|
+
it('moves roving focus with ArrowDown/ArrowUp and wraps at the ends', async () => {
|
|
53
|
+
render(UserMenu, { props: kbProps });
|
|
54
|
+
screen.getByRole('button', { name: 'User menu' }).focus();
|
|
55
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
56
|
+
const items = screen.getAllByRole('menuitem');
|
|
57
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
58
|
+
expect(document.activeElement).toBe(items[1]);
|
|
59
|
+
// From the first item, ArrowUp wraps to the last.
|
|
60
|
+
await userEvent.keyboard('{ArrowUp}{ArrowUp}');
|
|
61
|
+
expect(document.activeElement).toBe(items[items.length - 1]);
|
|
62
|
+
});
|
|
63
|
+
it('jumps to the last item with End and the first with Home', async () => {
|
|
64
|
+
render(UserMenu, { props: kbProps });
|
|
65
|
+
screen.getByRole('button', { name: 'User menu' }).focus();
|
|
66
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
67
|
+
const items = screen.getAllByRole('menuitem');
|
|
68
|
+
await userEvent.keyboard('{End}');
|
|
69
|
+
expect(document.activeElement).toBe(items[items.length - 1]);
|
|
70
|
+
await userEvent.keyboard('{Home}');
|
|
71
|
+
expect(document.activeElement).toBe(items[0]);
|
|
72
|
+
});
|
|
73
|
+
it('closes on Escape and restores focus to the trigger', async () => {
|
|
74
|
+
render(UserMenu, { props: kbProps });
|
|
75
|
+
const trigger = screen.getByRole('button', { name: 'User menu' });
|
|
76
|
+
trigger.focus();
|
|
77
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
78
|
+
expect(screen.queryByRole('menu')).not.toBeNull();
|
|
79
|
+
await userEvent.keyboard('{Escape}');
|
|
80
|
+
expect(screen.queryByRole('menu')).toBeNull();
|
|
81
|
+
expect(document.activeElement).toBe(trigger);
|
|
82
|
+
});
|
|
38
83
|
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { UserStatus } from '@happyvertical/smrt-types';
|
|
2
|
+
import { render, screen } from '@happyvertical/smrt-vitest/svelte';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import UserCard from '../UserCard.svelte';
|
|
5
|
+
import UserForm from '../UserForm.svelte';
|
|
6
|
+
const profile = { name: 'Ada Lovelace', email: 'ada@example.com' };
|
|
7
|
+
const user = { email: 'ada@example.com', status: UserStatus.INACTIVE };
|
|
8
|
+
describe('UserForm status options', () => {
|
|
9
|
+
it('offers exactly the UserStatus values — including inactive, never deactivated', () => {
|
|
10
|
+
render(UserForm, { props: { onsubmit: vi.fn() } });
|
|
11
|
+
const select = screen.getByLabelText('Status', {
|
|
12
|
+
hidden: true,
|
|
13
|
+
});
|
|
14
|
+
const optionValues = Array.from(select.options).map((o) => o.value);
|
|
15
|
+
expect(optionValues).toEqual(Object.values(UserStatus));
|
|
16
|
+
expect(optionValues).toContain('inactive');
|
|
17
|
+
expect(optionValues).not.toContain('deactivated');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe('UserCard status styling', () => {
|
|
21
|
+
it('styles an inactive user instead of leaving it unstyled', () => {
|
|
22
|
+
render(UserCard, {
|
|
23
|
+
props: { user, profile, status: 'inactive' },
|
|
24
|
+
});
|
|
25
|
+
const badge = screen.getByText('inactive', { hidden: true });
|
|
26
|
+
expect(badge.className).toContain('status-disabled');
|
|
27
|
+
});
|
|
28
|
+
it('does not recognise the bogus deactivated value', () => {
|
|
29
|
+
render(UserCard, {
|
|
30
|
+
props: { user, profile, status: 'deactivated' },
|
|
31
|
+
});
|
|
32
|
+
const badge = screen.getByText('deactivated', { hidden: true });
|
|
33
|
+
// No status-* style class is applied for a non-enum value.
|
|
34
|
+
expect(badge.className).not.toContain('status-disabled');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -15,7 +15,11 @@ export interface SessionHandlerOptions extends SmrtClassOptions {
|
|
|
15
15
|
skipPaths?: string[];
|
|
16
16
|
/** Whether to auto-extend sessions on each request (default: false) */
|
|
17
17
|
autoExtend?: boolean;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Cookie domain (default: undefined, uses request domain). The session
|
|
20
|
+
* handler only reads the cookie; this is consumed by `createSessionCookie`
|
|
21
|
+
* / `destroySessionCookie` when the same options object is shared with them.
|
|
22
|
+
*/
|
|
19
23
|
cookieDomain?: string;
|
|
20
24
|
/** Cookie path (default: '/') */
|
|
21
25
|
cookiePath?: string;
|
|
@@ -178,6 +182,7 @@ export interface CreateSessionCookieOptions {
|
|
|
178
182
|
export declare function createSessionCookie(event: HandleInput['event'], userId: string, tenantId: string | undefined, options: SmrtClassOptions & CreateSessionCookieOptions & {
|
|
179
183
|
cookieName?: string;
|
|
180
184
|
cookiePath?: string;
|
|
185
|
+
cookieDomain?: string;
|
|
181
186
|
cookieSecure?: boolean;
|
|
182
187
|
cookieSameSite?: 'strict' | 'lax' | 'none';
|
|
183
188
|
}): Promise<string>;
|
|
@@ -203,6 +208,7 @@ export declare function createSessionCookie(event: HandleInput['event'], userId:
|
|
|
203
208
|
export declare function destroySessionCookie(event: HandleInput['event'], options: SmrtClassOptions & {
|
|
204
209
|
cookieName?: string;
|
|
205
210
|
cookiePath?: string;
|
|
211
|
+
cookieDomain?: string;
|
|
206
212
|
ttl?: number;
|
|
207
213
|
}): Promise<void>;
|
|
208
214
|
/**
|
|
@@ -213,6 +219,12 @@ export declare function destroySessionCookie(event: HandleInput['event'], option
|
|
|
213
219
|
* target tenant id is therefore safe to take straight from untrusted form data,
|
|
214
220
|
* but callers MUST honour the boolean result rather than assuming success.
|
|
215
221
|
*
|
|
222
|
+
* Session-id ROTATION (#1354 follow-up): a successful switch into a non-null
|
|
223
|
+
* tenant mints a fresh session and revokes the old one. This helper transparently
|
|
224
|
+
* re-sets the session COOKIE to the new id (same flags), so the old cookie value
|
|
225
|
+
* stops working and the browser carries the rotated id forward. A `null` clear
|
|
226
|
+
* leaves the id (and cookie) unchanged.
|
|
227
|
+
*
|
|
216
228
|
* @example
|
|
217
229
|
* ```typescript
|
|
218
230
|
* // +page.server.ts
|
|
@@ -238,6 +250,10 @@ export declare function destroySessionCookie(event: HandleInput['event'], option
|
|
|
238
250
|
*/
|
|
239
251
|
export declare function switchSessionTenant(event: HandleInput['event'], tenantId: string | null, options: SmrtClassOptions & {
|
|
240
252
|
cookieName?: string;
|
|
253
|
+
cookiePath?: string;
|
|
254
|
+
cookieDomain?: string;
|
|
255
|
+
cookieSecure?: boolean;
|
|
256
|
+
cookieSameSite?: 'strict' | 'lax' | 'none';
|
|
241
257
|
ttl?: number;
|
|
242
258
|
}): Promise<boolean>;
|
|
243
259
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sveltekit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAKL,KAAK,eAAe,EAGpB,KAAK,6BAA6B,EAClC,KAAK,eAAe,EAGrB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAEL,iBAAiB,EACjB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,0BAA0B,EAChC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,gCAAgC,EACrC,yBAAyB,EACzB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,wBAAwB,GAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAItE;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sveltekit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAKL,KAAK,eAAe,EAGpB,KAAK,6BAA6B,EAClC,KAAK,eAAe,EAGrB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAEL,iBAAiB,EACjB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,0BAA0B,EAChC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,gCAAgC,EACrC,yBAAyB,EACzB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,wBAAwB,GAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAItE;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iDAAiD;IACjD,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC3C,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE;QACL,OAAO,EAAE;YACP,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;YAC1C,GAAG,EAAE,CACH,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,IAAI,CAAC;YACV,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;SACnE,CAAC;QACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,GAAG,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7C,OAAO,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,CAAC;KAC/B,CAAC;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChD,CAAC;AAEF,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAExD,KAAK,qBAAqB,GAAG;IAC3B,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;CACV,CAAC;AAEF,KAAK,oBAAoB,GACrB,MAAM,GACN,CAAC,CAAC,KAAK,EAAE,qBAAqB,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;AAE3D,KAAK,kBAAkB,CAAC,CAAC,IACrB,CAAC,GACD,CAAC,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,qBAAqB,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,MAAM,WAAW,oBACf,SAAQ,gBAAgB,EACtB,6BAA6B;IAC/B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAC3D,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,6DAA6D;IAC7D,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,gEAAgE;IAChE,yBAAyB,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACtD,8EAA8E;IAC9E,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,6CAA6C;IAC7C,qBAAqB,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAClD,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,kBAAkB,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACzD,iDAAiD;IACjD,eAAe,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,eAAe,CAAC,EACZ,MAAM,GACN,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,qBAAqB,KAAK,MAAM,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,eAAe,CAAC;IAC7B,GAAG,EAAE,GAAG,CAAC;CACV;AAED,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAwE3E;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AA0BD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,EAAE,gBAAgB,GACvB,0BAA0B,GAAG;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CAC5C,GACF,OAAO,CAAC,MAAM,CAAC,CA2BjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAC3B,OAAO,EAAE,gBAAgB,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACA,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,EAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,EAAE,gBAAgB,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACA,OAAO,CAAC,OAAO,CAAC,CA0ClB;AA+PD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAyB/B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CA0DlC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,IACpD,OAAO,qBAAqB,KAAG,OAAO,CAAC,QAAQ,CAAC,CAI/D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,IACvD,OAAO,qBAAqB,KAAG,OAAO,CAAC,QAAQ,CAAC,CAW/D;AAoCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG5E;AAED,mDAAmD;AACnD,MAAM,WAAW,qCACf,SAAQ,0BAA0B;IAClC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,qBAAqB,KAAK,MAAM,CAAC,CAAC;CAC1E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,qCAAqC,IAEhC,OAAO,qBAAqB,KAAG,OAAO,CAAC,QAAQ,CAAC,CAU/D;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,0BAA0B,IAErB,OAAO,qBAAqB,KAAG,OAAO,CAAC,QAAQ,CAAC,CAe/D;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,0BAA0B,IAErB,OAAO,qBAAqB,KAAG,OAAO,CAAC,QAAQ,CAAC,CAY/D;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,0BAA0B,wDAIpC;AAED,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,uDAAuD;AACvD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,IAAI,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,kEAAkE;AAClE,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,6BACf,SAAQ,0BAA0B;IAClC,0DAA0D;IAC1D,WAAW,EAAE,CACX,KAAK,EAAE,qBAAqB,KACzB;QAAE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IACtE,iDAAiD;IACjD,eAAe,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7E,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvE,OAAO,EAAE,CACP,KAAK,EAAE,qBAAqB,KACzB,OAAO,CACR,2BAA2B,GAC3B;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,2BAA2B,CAAA;KAAE,CACzE,CAAC;CACH;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,6BAA6B,GACrC,wBAAwB,CAuF1B;AAuBD,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,0BAA0B,GAChC,CAAC"}
|
package/dist/sveltekit.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as OidcLoginError, h as DEFAULT_SESSION_TTL,
|
|
1
|
+
import { O as OidcLoginError, h as DEFAULT_SESSION_TTL, Z as withSessionPermissionContext, H as TerminalAuthRateLimitError, F as TerminalAuthError, Y as resolveOidcProviderConfig, u as OidcLoginService, N as encodeOidcTransaction, X as getUsersOidcConfig, L as decodeOidcTransaction, I as TerminalAuthService, z as SessionService } from "./chunks/TerminalAuthService-D5VVPG9e.js";
|
|
2
2
|
import { createLogger } from "@happyvertical/logger";
|
|
3
3
|
import { ObjectRegistry } from "@happyvertical/smrt-core";
|
|
4
4
|
import { classnameToTablename } from "@happyvertical/smrt-core/utils";
|
|
@@ -437,8 +437,6 @@ function createSessionHandler(options) {
|
|
|
437
437
|
const cookieName = options.cookieName ?? "sid";
|
|
438
438
|
const ttl = options.ttl ?? DEFAULT_SESSION_TTL;
|
|
439
439
|
const skipPaths = options.skipPaths ?? [];
|
|
440
|
-
options.cookiePath ?? "/";
|
|
441
|
-
options.cookieSameSite ?? "lax";
|
|
442
440
|
let sessionService = null;
|
|
443
441
|
const getSessionService = async () => {
|
|
444
442
|
if (!sessionService) {
|
|
@@ -523,6 +521,8 @@ async function createSessionCookie(event, userId, tenantId, options) {
|
|
|
523
521
|
});
|
|
524
522
|
event.cookies.set(cookieName, sessionId, {
|
|
525
523
|
path: cookiePath,
|
|
524
|
+
// undefined => SvelteKit scopes the cookie to the request host.
|
|
525
|
+
domain: options.cookieDomain,
|
|
526
526
|
httpOnly: true,
|
|
527
527
|
secure: cookieSecure,
|
|
528
528
|
sameSite: cookieSameSite,
|
|
@@ -543,7 +543,10 @@ async function destroySessionCookie(event, options) {
|
|
|
543
543
|
logger.error("Session destruction error", { error });
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
|
-
event.cookies.delete(cookieName, {
|
|
546
|
+
event.cookies.delete(cookieName, {
|
|
547
|
+
path: cookiePath,
|
|
548
|
+
domain: options.cookieDomain
|
|
549
|
+
});
|
|
547
550
|
}
|
|
548
551
|
async function switchSessionTenant(event, tenantId, options) {
|
|
549
552
|
const cookieName = options.cookieName ?? "sid";
|
|
@@ -551,7 +554,28 @@ async function switchSessionTenant(event, tenantId, options) {
|
|
|
551
554
|
const sessionId = event.cookies.get(cookieName);
|
|
552
555
|
if (!sessionId) return false;
|
|
553
556
|
const service = await getOrCreateSessionService(options, ttl);
|
|
554
|
-
|
|
557
|
+
const result = await service.switchTenant(sessionId, tenantId);
|
|
558
|
+
if (result.rotated && result.sessionId) {
|
|
559
|
+
const cookiePath = options.cookiePath ?? "/";
|
|
560
|
+
const cookieSameSite = options.cookieSameSite ?? "lax";
|
|
561
|
+
const cookieSecure = options.cookieSecure ?? event.url.protocol === "https:";
|
|
562
|
+
const maxAge = result.session ? Math.max(
|
|
563
|
+
0,
|
|
564
|
+
Math.round(
|
|
565
|
+
(new Date(result.session.expiresAt).getTime() - Date.now()) / 1e3
|
|
566
|
+
)
|
|
567
|
+
) : ttl;
|
|
568
|
+
event.cookies.set(cookieName, result.sessionId, {
|
|
569
|
+
path: cookiePath,
|
|
570
|
+
// undefined => SvelteKit scopes the cookie to the request host.
|
|
571
|
+
domain: options.cookieDomain,
|
|
572
|
+
httpOnly: true,
|
|
573
|
+
secure: cookieSecure,
|
|
574
|
+
sameSite: cookieSameSite,
|
|
575
|
+
maxAge
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
return result.switched;
|
|
555
579
|
}
|
|
556
580
|
function getOidcProviderName(event, options) {
|
|
557
581
|
if (typeof options.provider === "function") {
|
|
@@ -838,7 +862,7 @@ function createTerminalAuthStartHandler(options) {
|
|
|
838
862
|
const service = await getOrCreateTerminalAuthService(options);
|
|
839
863
|
const origin = typeof options.verificationOrigin === "function" ? options.verificationOrigin(event) : options.verificationOrigin ?? event.url.origin;
|
|
840
864
|
const result = await service.createRequest(origin);
|
|
841
|
-
return jsonResponse(result, 201);
|
|
865
|
+
return jsonResponse(result, 201, NO_STORE_HEADERS);
|
|
842
866
|
};
|
|
843
867
|
}
|
|
844
868
|
function createTerminalAuthTokenHandler(options) {
|
|
@@ -850,7 +874,7 @@ function createTerminalAuthTokenHandler(options) {
|
|
|
850
874
|
}
|
|
851
875
|
const service = await getOrCreateTerminalAuthService(options);
|
|
852
876
|
const result = await service.exchangeDeviceCode(deviceCode);
|
|
853
|
-
return jsonResponse(result);
|
|
877
|
+
return jsonResponse(result, 200, NO_STORE_HEADERS);
|
|
854
878
|
};
|
|
855
879
|
}
|
|
856
880
|
function createBearerSessionDeleteHandler(options) {
|
|
@@ -947,12 +971,16 @@ function mountTerminalLoginPage(options) {
|
|
|
947
971
|
}
|
|
948
972
|
};
|
|
949
973
|
}
|
|
950
|
-
function jsonResponse(body, status = 200) {
|
|
974
|
+
function jsonResponse(body, status = 200, extraHeaders) {
|
|
951
975
|
return new Response(JSON.stringify(body), {
|
|
952
976
|
status,
|
|
953
|
-
headers: { "content-type": "application/json" }
|
|
977
|
+
headers: { "content-type": "application/json", ...extraHeaders }
|
|
954
978
|
});
|
|
955
979
|
}
|
|
980
|
+
const NO_STORE_HEADERS = {
|
|
981
|
+
"cache-control": "private, no-store",
|
|
982
|
+
pragma: "no-cache"
|
|
983
|
+
};
|
|
956
984
|
export {
|
|
957
985
|
InvalidBearerError,
|
|
958
986
|
TerminalAuthError,
|