@atlasauth/svelte 0.1.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +231 -0
  3. package/dist/accessors.d.ts +81 -0
  4. package/dist/accessors.js +126 -0
  5. package/dist/appearance.d.ts +85 -0
  6. package/dist/appearance.js +91 -0
  7. package/dist/components/AtlasLoaded.svelte +7 -0
  8. package/dist/components/AtlasLoaded.svelte.d.ts +18 -0
  9. package/dist/components/AtlasLoading.svelte +7 -0
  10. package/dist/components/AtlasLoading.svelte.d.ts +18 -0
  11. package/dist/components/AtlasProvider.svelte +23 -0
  12. package/dist/components/AtlasProvider.svelte.d.ts +33 -0
  13. package/dist/components/AttemptFlow.svelte +95 -0
  14. package/dist/components/AttemptFlow.svelte.d.ts +30 -0
  15. package/dist/components/OrganizationProfile.svelte +22 -0
  16. package/dist/components/OrganizationProfile.svelte.d.ts +16 -0
  17. package/dist/components/OrganizationSwitcher.svelte +25 -0
  18. package/dist/components/OrganizationSwitcher.svelte.d.ts +16 -0
  19. package/dist/components/Protect.svelte +21 -0
  20. package/dist/components/Protect.svelte.d.ts +32 -0
  21. package/dist/components/SignIn.svelte +16 -0
  22. package/dist/components/SignIn.svelte.d.ts +22 -0
  23. package/dist/components/SignUp.svelte +16 -0
  24. package/dist/components/SignUp.svelte.d.ts +21 -0
  25. package/dist/components/SignedIn.svelte +7 -0
  26. package/dist/components/SignedIn.svelte.d.ts +18 -0
  27. package/dist/components/SignedOut.svelte +7 -0
  28. package/dist/components/SignedOut.svelte.d.ts +18 -0
  29. package/dist/components/UserButton.svelte +40 -0
  30. package/dist/components/UserButton.svelte.d.ts +16 -0
  31. package/dist/components/UserProfile.svelte +35 -0
  32. package/dist/components/UserProfile.svelte.d.ts +16 -0
  33. package/dist/context.d.ts +105 -0
  34. package/dist/context.js +258 -0
  35. package/dist/fapi.d.ts +11 -0
  36. package/dist/fapi.js +11 -0
  37. package/dist/i18n.d.ts +23 -0
  38. package/dist/i18n.js +77 -0
  39. package/dist/index.d.ts +31 -0
  40. package/dist/index.js +35 -0
  41. package/dist/protect.d.ts +18 -0
  42. package/dist/protect.js +18 -0
  43. package/dist/server.d.ts +101 -0
  44. package/dist/server.js +87 -0
  45. package/dist/types.d.ts +42 -0
  46. package/dist/types.js +1 -0
  47. package/package.json +57 -0
