@authrim/sveltekit 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.
- package/LICENSE +191 -0
- package/README.md +531 -0
- package/dist/__tests__/client-events.test.d.ts +2 -0
- package/dist/__tests__/client-events.test.d.ts.map +1 -0
- package/dist/__tests__/client-events.test.js +225 -0
- package/dist/__tests__/providers.test.d.ts +2 -0
- package/dist/__tests__/providers.test.d.ts.map +1 -0
- package/dist/__tests__/providers.test.js +68 -0
- package/dist/__tests__/response.test.d.ts +2 -0
- package/dist/__tests__/response.test.d.ts.map +1 -0
- package/dist/__tests__/response.test.js +99 -0
- package/dist/__tests__/stores.test.d.ts +2 -0
- package/dist/__tests__/stores.test.d.ts.map +1 -0
- package/dist/__tests__/stores.test.js +91 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +411 -0
- package/dist/components/AuthProvider.svelte +56 -0
- package/dist/components/AuthProvider.svelte.d.ts +34 -0
- package/dist/components/AuthProvider.svelte.d.ts.map +1 -0
- package/dist/components/ProtectedRoute.svelte +71 -0
- package/dist/components/ProtectedRoute.svelte.d.ts +38 -0
- package/dist/components/ProtectedRoute.svelte.d.ts.map +1 -0
- package/dist/components/SignInButton.svelte +93 -0
- package/dist/components/SignInButton.svelte.d.ts +43 -0
- package/dist/components/SignInButton.svelte.d.ts.map +1 -0
- package/dist/components/SignOutButton.svelte +72 -0
- package/dist/components/SignOutButton.svelte.d.ts +40 -0
- package/dist/components/SignOutButton.svelte.d.ts.map +1 -0
- package/dist/components/UserProfile.svelte +71 -0
- package/dist/components/UserProfile.svelte.d.ts +51 -0
- package/dist/components/UserProfile.svelte.d.ts.map +1 -0
- package/dist/components/index.d.ts +6 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +5 -0
- package/dist/direct-auth/ciba.d.ts +47 -0
- package/dist/direct-auth/ciba.d.ts.map +1 -0
- package/dist/direct-auth/ciba.js +77 -0
- package/dist/direct-auth/consent.d.ts +85 -0
- package/dist/direct-auth/consent.d.ts.map +1 -0
- package/dist/direct-auth/consent.js +57 -0
- package/dist/direct-auth/device-flow.d.ts +40 -0
- package/dist/direct-auth/device-flow.d.ts.map +1 -0
- package/dist/direct-auth/device-flow.js +45 -0
- package/dist/direct-auth/email-code.d.ts +48 -0
- package/dist/direct-auth/email-code.d.ts.map +1 -0
- package/dist/direct-auth/email-code.js +265 -0
- package/dist/direct-auth/index.d.ts +9 -0
- package/dist/direct-auth/index.d.ts.map +1 -0
- package/dist/direct-auth/index.js +8 -0
- package/dist/direct-auth/login-challenge.d.ts +41 -0
- package/dist/direct-auth/login-challenge.d.ts.map +1 -0
- package/dist/direct-auth/login-challenge.js +34 -0
- package/dist/direct-auth/passkey.d.ts +30 -0
- package/dist/direct-auth/passkey.d.ts.map +1 -0
- package/dist/direct-auth/passkey.js +392 -0
- package/dist/direct-auth/session.d.ts +48 -0
- package/dist/direct-auth/session.d.ts.map +1 -0
- package/dist/direct-auth/session.js +219 -0
- package/dist/direct-auth/social.d.ts +56 -0
- package/dist/direct-auth/social.d.ts.map +1 -0
- package/dist/direct-auth/social.js +484 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/providers/crypto.d.ts +13 -0
- package/dist/providers/crypto.d.ts.map +1 -0
- package/dist/providers/crypto.js +27 -0
- package/dist/providers/http.d.ts +30 -0
- package/dist/providers/http.d.ts.map +1 -0
- package/dist/providers/http.js +65 -0
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/storage.d.ts +21 -0
- package/dist/providers/storage.d.ts.map +1 -0
- package/dist/providers/storage.js +83 -0
- package/dist/server/handle.d.ts +46 -0
- package/dist/server/handle.d.ts.map +1 -0
- package/dist/server/handle.js +60 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +3 -0
- package/dist/server/load.d.ts +83 -0
- package/dist/server/load.d.ts.map +1 -0
- package/dist/server/load.js +86 -0
- package/dist/server/session.d.ts +44 -0
- package/dist/server/session.d.ts.map +1 -0
- package/dist/server/session.js +50 -0
- package/dist/stores/auth.d.ts +56 -0
- package/dist/stores/auth.d.ts.map +1 -0
- package/dist/stores/auth.js +64 -0
- package/dist/stores/index.d.ts +2 -0
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/index.js +1 -0
- package/dist/types.d.ts +164 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/ui/account/LinkAccountButton.svelte +133 -0
- package/dist/ui/account/LinkAccountButton.svelte.d.ts +37 -0
- package/dist/ui/account/LinkAccountButton.svelte.d.ts.map +1 -0
- package/dist/ui/account/LinkedAccountsList.svelte +233 -0
- package/dist/ui/account/LinkedAccountsList.svelte.d.ts +32 -0
- package/dist/ui/account/LinkedAccountsList.svelte.d.ts.map +1 -0
- package/dist/ui/account/UnlinkAccountButton.svelte +179 -0
- package/dist/ui/account/UnlinkAccountButton.svelte.d.ts +28 -0
- package/dist/ui/account/UnlinkAccountButton.svelte.d.ts.map +1 -0
- package/dist/ui/account/index.d.ts +7 -0
- package/dist/ui/account/index.d.ts.map +1 -0
- package/dist/ui/account/index.js +6 -0
- package/dist/ui/context.d.ts +17 -0
- package/dist/ui/context.d.ts.map +1 -0
- package/dist/ui/context.js +71 -0
- package/dist/ui/forms/CIBARequestCard.svelte +315 -0
- package/dist/ui/forms/CIBARequestCard.svelte.d.ts +50 -0
- package/dist/ui/forms/CIBARequestCard.svelte.d.ts.map +1 -0
- package/dist/ui/forms/ClientInfo.svelte +232 -0
- package/dist/ui/forms/ClientInfo.svelte.d.ts +35 -0
- package/dist/ui/forms/ClientInfo.svelte.d.ts.map +1 -0
- package/dist/ui/forms/ConsentScopesList.svelte +109 -0
- package/dist/ui/forms/ConsentScopesList.svelte.d.ts +30 -0
- package/dist/ui/forms/ConsentScopesList.svelte.d.ts.map +1 -0
- package/dist/ui/forms/EmailCodeForm.svelte +224 -0
- package/dist/ui/forms/EmailCodeForm.svelte.d.ts +39 -0
- package/dist/ui/forms/EmailCodeForm.svelte.d.ts.map +1 -0
- package/dist/ui/forms/OrgSelector.svelte +95 -0
- package/dist/ui/forms/OrgSelector.svelte.d.ts +37 -0
- package/dist/ui/forms/OrgSelector.svelte.d.ts.map +1 -0
- package/dist/ui/forms/PasskeyConditionalInput.svelte +173 -0
- package/dist/ui/forms/PasskeyConditionalInput.svelte.d.ts +36 -0
- package/dist/ui/forms/PasskeyConditionalInput.svelte.d.ts.map +1 -0
- package/dist/ui/forms/QRCodeDisplay.svelte +122 -0
- package/dist/ui/forms/QRCodeDisplay.svelte.d.ts +27 -0
- package/dist/ui/forms/QRCodeDisplay.svelte.d.ts.map +1 -0
- package/dist/ui/forms/SocialLoginButtons.svelte +209 -0
- package/dist/ui/forms/SocialLoginButtons.svelte.d.ts +33 -0
- package/dist/ui/forms/SocialLoginButtons.svelte.d.ts.map +1 -0
- package/dist/ui/forms/UserCodeInput.svelte +183 -0
- package/dist/ui/forms/UserCodeInput.svelte.d.ts +34 -0
- package/dist/ui/forms/UserCodeInput.svelte.d.ts.map +1 -0
- package/dist/ui/forms/index.d.ts +13 -0
- package/dist/ui/forms/index.d.ts.map +1 -0
- package/dist/ui/forms/index.js +12 -0
- package/dist/ui/helpers/AuthError.svelte +124 -0
- package/dist/ui/helpers/AuthError.svelte.d.ts +26 -0
- package/dist/ui/helpers/AuthError.svelte.d.ts.map +1 -0
- package/dist/ui/helpers/AuthLoading.svelte +83 -0
- package/dist/ui/helpers/AuthLoading.svelte.d.ts +25 -0
- package/dist/ui/helpers/AuthLoading.svelte.d.ts.map +1 -0
- package/dist/ui/helpers/OTPInput.svelte +214 -0
- package/dist/ui/helpers/OTPInput.svelte.d.ts +34 -0
- package/dist/ui/helpers/OTPInput.svelte.d.ts.map +1 -0
- package/dist/ui/helpers/ResendCodeButton.svelte +140 -0
- package/dist/ui/helpers/ResendCodeButton.svelte.d.ts +28 -0
- package/dist/ui/helpers/ResendCodeButton.svelte.d.ts.map +1 -0
- package/dist/ui/helpers/index.d.ts +8 -0
- package/dist/ui/helpers/index.d.ts.map +1 -0
- package/dist/ui/helpers/index.js +7 -0
- package/dist/ui/index.d.ts +43 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +48 -0
- package/dist/ui/passkey/PasskeyDeleteButton.svelte +177 -0
- package/dist/ui/passkey/PasskeyDeleteButton.svelte.d.ts +26 -0
- package/dist/ui/passkey/PasskeyDeleteButton.svelte.d.ts.map +1 -0
- package/dist/ui/passkey/PasskeyList.svelte +225 -0
- package/dist/ui/passkey/PasskeyList.svelte.d.ts +30 -0
- package/dist/ui/passkey/PasskeyList.svelte.d.ts.map +1 -0
- package/dist/ui/passkey/PasskeyRegisterButton.svelte +52 -0
- package/dist/ui/passkey/PasskeyRegisterButton.svelte.d.ts +38 -0
- package/dist/ui/passkey/PasskeyRegisterButton.svelte.d.ts.map +1 -0
- package/dist/ui/passkey/index.d.ts +7 -0
- package/dist/ui/passkey/index.d.ts.map +1 -0
- package/dist/ui/passkey/index.js +6 -0
- package/dist/ui/session/SessionExpiryIndicator.svelte +109 -0
- package/dist/ui/session/SessionExpiryIndicator.svelte.d.ts +23 -0
- package/dist/ui/session/SessionExpiryIndicator.svelte.d.ts.map +1 -0
- package/dist/ui/session/SessionList.svelte +231 -0
- package/dist/ui/session/SessionList.svelte.d.ts +31 -0
- package/dist/ui/session/SessionList.svelte.d.ts.map +1 -0
- package/dist/ui/session/SessionRevokeButton.svelte +72 -0
- package/dist/ui/session/SessionRevokeButton.svelte.d.ts +26 -0
- package/dist/ui/session/SessionRevokeButton.svelte.d.ts.map +1 -0
- package/dist/ui/session/index.d.ts +7 -0
- package/dist/ui/session/index.d.ts.map +1 -0
- package/dist/ui/session/index.js +6 -0
- package/dist/ui/shared/Alert.svelte +246 -0
- package/dist/ui/shared/Alert.svelte.d.ts +36 -0
- package/dist/ui/shared/Alert.svelte.d.ts.map +1 -0
- package/dist/ui/shared/Badge.svelte +100 -0
- package/dist/ui/shared/Badge.svelte.d.ts +35 -0
- package/dist/ui/shared/Badge.svelte.d.ts.map +1 -0
- package/dist/ui/shared/Button.svelte +213 -0
- package/dist/ui/shared/Button.svelte.d.ts +42 -0
- package/dist/ui/shared/Button.svelte.d.ts.map +1 -0
- package/dist/ui/shared/Card.svelte +85 -0
- package/dist/ui/shared/Card.svelte.d.ts +39 -0
- package/dist/ui/shared/Card.svelte.d.ts.map +1 -0
- package/dist/ui/shared/CountdownTimer.svelte +150 -0
- package/dist/ui/shared/CountdownTimer.svelte.d.ts +30 -0
- package/dist/ui/shared/CountdownTimer.svelte.d.ts.map +1 -0
- package/dist/ui/shared/Dialog.svelte +240 -0
- package/dist/ui/shared/Dialog.svelte.d.ts +39 -0
- package/dist/ui/shared/Dialog.svelte.d.ts.map +1 -0
- package/dist/ui/shared/Input.svelte +192 -0
- package/dist/ui/shared/Input.svelte.d.ts +42 -0
- package/dist/ui/shared/Input.svelte.d.ts.map +1 -0
- package/dist/ui/shared/LanguageSwitcher.svelte +99 -0
- package/dist/ui/shared/LanguageSwitcher.svelte.d.ts +31 -0
- package/dist/ui/shared/LanguageSwitcher.svelte.d.ts.map +1 -0
- package/dist/ui/shared/Spinner.svelte +75 -0
- package/dist/ui/shared/Spinner.svelte.d.ts +24 -0
- package/dist/ui/shared/Spinner.svelte.d.ts.map +1 -0
- package/dist/ui/shared/index.d.ts +13 -0
- package/dist/ui/shared/index.d.ts.map +1 -0
- package/dist/ui/shared/index.js +12 -0
- package/dist/ui/styles/base.css +168 -0
- package/dist/ui/styles/theme.css +279 -0
- package/dist/ui/templates/AccountSettingsTemplate.svelte +205 -0
- package/dist/ui/templates/AccountSettingsTemplate.svelte.d.ts +49 -0
- package/dist/ui/templates/AccountSettingsTemplate.svelte.d.ts.map +1 -0
- package/dist/ui/templates/CIBATemplate.svelte +227 -0
- package/dist/ui/templates/CIBATemplate.svelte.d.ts +45 -0
- package/dist/ui/templates/CIBATemplate.svelte.d.ts.map +1 -0
- package/dist/ui/templates/ConsentTemplate.svelte +549 -0
- package/dist/ui/templates/ConsentTemplate.svelte.d.ts +76 -0
- package/dist/ui/templates/ConsentTemplate.svelte.d.ts.map +1 -0
- package/dist/ui/templates/DeviceFlowTemplate.svelte +228 -0
- package/dist/ui/templates/DeviceFlowTemplate.svelte.d.ts +47 -0
- package/dist/ui/templates/DeviceFlowTemplate.svelte.d.ts.map +1 -0
- package/dist/ui/templates/LoginTemplate.svelte +234 -0
- package/dist/ui/templates/LoginTemplate.svelte.d.ts +49 -0
- package/dist/ui/templates/LoginTemplate.svelte.d.ts.map +1 -0
- package/dist/ui/templates/ReauthTemplate.svelte +269 -0
- package/dist/ui/templates/ReauthTemplate.svelte.d.ts +54 -0
- package/dist/ui/templates/ReauthTemplate.svelte.d.ts.map +1 -0
- package/dist/ui/templates/SignUpTemplate.svelte +345 -0
- package/dist/ui/templates/SignUpTemplate.svelte.d.ts +53 -0
- package/dist/ui/templates/SignUpTemplate.svelte.d.ts.map +1 -0
- package/dist/ui/templates/index.d.ts +14 -0
- package/dist/ui/templates/index.d.ts.map +1 -0
- package/dist/ui/templates/index.js +13 -0
- package/dist/ui/types.d.ts +151 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +4 -0
- package/dist/utils/context.d.ts +12 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +26 -0
- package/dist/utils/error-mapping.d.ts +29 -0
- package/dist/utils/error-mapping.d.ts.map +1 -0
- package/dist/utils/error-mapping.js +38 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/response.d.ts +21 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +84 -0
- package/dist/utils/sensitive-data.d.ts +9 -0
- package/dist/utils/sensitive-data.d.ts.map +1 -0
- package/dist/utils/sensitive-data.js +56 -0
- package/dist/utils/ssr.d.ts +38 -0
- package/dist/utils/ssr.d.ts.map +1 -0
- package/dist/utils/ssr.js +73 -0
- package/dist/utils/webauthn-converters.d.ts +9 -0
- package/dist/utils/webauthn-converters.d.ts.map +1 -0
- package/dist/utils/webauthn-converters.js +75 -0
- package/package.json +111 -0
package/README.md
ADDED
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
# @authrim/sveltekit
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@authrim/sveltekit)
|
|
4
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
|
+
|
|
6
|
+
Official SvelteKit SDK for [Authrim](https://authrim.com) authentication.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Passkey Authentication** - WebAuthn-based passwordless login
|
|
11
|
+
- **Email Code (OTP)** - One-time password via email
|
|
12
|
+
- **Social Login** - Google, GitHub, Apple, Microsoft, Facebook
|
|
13
|
+
- **Svelte Stores** - Reactive authentication state
|
|
14
|
+
- **Server-Side Integration** - SvelteKit hooks and load functions
|
|
15
|
+
- **SSR Support** - Full server-side rendering compatibility
|
|
16
|
+
- **TypeScript** - Complete type definitions
|
|
17
|
+
- **UI Components** - Ready-to-use authentication components
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- Node.js >= 18
|
|
22
|
+
- SvelteKit >= 2.0
|
|
23
|
+
- Svelte >= 4.0 or >= 5.0
|
|
24
|
+
- @authrim/core >= 0.1.10
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# pnpm (recommended)
|
|
30
|
+
pnpm add @authrim/sveltekit @authrim/core
|
|
31
|
+
|
|
32
|
+
# npm
|
|
33
|
+
npm install @authrim/sveltekit @authrim/core
|
|
34
|
+
|
|
35
|
+
# yarn
|
|
36
|
+
yarn add @authrim/sveltekit @authrim/core
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> **Note**: `@authrim/core` is a peer dependency that provides the underlying authentication logic. You need to install it alongside `@authrim/sveltekit`, but you don't need to import from it directly—all necessary types and functions are re-exported from `@authrim/sveltekit`.
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
### 1. Create Auth Client
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// src/lib/auth.ts
|
|
47
|
+
import { createAuthrim } from '@authrim/sveltekit';
|
|
48
|
+
|
|
49
|
+
export const auth = await createAuthrim({
|
|
50
|
+
issuer: 'https://auth.example.com',
|
|
51
|
+
clientId: 'your-client-id',
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Set Up Server Hooks
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// src/hooks.server.ts
|
|
59
|
+
import { createAuthHandle } from '@authrim/sveltekit/server';
|
|
60
|
+
|
|
61
|
+
export const handle = createAuthHandle();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 3. Configure Type Safety
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// src/app.d.ts
|
|
68
|
+
import type { ServerAuthContext } from '@authrim/sveltekit/server';
|
|
69
|
+
|
|
70
|
+
declare global {
|
|
71
|
+
namespace App {
|
|
72
|
+
interface Locals {
|
|
73
|
+
auth?: ServerAuthContext;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 4. Set Up AuthProvider
|
|
82
|
+
|
|
83
|
+
```svelte
|
|
84
|
+
<!-- src/routes/+layout.svelte -->
|
|
85
|
+
<script lang="ts">
|
|
86
|
+
import { AuthProvider } from '@authrim/sveltekit/components';
|
|
87
|
+
import { auth } from '$lib/auth';
|
|
88
|
+
|
|
89
|
+
export let data;
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<AuthProvider
|
|
93
|
+
{auth}
|
|
94
|
+
initialSession={data.auth?.session}
|
|
95
|
+
initialUser={data.auth?.user}
|
|
96
|
+
>
|
|
97
|
+
<slot />
|
|
98
|
+
</AuthProvider>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// src/routes/+layout.server.ts
|
|
103
|
+
import { createAuthLoad } from '@authrim/sveltekit/server';
|
|
104
|
+
|
|
105
|
+
export const load = createAuthLoad();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 5. Use Authentication
|
|
109
|
+
|
|
110
|
+
```svelte
|
|
111
|
+
<!-- src/routes/+page.svelte -->
|
|
112
|
+
<script lang="ts">
|
|
113
|
+
import { getAuthContext } from '@authrim/sveltekit';
|
|
114
|
+
|
|
115
|
+
const auth = getAuthContext();
|
|
116
|
+
const { session, user, isAuthenticated, loadingState } = auth.stores;
|
|
117
|
+
|
|
118
|
+
async function handleLogin() {
|
|
119
|
+
const result = await auth.passkey.login();
|
|
120
|
+
if (result.error) {
|
|
121
|
+
console.error(result.error.message);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
{#if $loadingState !== 'idle'}
|
|
127
|
+
<p>Loading...</p>
|
|
128
|
+
{:else if $isAuthenticated}
|
|
129
|
+
<p>Welcome, {$user?.name}</p>
|
|
130
|
+
<button on:click={() => auth.signOut()}>Sign Out</button>
|
|
131
|
+
{:else}
|
|
132
|
+
<button on:click={handleLogin}>Sign In with Passkey</button>
|
|
133
|
+
{/if}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## API Reference
|
|
137
|
+
|
|
138
|
+
### `createAuthrim(config)`
|
|
139
|
+
|
|
140
|
+
Creates an Authrim client instance.
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const auth = await createAuthrim({
|
|
144
|
+
issuer: 'https://auth.example.com',
|
|
145
|
+
clientId: 'your-client-id',
|
|
146
|
+
storage: {
|
|
147
|
+
storage: 'sessionStorage', // 'memory' | 'sessionStorage' | 'localStorage'
|
|
148
|
+
prefix: 'authrim',
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Authentication Namespaces
|
|
154
|
+
|
|
155
|
+
#### `auth.passkey`
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// Login with Passkey
|
|
159
|
+
const result = await auth.passkey.login();
|
|
160
|
+
|
|
161
|
+
// Login with Conditional UI (autofill)
|
|
162
|
+
const result = await auth.passkey.login({ conditional: true });
|
|
163
|
+
|
|
164
|
+
// Sign up with Passkey
|
|
165
|
+
const result = await auth.passkey.signUp({ email: 'user@example.com' });
|
|
166
|
+
|
|
167
|
+
// Register new Passkey (requires authentication)
|
|
168
|
+
const credential = await auth.passkey.register();
|
|
169
|
+
|
|
170
|
+
// Check support
|
|
171
|
+
auth.passkey.isSupported(); // boolean
|
|
172
|
+
await auth.passkey.isConditionalUIAvailable(); // Promise<boolean>
|
|
173
|
+
|
|
174
|
+
// Cancel Conditional UI
|
|
175
|
+
auth.passkey.cancelConditionalUI();
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### `auth.emailCode`
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// Send verification code
|
|
182
|
+
const result = await auth.emailCode.send('user@example.com');
|
|
183
|
+
|
|
184
|
+
// Verify code
|
|
185
|
+
const result = await auth.emailCode.verify('user@example.com', '123456');
|
|
186
|
+
|
|
187
|
+
// Check pending verification
|
|
188
|
+
auth.emailCode.hasPendingVerification('user@example.com'); // boolean
|
|
189
|
+
auth.emailCode.getRemainingTime('user@example.com'); // seconds
|
|
190
|
+
auth.emailCode.clearPendingVerification('user@example.com');
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### `auth.social`
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Login with popup
|
|
197
|
+
const result = await auth.social.loginWithPopup('google');
|
|
198
|
+
|
|
199
|
+
// Login with redirect
|
|
200
|
+
await auth.social.loginWithRedirect('github');
|
|
201
|
+
|
|
202
|
+
// Handle callback (after redirect)
|
|
203
|
+
if (auth.social.hasCallbackParams()) {
|
|
204
|
+
const result = await auth.social.handleCallback();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Get supported providers
|
|
208
|
+
auth.social.getSupportedProviders(); // ['google', 'github', 'apple', 'microsoft', 'facebook']
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### `auth.session`
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// Get current session
|
|
215
|
+
const result = await auth.session.get();
|
|
216
|
+
|
|
217
|
+
// Validate session
|
|
218
|
+
const isValid = await auth.session.validate();
|
|
219
|
+
|
|
220
|
+
// Get user
|
|
221
|
+
const user = await auth.session.getUser();
|
|
222
|
+
|
|
223
|
+
// Refresh session cache
|
|
224
|
+
const session = await auth.session.refresh();
|
|
225
|
+
|
|
226
|
+
// Check authentication
|
|
227
|
+
const isAuth = await auth.session.isAuthenticated();
|
|
228
|
+
|
|
229
|
+
// Clear cache
|
|
230
|
+
auth.session.clearCache();
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Shortcuts
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
// Sign in
|
|
237
|
+
await auth.signIn.passkey();
|
|
238
|
+
await auth.signIn.social('google');
|
|
239
|
+
|
|
240
|
+
// Sign up
|
|
241
|
+
await auth.signUp.passkey({ email: 'user@example.com' });
|
|
242
|
+
|
|
243
|
+
// Sign out
|
|
244
|
+
await auth.signOut();
|
|
245
|
+
await auth.signOut({ redirectUri: '/login' });
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Svelte Stores
|
|
249
|
+
|
|
250
|
+
All stores are **Readable** (not Writable) to ensure events are the source of truth.
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
const { session, user, isAuthenticated, loadingState, error } = auth.stores;
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
| Store | Type | Description |
|
|
257
|
+
|-------|------|-------------|
|
|
258
|
+
| `session` | `Readable<Session \| null>` | Current session |
|
|
259
|
+
| `user` | `Readable<User \| null>` | Current user |
|
|
260
|
+
| `isAuthenticated` | `Readable<boolean>` | Authentication status (derived from session) |
|
|
261
|
+
| `loadingState` | `Readable<AuthLoadingState>` | Current loading state |
|
|
262
|
+
| `error` | `Readable<AuthError \| null>` | Last error |
|
|
263
|
+
|
|
264
|
+
#### `AuthLoadingState`
|
|
265
|
+
|
|
266
|
+
| State | Description |
|
|
267
|
+
|-------|-------------|
|
|
268
|
+
| `'idle'` | Completely stable (also after errors) |
|
|
269
|
+
| `'initializing'` | Initial session check |
|
|
270
|
+
| `'authenticating'` | Login/signup in progress |
|
|
271
|
+
| `'refreshing'` | Session refresh in progress |
|
|
272
|
+
| `'signing_out'` | Sign out in progress |
|
|
273
|
+
|
|
274
|
+
> **Important**: After any operation completes (success or error), `loadingState` returns to `'idle'`. Use `error !== null` to detect error conditions.
|
|
275
|
+
|
|
276
|
+
### Events
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
// Subscribe to events
|
|
280
|
+
const unsubscribe = auth.on('auth:login', ({ session, user, method }) => {
|
|
281
|
+
console.log('Logged in:', user.email, 'via', method);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
auth.on('auth:logout', ({ redirectUri }) => {
|
|
285
|
+
console.log('Logged out');
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
auth.on('auth:error', ({ error }) => {
|
|
289
|
+
console.error('Auth error:', error.message);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
auth.on('session:changed', ({ session, user }) => {
|
|
293
|
+
console.log('Session changed');
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
auth.on('session:expired', ({ reason }) => {
|
|
297
|
+
console.log('Session expired:', reason);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// Unsubscribe
|
|
301
|
+
unsubscribe();
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Cleanup
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
// When not using AuthProvider, manually cleanup resources
|
|
308
|
+
auth.destroy();
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Components
|
|
312
|
+
|
|
313
|
+
### `AuthProvider`
|
|
314
|
+
|
|
315
|
+
Provides auth context to child components.
|
|
316
|
+
|
|
317
|
+
```svelte
|
|
318
|
+
<script lang="ts">
|
|
319
|
+
import { AuthProvider } from '@authrim/sveltekit/components';
|
|
320
|
+
import { auth } from '$lib/auth';
|
|
321
|
+
|
|
322
|
+
export let data;
|
|
323
|
+
</script>
|
|
324
|
+
|
|
325
|
+
<AuthProvider
|
|
326
|
+
{auth}
|
|
327
|
+
initialSession={data.auth?.session}
|
|
328
|
+
initialUser={data.auth?.user}
|
|
329
|
+
>
|
|
330
|
+
<slot />
|
|
331
|
+
</AuthProvider>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Props:**
|
|
335
|
+
- `auth` (required): Authrim client instance
|
|
336
|
+
- `initialSession`: Session from SSR
|
|
337
|
+
- `initialUser`: User from SSR
|
|
338
|
+
|
|
339
|
+
### `SignInButton`
|
|
340
|
+
|
|
341
|
+
```svelte
|
|
342
|
+
<script lang="ts">
|
|
343
|
+
import { SignInButton } from '@authrim/sveltekit/components';
|
|
344
|
+
</script>
|
|
345
|
+
|
|
346
|
+
<!-- Passkey login -->
|
|
347
|
+
<SignInButton
|
|
348
|
+
method="passkey"
|
|
349
|
+
on:success={({ detail }) => console.log(detail.user)}
|
|
350
|
+
on:error={({ detail }) => console.error(detail.message)}
|
|
351
|
+
>
|
|
352
|
+
Sign In with Passkey
|
|
353
|
+
</SignInButton>
|
|
354
|
+
|
|
355
|
+
<!-- Social login -->
|
|
356
|
+
<SignInButton method="social" provider="google">
|
|
357
|
+
Sign In with Google
|
|
358
|
+
</SignInButton>
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### `SignOutButton`
|
|
362
|
+
|
|
363
|
+
```svelte
|
|
364
|
+
<script lang="ts">
|
|
365
|
+
import { SignOutButton } from '@authrim/sveltekit/components';
|
|
366
|
+
</script>
|
|
367
|
+
|
|
368
|
+
<SignOutButton
|
|
369
|
+
redirectUri="/login"
|
|
370
|
+
on:success={() => console.log('Signed out')}
|
|
371
|
+
on:error={({ detail }) => console.error(detail)}
|
|
372
|
+
>
|
|
373
|
+
Sign Out
|
|
374
|
+
</SignOutButton>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### `UserProfile`
|
|
378
|
+
|
|
379
|
+
```svelte
|
|
380
|
+
<script lang="ts">
|
|
381
|
+
import { UserProfile } from '@authrim/sveltekit/components';
|
|
382
|
+
</script>
|
|
383
|
+
|
|
384
|
+
<UserProfile showAvatar showEmail>
|
|
385
|
+
<svelte:fragment slot="avatar" let:user>
|
|
386
|
+
<img src={user.picture} alt={user.name} />
|
|
387
|
+
</svelte:fragment>
|
|
388
|
+
</UserProfile>
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### `ProtectedRoute`
|
|
392
|
+
|
|
393
|
+
```svelte
|
|
394
|
+
<script lang="ts">
|
|
395
|
+
import { ProtectedRoute } from '@authrim/sveltekit/components';
|
|
396
|
+
</script>
|
|
397
|
+
|
|
398
|
+
<ProtectedRoute redirectTo="/login" includeReturnPath>
|
|
399
|
+
<Dashboard />
|
|
400
|
+
|
|
401
|
+
<svelte:fragment slot="loading">
|
|
402
|
+
<Spinner />
|
|
403
|
+
</svelte:fragment>
|
|
404
|
+
|
|
405
|
+
<svelte:fragment slot="unauthenticated">
|
|
406
|
+
<p>Please sign in to continue.</p>
|
|
407
|
+
</svelte:fragment>
|
|
408
|
+
</ProtectedRoute>
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Server-Side Integration
|
|
412
|
+
|
|
413
|
+
### Handle Hook
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
// src/hooks.server.ts
|
|
417
|
+
import { createAuthHandle } from '@authrim/sveltekit/server';
|
|
418
|
+
|
|
419
|
+
export const handle = createAuthHandle({
|
|
420
|
+
cookieName: 'authrim_session',
|
|
421
|
+
secure: true,
|
|
422
|
+
sameSite: 'lax',
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Protected Routes (Server)
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
// src/routes/dashboard/+page.server.ts
|
|
430
|
+
import { requireAuth } from '@authrim/sveltekit/server';
|
|
431
|
+
|
|
432
|
+
export const load = requireAuth({
|
|
433
|
+
loginUrl: '/login',
|
|
434
|
+
redirectParam: 'redirectTo',
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### Layout Data
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
// src/routes/+layout.server.ts
|
|
442
|
+
import { createAuthLoad } from '@authrim/sveltekit/server';
|
|
443
|
+
|
|
444
|
+
export const load = createAuthLoad();
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Helper Functions
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
import {
|
|
451
|
+
isAuthenticated,
|
|
452
|
+
getUser,
|
|
453
|
+
getSession,
|
|
454
|
+
getAuthFromEvent
|
|
455
|
+
} from '@authrim/sveltekit/server';
|
|
456
|
+
|
|
457
|
+
// In +page.server.ts or hooks
|
|
458
|
+
export const load = async ({ locals }) => {
|
|
459
|
+
if (isAuthenticated(locals)) {
|
|
460
|
+
const user = getUser(locals);
|
|
461
|
+
const session = getSession(locals);
|
|
462
|
+
// ...
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
// In handle hook
|
|
467
|
+
const authContext = getAuthFromEvent(event);
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## Package Exports
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
// Main client
|
|
474
|
+
import { createAuthrim, getAuthContext, setAuthContext } from '@authrim/sveltekit';
|
|
475
|
+
|
|
476
|
+
// Server utilities
|
|
477
|
+
import {
|
|
478
|
+
createAuthHandle,
|
|
479
|
+
requireAuth,
|
|
480
|
+
createAuthLoad,
|
|
481
|
+
isAuthenticated,
|
|
482
|
+
getUser,
|
|
483
|
+
getSession
|
|
484
|
+
} from '@authrim/sveltekit/server';
|
|
485
|
+
|
|
486
|
+
// Components
|
|
487
|
+
import {
|
|
488
|
+
AuthProvider,
|
|
489
|
+
SignInButton,
|
|
490
|
+
SignOutButton,
|
|
491
|
+
UserProfile,
|
|
492
|
+
ProtectedRoute
|
|
493
|
+
} from '@authrim/sveltekit/components';
|
|
494
|
+
|
|
495
|
+
// Stores (for advanced use)
|
|
496
|
+
import { createAuthStores } from '@authrim/sveltekit/stores';
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
## Design Principles
|
|
500
|
+
|
|
501
|
+
1. **Stores are observation-only**: All stores are `Readable`, not `Writable`. This ensures that the event system is the single source of truth.
|
|
502
|
+
|
|
503
|
+
2. **Events are source of truth**: Store updates are projections of events. This makes the data flow predictable and debuggable.
|
|
504
|
+
|
|
505
|
+
3. **Components are thin wrappers**: UI components delegate behavior to props/events. They don't implement business logic.
|
|
506
|
+
|
|
507
|
+
4. **SSR-first**: Full server-side rendering support with proper hydration handling.
|
|
508
|
+
|
|
509
|
+
5. **Type safety**: Complete TypeScript support with strict typing.
|
|
510
|
+
|
|
511
|
+
## Security Considerations
|
|
512
|
+
|
|
513
|
+
- **PKCE**: All OAuth flows use PKCE (Proof Key for Code Exchange)
|
|
514
|
+
- **Secure Storage**: Session tokens are stored securely with configurable storage options
|
|
515
|
+
- **CSRF Protection**: State parameter validation for OAuth flows
|
|
516
|
+
- **HttpOnly Cookies**: Server-side session cookies are HttpOnly by default
|
|
517
|
+
|
|
518
|
+
## Contributing
|
|
519
|
+
|
|
520
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
521
|
+
|
|
522
|
+
## License
|
|
523
|
+
|
|
524
|
+
[Apache-2.0](LICENSE)
|
|
525
|
+
|
|
526
|
+
## Links
|
|
527
|
+
|
|
528
|
+
- [Documentation](https://docs.authrim.com)
|
|
529
|
+
- [GitHub](https://github.com/authrim/js-sveltekit)
|
|
530
|
+
- [npm](https://www.npmjs.com/package/@authrim/sveltekit)
|
|
531
|
+
- [Authrim](https://authrim.com)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-events.test.d.ts","sourceRoot":"","sources":["../../src/lib/__tests__/client-events.test.ts"],"names":[],"mappings":""}
|