@@ -0,0 +1,101 @@
1
+ import { AtlasBackend, ForbiddenError, type ProtectCondition, type SessionClaims } from '@atlasauth/backend';
2
+ /**
3
+ * §10.1 SvelteKit server helper — the peer of the Next.js middleware `auth()`.
4
+ *
5
+ * Verifies the session JWT LOCALLY at the edge (§7.3): the JWKS is cached
6
+ * in-process by `@atlasauth/backend`, so a warm server verifies with no network at
7
+ * all. A helper that called Atlas on every request would make Atlas's latency
8
+ * the app's.
9
+ *
10
+ * Types for SvelteKit's `Handle` / `RequestEvent` are kept structural so this
11
+ * module does not need `@sveltejs/kit` at build time — `@sveltejs/kit` is an
12
+ * optional peer.
13
+ */
14
+ export interface AtlasServerOptions {
15
+ /** The instance's JWKS URL. */
16
+ jwksUrl: string;
17
+ /** Expected `iss`. Required — an unchecked issuer accepts any Atlas instance. */
18
+ issuer: string;
19
+ /** §7.3 optional azp allowlist: refuse a token minted for a different origin. */
20
+ authorizedParties?: readonly string[];
21
+ /** Cookie the session JWT rides in. Defaults to `__session`. */
22
+ cookieName?: string;
23
+ fetchImpl?: typeof fetch;
24
+ }
25
+ /** The resolved auth state, plus the `has`/`protect` helpers bound to its claims. */
26
+ export interface ServerAuth {
27
+ userId: string | null;
28
+ sessionId: string | null;
29
+ orgId: string | null;
30
+ orgRole: string | null;
31
+ claims: SessionClaims | null;
32
+ isSignedIn: boolean;
33
+ /** True when the claims satisfy the condition (empty condition = "signed in"). */
34
+ has(condition?: ProtectCondition): boolean;
35
+ /**
36
+ * Assert access, throwing `ForbiddenError` when unmet — map it to a 401/403 in
37
+ * a `load` or endpoint. With no argument it asserts signed-in.
38
+ */
39
+ protect(condition?: ProtectCondition): asserts this is ServerAuth & {
40
+ userId: string;
41
+ };
42
+ }
43
+ /** Minimal structural shapes for the bits of SvelteKit this helper touches. */
44
+ interface KitCookies {
45
+ get(name: string): string | undefined;
46
+ }
47
+ interface KitRequestEvent {
48
+ request: {
49
+ headers: {
50
+ get(name: string): string | null;
51
+ };
52
+ };
53
+ cookies: KitCookies;
54
+ locals: Record<string, unknown> & {
55
+ auth?: ServerAuth;
56
+ };
57
+ }
58
+ type KitResolve = (event: KitRequestEvent) => unknown | Promise<unknown>;
59
+ type KitHandle = (input: {
60
+ event: KitRequestEvent;
61
+ resolve: KitResolve;
62
+ }) => unknown | Promise<unknown>;
63
+ /**
64
+ * Verify the request's session and return the auth state. Never throws on a bad
65
+ * token — an unverifiable token is treated as signed-out (which degrades to the
66
+ * sign-in screen), never a 500 that takes the page down.
67
+ */
68
+ export declare function resolveServerAuth(backend: AtlasBackend, event: KitRequestEvent, cookieName?: string): Promise<ServerAuth>;
69
+ /**
70
+ * A SvelteKit `handle` that resolves the session once per request and stashes it
71
+ * on `event.locals.auth`, so every `load` and endpoint reads a verified session
72
+ * without re-verifying.
73
+ *
74
+ * ```ts
75
+ * // src/hooks.server.ts
76
+ * import { handleAtlas } from '@atlasauth/svelte/server';
77
+ * export const handle = handleAtlas({
78
+ * jwksUrl: 'https://<instance>.atlas.dev/.well-known/jwks.json',
79
+ * issuer: 'https://<instance>.atlas.dev',
80
+ * });
81
+ * ```
82
+ */
83
+ export declare function handleAtlas(options: AtlasServerOptions): KitHandle;
84
+ /**
85
+ * Read the auth state a prior {@link handleAtlas} put on `event.locals`.
86
+ *
87
+ * ```ts
88
+ * // +layout.server.ts / +page.server.ts
89
+ * import { getServerAuth } from '@atlasauth/svelte/server';
90
+ * export const load = (event) => {
91
+ * const { userId, isSignedIn } = getServerAuth(event);
92
+ * return { userId, isSignedIn };
93
+ * };
94
+ * ```
95
+ */
96
+ export declare function getServerAuth(event: {
97
+ locals: {
98
+ auth?: ServerAuth;
99
+ };
100
+ }): ServerAuth;
101
+ export { ForbiddenError, type ProtectCondition, type SessionClaims };
package/dist/server.js ADDED
@@ -0,0 +1,87 @@
1
+ import { AtlasBackend, ForbiddenError, evaluate, hasFromClaims, } from '@atlasauth/backend';
2
+ const SIGNED_OUT = {
3
+ userId: null,
4
+ sessionId: null,
5
+ orgId: null,
6
+ orgRole: null,
7
+ claims: null,
8
+ };
9
+ function bind(state) {
10
+ const claims = state.claims;
11
+ return {
12
+ ...state,
13
+ isSignedIn: state.userId !== null,
14
+ has(condition = {}) {
15
+ return hasFromClaims(claims, condition);
16
+ },
17
+ protect(condition = {}) {
18
+ const outcome = evaluate(claims, condition);
19
+ if (!outcome.allowed)
20
+ throw new ForbiddenError(outcome.reason, condition);
21
+ },
22
+ };
23
+ }
24
+ /**
25
+ * Verify the request's session and return the auth state. Never throws on a bad
26
+ * token — an unverifiable token is treated as signed-out (which degrades to the
27
+ * sign-in screen), never a 500 that takes the page down.
28
+ */
29
+ export async function resolveServerAuth(backend, event, cookieName = '__session') {
30
+ const header = event.request.headers.get('authorization');
31
+ const bearer = header?.startsWith('Bearer ') ? header.slice(7) : undefined;
32
+ const token = bearer ?? event.cookies.get(cookieName);
33
+ if (!token)
34
+ return bind(SIGNED_OUT);
35
+ const result = await backend.verify(token);
36
+ if (!result.ok)
37
+ return bind(SIGNED_OUT);
38
+ return bind({
39
+ userId: result.claims.sub,
40
+ sessionId: result.claims.sid,
41
+ orgId: result.claims.org_id ?? null,
42
+ orgRole: result.claims.org_role ?? null,
43
+ claims: result.claims,
44
+ });
45
+ }
46
+ /**
47
+ * A SvelteKit `handle` that resolves the session once per request and stashes it
48
+ * on `event.locals.auth`, so every `load` and endpoint reads a verified session
49
+ * without re-verifying.
50
+ *
51
+ * ```ts
52
+ * // src/hooks.server.ts
53
+ * import { handleAtlas } from '@atlasauth/svelte/server';
54
+ * export const handle = handleAtlas({
55
+ * jwksUrl: 'https://<instance>.atlas.dev/.well-known/jwks.json',
56
+ * issuer: 'https://<instance>.atlas.dev',
57
+ * });
58
+ * ```
59
+ */
60
+ export function handleAtlas(options) {
61
+ const backend = new AtlasBackend({
62
+ jwksUrl: options.jwksUrl,
63
+ issuer: options.issuer,
64
+ authorizedParties: options.authorizedParties,
65
+ fetchImpl: options.fetchImpl,
66
+ });
67
+ return async ({ event, resolve }) => {
68
+ event.locals.auth = await resolveServerAuth(backend, event, options.cookieName ?? '__session');
69
+ return resolve(event);
70
+ };
71
+ }
72
+ /**
73
+ * Read the auth state a prior {@link handleAtlas} put on `event.locals`.
74
+ *
75
+ * ```ts
76
+ * // +layout.server.ts / +page.server.ts
77
+ * import { getServerAuth } from '@atlasauth/svelte/server';
78
+ * export const load = (event) => {
79
+ * const { userId, isSignedIn } = getServerAuth(event);
80
+ * return { userId, isSignedIn };
81
+ * };
82
+ * ```
83
+ */
84
+ export function getServerAuth(event) {
85
+ return event.locals.auth ?? bind(SIGNED_OUT);
86
+ }
87
+ export { ForbiddenError };
@@ -0,0 +1,42 @@
1
+ export interface SessionClaims {
2
+ sub: string;
3
+ sid: string;
4
+ exp: number;
5
+ org_id?: string;
6
+ org_slug?: string;
7
+ org_role?: string;
8
+ org_permissions?: string[];
9
+ mfa?: boolean;
10
+ [claim: string]: unknown;
11
+ }
12
+ export interface AtlasUser {
13
+ id: string;
14
+ first_name: string | null;
15
+ last_name: string | null;
16
+ username: string | null;
17
+ image_url: string | null;
18
+ public_metadata: Record<string, unknown>;
19
+ unsafe_metadata: Record<string, unknown>;
20
+ mfa_enabled: boolean;
21
+ has_password: boolean;
22
+ email_addresses?: Array<{
23
+ id: string;
24
+ email_address: string;
25
+ verified: boolean;
26
+ primary: boolean;
27
+ }>;
28
+ }
29
+ export interface AtlasOrganizationMembership {
30
+ role: string;
31
+ organization: {
32
+ id: string;
33
+ name: string;
34
+ slug: string;
35
+ image_url: string | null;
36
+ };
37
+ }
38
+ export interface AtlasSession {
39
+ id: string;
40
+ status: string;
41
+ last_active_organization_id: string | null;
42
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@atlasauth/svelte",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "svelte": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "svelte": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./server": {
18
+ "types": "./dist/server.d.ts",
19
+ "default": "./dist/server.js"
20
+ },
21
+ "./package.json": "./package.json"
22
+ },
23
+ "dependencies": {
24
+ "@atlasauth/js": "0.1.0",
25
+ "@atlasauth/backend": "0.1.0",
26
+ "@atlasauth/authz": "0.1.0"
27
+ },
28
+ "peerDependencies": {
29
+ "svelte": ">=4",
30
+ "@sveltejs/kit": ">=1"
31
+ },
32
+ "peerDependenciesMeta": {
33
+ "@sveltejs/kit": {
34
+ "optional": true
35
+ }
36
+ },
37
+ "devDependencies": {
38
+ "@sveltejs/package": "^2.3.7",
39
+ "@sveltejs/vite-plugin-svelte": "^3.1.2",
40
+ "@testing-library/jest-dom": "^6.6.3",
41
+ "@testing-library/svelte": "^5.2.4",
42
+ "jsdom": "^25.0.1",
43
+ "svelte": "^4.2.19",
44
+ "svelte-check": "^4.0.5",
45
+ "typescript": "^5.6.3",
46
+ "vite": "^5.4.11",
47
+ "vitest": "^2.1.4"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "scripts": {
53
+ "build": "svelte-package -i src/lib -o dist",
54
+ "typecheck": "svelte-check --tsconfig ./tsconfig.json",
55
+ "test": "vitest run"
56
+ }
57
+ }