better-auth-ui-svelte 0.3.3 → 0.3.7
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/README.md +24 -17
- package/dist/auth-client.d.ts +32 -0
- package/dist/auth-client.js +9 -2
- package/dist/components/account/account-view.svelte +8 -8
- package/dist/components/account/account-view.svelte.d.ts +1 -3
- package/dist/components/account/index.d.ts +3 -1
- package/dist/components/account/index.js +1 -0
- package/dist/components/auth/auth-form.svelte +1 -4
- package/dist/components/auth/auth-view.svelte +2 -2
- package/dist/components/auth/forms/email-otp-form.svelte +0 -2
- package/dist/components/auth/forms/email-otp-form.svelte.d.ts +0 -1
- package/dist/components/auth/forms/forgot-password-form.svelte +2 -2
- package/dist/components/auth/forms/magic-link-form.svelte +2 -2
- package/dist/components/auth/forms/sign-in-form.svelte +2 -2
- package/dist/components/auth/forms/sign-up-form.svelte +34 -24
- package/dist/components/auth/forms/two-factor-form.svelte +1 -5
- package/dist/components/auth/magic-link-button.svelte +1 -1
- package/dist/components/auth/magic-link-sent.svelte +0 -3
- package/dist/components/auth-ui-provider.svelte +5 -5
- package/dist/components/auth-ui-provider.svelte.d.ts +3 -3
- package/dist/components/captcha/captcha.svelte +1 -3
- package/dist/components/captcha/captcha.svelte.d.ts +1 -1
- package/dist/components/captcha/recaptcha-v2.svelte +2 -7
- package/dist/components/captcha/recaptcha-v2.svelte.d.ts +1 -1
- package/dist/components/captcha/recaptcha-v3.svelte +5 -6
- package/dist/components/default-link.svelte +2 -1
- package/dist/components/organization/accept-invitation-card.svelte +1 -1
- package/dist/components/organization/accept-invitation-card.svelte.d.ts +1 -2
- package/dist/components/organization/create-organization-dialog.svelte +0 -2
- package/dist/components/organization/create-organization-dialog.svelte.d.ts +0 -1
- package/dist/components/organization/delete-organization-card.svelte +1 -1
- package/dist/components/organization/delete-organization-card.svelte.d.ts +1 -3
- package/dist/components/organization/delete-organization-dialog.svelte +2 -2
- package/dist/components/organization/delete-organization-form.svelte +1 -1
- package/dist/components/organization/invitation-cell.svelte +18 -14
- package/dist/components/organization/invite-member-dialog.svelte +1 -7
- package/dist/components/organization/invite-member-dialog.svelte.d.ts +0 -1
- package/dist/components/organization/leave-organization-dialog.svelte +1 -1
- package/dist/components/organization/member-cell.svelte +4 -2
- package/dist/components/organization/organization-invitations-card.svelte +1 -1
- package/dist/components/organization/organization-invitations-card.svelte.d.ts +1 -3
- package/dist/components/organization/organization-logo-card.svelte +1 -1
- package/dist/components/organization/organization-logo-card.svelte.d.ts +1 -3
- package/dist/components/organization/organization-logo-form.svelte +2 -2
- package/dist/components/organization/organization-logo-form.svelte.d.ts +1 -3
- package/dist/components/organization/organization-members-card.svelte +3 -3
- package/dist/components/organization/organization-members-card.svelte.d.ts +1 -3
- package/dist/components/organization/organization-name-card.svelte +1 -1
- package/dist/components/organization/organization-name-card.svelte.d.ts +1 -3
- package/dist/components/organization/organization-name-form.svelte +2 -2
- package/dist/components/organization/organization-name-form.svelte.d.ts +1 -3
- package/dist/components/organization/organization-settings-cards.svelte +1 -1
- package/dist/components/organization/organization-settings-cards.svelte.d.ts +1 -3
- package/dist/components/organization/organization-slug-card.svelte +1 -1
- package/dist/components/organization/organization-slug-card.svelte.d.ts +1 -3
- package/dist/components/organization/organization-slug-form.svelte +2 -2
- package/dist/components/organization/organization-slug-form.svelte.d.ts +1 -3
- package/dist/components/organization/organization-switcher.svelte +1 -1
- package/dist/components/organization/organization-view.svelte +6 -4
- package/dist/components/organization/organization-view.svelte.d.ts +1 -3
- package/dist/components/organization/organizations-card.svelte +1 -1
- package/dist/components/organization/organizations-card.svelte.d.ts +1 -3
- package/dist/components/organization/remove-member-dialog.svelte +0 -2
- package/dist/components/organization/remove-member-dialog.svelte.d.ts +0 -1
- package/dist/components/organization/update-member-role-dialog.svelte +1 -3
- package/dist/components/organization/user-invitations-card.svelte +1 -1
- package/dist/components/organization/user-invitations-card.svelte.d.ts +1 -3
- package/dist/components/organization-refetcher.svelte +8 -3
- package/dist/components/settings/account/account-cell.svelte +18 -18
- package/dist/components/settings/account/account-settings-cards.svelte +1 -3
- package/dist/components/settings/account/account-settings-cards.svelte.d.ts +1 -3
- package/dist/components/settings/account/accounts-card.svelte +1 -1
- package/dist/components/settings/account/accounts-card.svelte.d.ts +1 -3
- package/dist/components/settings/account/delete-account-card.svelte +1 -1
- package/dist/components/settings/account/delete-account-card.svelte.d.ts +1 -3
- package/dist/components/settings/account/delete-account-dialog.svelte +0 -9
- package/dist/components/settings/account/index.d.ts +11 -5
- package/dist/components/settings/account/index.js +5 -0
- package/dist/components/settings/account/update-avatar-card.svelte +1 -1
- package/dist/components/settings/account/update-avatar-card.svelte.d.ts +1 -3
- package/dist/components/settings/account/update-field-card.svelte +6 -8
- package/dist/components/settings/account/update-field-card.svelte.d.ts +1 -3
- package/dist/components/settings/account/update-name-card.svelte +1 -1
- package/dist/components/settings/account/update-name-card.svelte.d.ts +1 -3
- package/dist/components/settings/account/update-username-card.svelte +1 -1
- package/dist/components/settings/account/update-username-card.svelte.d.ts +1 -3
- package/dist/components/settings/api-key/api-key-cell.svelte +11 -20
- package/dist/components/settings/api-key/api-key-cell.svelte.d.ts +1 -3
- package/dist/components/settings/api-key/api-key-delete-dialog.svelte +3 -2
- package/dist/components/settings/api-key/api-key-display-dialog.svelte +1 -1
- package/dist/components/settings/api-key/api-keys-card.svelte +7 -10
- package/dist/components/settings/api-key/api-keys-card.svelte.d.ts +1 -3
- package/dist/components/settings/api-key/create-api-key-dialog.svelte +32 -33
- package/dist/components/settings/api-key/create-api-key-dialog.svelte.d.ts +0 -1
- package/dist/components/settings/api-key/index.d.ts +5 -2
- package/dist/components/settings/api-key/index.js +2 -0
- package/dist/components/settings/index.d.ts +3 -1
- package/dist/components/settings/index.js +1 -0
- package/dist/components/settings/passkey/index.d.ts +5 -2
- package/dist/components/settings/passkey/index.js +2 -0
- package/dist/components/settings/passkey/passkey-cell.svelte +2 -8
- package/dist/components/settings/passkey/passkey-cell.svelte.d.ts +1 -3
- package/dist/components/settings/passkey/passkeys-card.svelte +11 -15
- package/dist/components/settings/passkey/passkeys-card.svelte.d.ts +1 -3
- package/dist/components/settings/providers/index.d.ts +3 -1
- package/dist/components/settings/providers/index.js +1 -0
- package/dist/components/settings/providers/provider-cell.svelte +12 -3
- package/dist/components/settings/providers/providers-card.svelte +3 -10
- package/dist/components/settings/providers/providers-card.svelte.d.ts +1 -3
- package/dist/components/settings/security/change-email-card.svelte +1 -1
- package/dist/components/settings/security/change-email-card.svelte.d.ts +1 -3
- package/dist/components/settings/security/change-password-card.svelte +2 -4
- package/dist/components/settings/security/change-password-card.svelte.d.ts +1 -3
- package/dist/components/settings/security/index.d.ts +9 -4
- package/dist/components/settings/security/index.js +4 -0
- package/dist/components/settings/security/session-cell.svelte +3 -3
- package/dist/components/settings/security/session-cell.svelte.d.ts +1 -3
- package/dist/components/settings/security/sessions-card.svelte +3 -10
- package/dist/components/settings/security/sessions-card.svelte.d.ts +1 -3
- package/dist/components/settings/security-settings-cards.svelte +4 -12
- package/dist/components/settings/security-settings-cards.svelte.d.ts +1 -3
- package/dist/components/settings/shared/index.d.ts +6 -2
- package/dist/components/settings/shared/index.js +2 -0
- package/dist/components/settings/shared/session-freshness-dialog.svelte +1 -1
- package/dist/components/settings/shared/session-freshness-dialog.svelte.d.ts +1 -3
- package/dist/components/settings/shared/settings-card-footer.svelte +0 -1
- package/dist/components/settings/shared/settings-card-footer.svelte.d.ts +0 -1
- package/dist/components/settings/shared/settings-card.svelte +0 -5
- package/dist/components/settings/shared/settings-card.svelte.d.ts +0 -3
- package/dist/components/settings/two-factor/backup-codes-dialog.svelte +1 -4
- package/dist/components/settings/two-factor/two-factor-card.svelte +10 -4
- package/dist/components/settings/two-factor/two-factor-card.svelte.d.ts +1 -3
- package/dist/components/ui/alert/index.js +2 -0
- package/dist/components/ui/button/button.svelte +2 -0
- package/dist/components/ui/button/index.d.ts +3 -2
- package/dist/components/ui/button/index.js +5 -2
- package/dist/components/ui/dropdown-menu/index.d.ts +19 -0
- package/dist/components/ui/input-otp/input-otp.svelte +0 -1
- package/dist/components/ui/qr-code/qr-code.js +9 -9
- package/dist/components/ui/qr-code/qr-code.svelte +1 -0
- package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
- package/dist/components/user-view.svelte +1 -1
- package/dist/context/auth-ui-config.svelte.d.ts +2 -1
- package/dist/hooks/use-authenticate.svelte.d.ts +1 -1
- package/dist/hooks/use-captcha.svelte.js +2 -1
- package/dist/hooks/use-current-organization.svelte.js +26 -9
- package/dist/index.d.ts +43 -21
- package/dist/index.js +21 -0
- package/dist/localization/auth-localization.d.ts +3 -1
- package/dist/localization/stripe-localization.d.ts +1 -1
- package/dist/localization/stripe-localization.js +1 -1
- package/dist/server/auth.d.ts +2652 -10878
- package/dist/server/auth.js +1 -1
- package/dist/server/db/index.d.ts +1 -1
- package/dist/server/db/schema.d.ts +115 -115
- package/dist/social-providers.d.ts +7 -0
- package/dist/types/any-auth-client.d.ts +1 -1
- package/dist/types/auth-hooks.d.ts +3 -3
- package/dist/types/generic-oauth-options.d.ts +1 -2
- package/package.json +18 -8
package/README.md
CHANGED
|
@@ -355,14 +355,18 @@ interface AuthUIProviderProps {
|
|
|
355
355
|
};
|
|
356
356
|
|
|
357
357
|
// Additional auth methods
|
|
358
|
-
magicLink?:
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
358
|
+
magicLink?:
|
|
359
|
+
| boolean
|
|
360
|
+
| {
|
|
361
|
+
resendCooldown?: number;
|
|
362
|
+
redirectToSentPage?: boolean;
|
|
363
|
+
};
|
|
364
|
+
emailVerification?:
|
|
365
|
+
| boolean
|
|
366
|
+
| {
|
|
367
|
+
resendCooldown?: number;
|
|
368
|
+
redirectToVerifyPage?: boolean;
|
|
369
|
+
};
|
|
366
370
|
passkey?: boolean;
|
|
367
371
|
|
|
368
372
|
// Two-factor authentication
|
|
@@ -476,16 +480,19 @@ Then use it everywhere:
|
|
|
476
480
|
```svelte
|
|
477
481
|
<!-- src/routes/+layout.svelte -->
|
|
478
482
|
<script lang="ts">
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
// Provider will use your custom paths
|
|
483
|
-
<AuthUIProvider
|
|
484
|
-
{authClient}
|
|
485
|
-
basePath={authPathConfig.basePath}
|
|
486
|
-
viewPaths={authPathConfig.viewPaths}
|
|
487
|
-
/>
|
|
483
|
+
import { AuthUIProvider } from 'better-auth-ui-svelte';
|
|
484
|
+
import { authClient } from '$lib/auth-client';
|
|
485
|
+
import { authPathConfig } from '$lib/config/auth-config';
|
|
488
486
|
</script>
|
|
487
|
+
|
|
488
|
+
<!-- Provider will use your custom paths -->
|
|
489
|
+
<AuthUIProvider
|
|
490
|
+
{authClient}
|
|
491
|
+
basePath={authPathConfig.basePath}
|
|
492
|
+
viewPaths={authPathConfig.viewPaths}
|
|
493
|
+
>
|
|
494
|
+
<slot />
|
|
495
|
+
</AuthUIProvider>
|
|
489
496
|
```
|
|
490
497
|
|
|
491
498
|
```typescript
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createAuthClient } from 'better-auth/svelte';
|
|
2
|
+
/**
|
|
3
|
+
* Better Auth Svelte client
|
|
4
|
+
* This provides reactive stores for authentication state
|
|
5
|
+
*/
|
|
6
|
+
export declare const authClient: ReturnType<typeof createAuthClient>;
|
|
7
|
+
export declare const useSession: () => import("nanostores").Atom<{
|
|
8
|
+
data: {
|
|
9
|
+
user: {
|
|
10
|
+
id: string;
|
|
11
|
+
createdAt: Date;
|
|
12
|
+
updatedAt: Date;
|
|
13
|
+
email: string;
|
|
14
|
+
emailVerified: boolean;
|
|
15
|
+
name: string;
|
|
16
|
+
image?: string | null | undefined;
|
|
17
|
+
};
|
|
18
|
+
session: {
|
|
19
|
+
id: string;
|
|
20
|
+
createdAt: Date;
|
|
21
|
+
updatedAt: Date;
|
|
22
|
+
userId: string;
|
|
23
|
+
expiresAt: Date;
|
|
24
|
+
token: string;
|
|
25
|
+
ipAddress?: string | null | undefined;
|
|
26
|
+
userAgent?: string | null | undefined;
|
|
27
|
+
};
|
|
28
|
+
} | null;
|
|
29
|
+
error: import("better-auth/svelte").BetterFetchError | null;
|
|
30
|
+
isPending: boolean;
|
|
31
|
+
isRefetching: boolean;
|
|
32
|
+
}>;
|
package/dist/auth-client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createAuthClient } from 'better-auth/svelte';
|
|
2
|
-
import { organizationClient, apiKeyClient, twoFactorClient, usernameClient, magicLinkClient, emailOTPClient, lastLoginMethodClient, oneTapClient, genericOAuthClient, anonymousClient, multiSessionClient
|
|
2
|
+
import { organizationClient, apiKeyClient, twoFactorClient, usernameClient, magicLinkClient, emailOTPClient, lastLoginMethodClient, oneTapClient, genericOAuthClient, anonymousClient, multiSessionClient } from 'better-auth/client/plugins';
|
|
3
|
+
import { passkeyClient } from '@better-auth/passkey/client';
|
|
3
4
|
/**
|
|
4
5
|
* Better Auth Svelte client
|
|
5
6
|
* This provides reactive stores for authentication state
|
|
@@ -9,6 +10,9 @@ export const authClient = createAuthClient({
|
|
|
9
10
|
apiKeyClient(),
|
|
10
11
|
multiSessionClient(),
|
|
11
12
|
passkeyClient(),
|
|
13
|
+
// @ts-expect-error - BetterAuthClientPlugin type incompatibility between better-auth versions.
|
|
14
|
+
// The oneTapClient plugin has a slightly different type signature that doesn't match the expected
|
|
15
|
+
// BetterAuthClientPlugin interface, but it works correctly at runtime.
|
|
12
16
|
oneTapClient({
|
|
13
17
|
clientId: ''
|
|
14
18
|
}),
|
|
@@ -18,9 +22,12 @@ export const authClient = createAuthClient({
|
|
|
18
22
|
magicLinkClient(),
|
|
19
23
|
emailOTPClient(),
|
|
20
24
|
twoFactorClient(),
|
|
25
|
+
// @ts-expect-error - BetterAuthClientPlugin type incompatibility between better-auth versions.
|
|
26
|
+
// The organizationClient plugin has a slightly different type signature that doesn't match the expected
|
|
27
|
+
// BetterAuthClientPlugin interface, but it works correctly at runtime.
|
|
21
28
|
organizationClient(),
|
|
22
29
|
lastLoginMethodClient()
|
|
23
30
|
]
|
|
24
31
|
});
|
|
25
32
|
// Export convenience methods
|
|
26
|
-
export const
|
|
33
|
+
export const useSession = authClient.useSession;
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
import { Label } from '../ui/label/index.js';
|
|
35
35
|
import { Menu } from '@lucide/svelte';
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
type Props = AccountViewProps;
|
|
38
38
|
|
|
39
39
|
let {
|
|
40
40
|
className,
|
|
@@ -101,9 +101,7 @@
|
|
|
101
101
|
{#if !accountOptions}
|
|
102
102
|
<!-- Return nothing if account options not configured -->
|
|
103
103
|
{:else}
|
|
104
|
-
<div
|
|
105
|
-
class={cn('flex w-full grow flex-col gap-4 md:flex-row md:gap-12', className, classNames?.base)}
|
|
106
|
-
>
|
|
104
|
+
<div class={cn('flex w-full flex-col gap-4 md:flex-row md:gap-12', className, classNames?.base)}>
|
|
107
105
|
{#if !hideNav}
|
|
108
106
|
<!-- Mobile Navigation (Drawer) -->
|
|
109
107
|
<div class="flex justify-between gap-2 md:hidden">
|
|
@@ -113,9 +111,11 @@
|
|
|
113
111
|
|
|
114
112
|
<Drawer.Root bind:open={drawerOpen}>
|
|
115
113
|
<Drawer.Trigger>
|
|
116
|
-
|
|
117
|
-
<
|
|
118
|
-
|
|
114
|
+
{#snippet child({ props })}
|
|
115
|
+
<Button {...props} variant="outline">
|
|
116
|
+
<Menu />
|
|
117
|
+
</Button>
|
|
118
|
+
{/snippet}
|
|
119
119
|
</Drawer.Trigger>
|
|
120
120
|
<Drawer.Content>
|
|
121
121
|
<Drawer.Header>
|
|
@@ -180,7 +180,7 @@
|
|
|
180
180
|
{:else if view === 'SECURITY'}
|
|
181
181
|
<SecuritySettingsCards {classNames} {localization} />
|
|
182
182
|
{:else if view === 'API_KEYS'}
|
|
183
|
-
<ApiKeysCard classNames={classNames?.card} {localization} />
|
|
183
|
+
<ApiKeysCard classNames={classNames?.card} {localization} />
|
|
184
184
|
{:else if view === 'ORGANIZATIONS' && organization}
|
|
185
185
|
<div class="grid w-full gap-4 md:gap-6">
|
|
186
186
|
<OrganizationsCard classNames={classNames?.card} {localization} />
|
|
@@ -22,8 +22,6 @@ export interface AccountViewProps {
|
|
|
22
22
|
view?: AccountViewPath;
|
|
23
23
|
hideNav?: boolean;
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
declare const AccountView: import("svelte").Component<Props, {}, "">;
|
|
25
|
+
declare const AccountView: import("svelte").Component<AccountViewProps, {}, "">;
|
|
28
26
|
type AccountView = ReturnType<typeof AccountView>;
|
|
29
27
|
export default AccountView;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
import type { ComponentProps } from 'svelte';
|
|
2
|
+
import AccountViewComponent from './account-view.svelte';
|
|
1
3
|
export { default as AccountView } from './account-view.svelte';
|
|
2
|
-
export type
|
|
4
|
+
export type AccountViewProps = ComponentProps<typeof AccountViewComponent>;
|
|
@@ -64,15 +64,12 @@
|
|
|
64
64
|
const config = getAuthUIConfig();
|
|
65
65
|
|
|
66
66
|
const {
|
|
67
|
-
basePath,
|
|
68
67
|
credentials,
|
|
69
68
|
localization: contextLocalization,
|
|
70
69
|
magicLink,
|
|
71
70
|
emailOTP,
|
|
72
71
|
signUp,
|
|
73
|
-
|
|
74
|
-
viewPaths,
|
|
75
|
-
replace
|
|
72
|
+
viewPaths
|
|
76
73
|
} = config;
|
|
77
74
|
|
|
78
75
|
const signUpEnabled = !!signUp;
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
socialLayout === 'grid' && 'grid grid-cols-2'
|
|
208
208
|
)}
|
|
209
209
|
>
|
|
210
|
-
{#each social?.providers || [] as providerName}
|
|
210
|
+
{#each social?.providers || [] as providerName (providerName)}
|
|
211
211
|
{@const provider = socialProviders.find((p) => p.provider === providerName)}
|
|
212
212
|
{#if provider}
|
|
213
213
|
<ProviderButton
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
{/if}
|
|
224
224
|
{/each}
|
|
225
225
|
|
|
226
|
-
{#each genericOAuth?.providers || [] as provider}
|
|
226
|
+
{#each genericOAuth?.providers || [] as provider (provider.providerId)}
|
|
227
227
|
<ProviderButton
|
|
228
228
|
{classNames}
|
|
229
229
|
{callbackURL}
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
interface Props {
|
|
18
18
|
className?: string;
|
|
19
19
|
classNames?: AuthFormClassNames;
|
|
20
|
-
callbackURL?: string;
|
|
21
20
|
isSubmitting?: boolean;
|
|
22
21
|
localization?: Partial<AuthLocalization>;
|
|
23
22
|
otpSeparators?: 0 | 1 | 2;
|
|
@@ -28,7 +27,6 @@
|
|
|
28
27
|
let {
|
|
29
28
|
className,
|
|
30
29
|
classNames,
|
|
31
|
-
callbackURL,
|
|
32
30
|
isSubmitting: isSubmittingProp,
|
|
33
31
|
localization: localizationProp,
|
|
34
32
|
otpSeparators = 0,
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
const captchaHook = $derived(useCaptcha({ localization }));
|
|
46
46
|
|
|
47
47
|
// Local state for captcha binding
|
|
48
|
-
let captchaRef = $state<
|
|
48
|
+
let captchaRef = $state<unknown>(null);
|
|
49
49
|
|
|
50
50
|
// Sync captchaRef with the hook
|
|
51
51
|
$effect(() => {
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
const basePath = config.basePath || '/auth';
|
|
76
76
|
const resetPasswordPath = config.viewPaths.RESET_PASSWORD || 'reset-password';
|
|
77
77
|
|
|
78
|
-
const fetchOptions:
|
|
78
|
+
const fetchOptions: Record<string, unknown> = {
|
|
79
79
|
throw: true,
|
|
80
80
|
headers: await captchaHook.getCaptchaHeaders('/forget-password')
|
|
81
81
|
};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { createForm } from '@tanstack/svelte-form';
|
|
6
6
|
import { useCaptcha } from '../../../hooks/use-captcha.svelte';
|
|
7
7
|
import { useIsHydrated } from '../../../hooks/use-hydrated.svelte';
|
|
8
|
-
import { getAuthUIConfig
|
|
8
|
+
import { getAuthUIConfig } from '../../../context/auth-ui-config.svelte';
|
|
9
9
|
import { cn, getLocalizedError, getSearchParam, getFieldError } from '../../../utils/utils.js';
|
|
10
10
|
import type { AuthLocalization } from '../../../localization/auth-localization.js';
|
|
11
11
|
import Captcha from '../../captcha/captcha.svelte';
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
const { getCaptchaHeaders, resetCaptcha } = captchaHook;
|
|
42
42
|
|
|
43
43
|
// Local state for captcha binding
|
|
44
|
-
let captchaRef = $state<
|
|
44
|
+
let captchaRef = $state<unknown>(null);
|
|
45
45
|
|
|
46
46
|
// Sync captchaRef with the hook
|
|
47
47
|
$effect(() => {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { useCaptcha } from '../../../hooks/use-captcha.svelte';
|
|
7
7
|
import { useIsHydrated } from '../../../hooks/use-hydrated.svelte';
|
|
8
8
|
import { useOnSuccessTransition } from '../../../hooks/use-success-transition.svelte';
|
|
9
|
-
import { getAuthUIConfig
|
|
9
|
+
import { getAuthUIConfig } from '../../../context/auth-ui-config.svelte';
|
|
10
10
|
import {
|
|
11
11
|
cn,
|
|
12
12
|
getLocalizedError,
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
const { getCaptchaHeaders, resetCaptcha } = captchaHook;
|
|
52
52
|
|
|
53
53
|
// Local state for captcha binding
|
|
54
|
-
let captchaRef = $state<
|
|
54
|
+
let captchaRef = $state<unknown>(null);
|
|
55
55
|
|
|
56
56
|
// Sync captchaRef with the hook
|
|
57
57
|
$effect(() => {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
const { getCaptchaHeaders, resetCaptcha } = captchaHook;
|
|
91
91
|
|
|
92
92
|
// Local state for captcha binding
|
|
93
|
-
let captchaRef = $state<
|
|
93
|
+
let captchaRef = $state<unknown>(null);
|
|
94
94
|
|
|
95
95
|
// Sync captchaRef with the hook
|
|
96
96
|
$effect(() => {
|
|
@@ -278,8 +278,7 @@
|
|
|
278
278
|
|
|
279
279
|
// Sign up function
|
|
280
280
|
async function signUp(values: z.infer<typeof formSchema>) {
|
|
281
|
-
const { email, password, name, username,
|
|
282
|
-
values;
|
|
281
|
+
const { email, password, name, username, image, ...additionalFieldValues } = values;
|
|
283
282
|
|
|
284
283
|
try {
|
|
285
284
|
// Validate additional fields with custom validators if provided
|
|
@@ -288,7 +287,7 @@
|
|
|
288
287
|
if (!additionalField?.validate) continue;
|
|
289
288
|
|
|
290
289
|
if (typeof value === 'string' && !(await additionalField.validate(value))) {
|
|
291
|
-
form.setFieldMeta(field as
|
|
290
|
+
form.setFieldMeta(field as never, (prev) => ({
|
|
292
291
|
...prev,
|
|
293
292
|
errorMap: {
|
|
294
293
|
...prev.errorMap,
|
|
@@ -300,7 +299,7 @@
|
|
|
300
299
|
}
|
|
301
300
|
|
|
302
301
|
// Prepare fetch options with captcha headers
|
|
303
|
-
const fetchOptions:
|
|
302
|
+
const fetchOptions: Record<string, unknown> = {
|
|
304
303
|
throw: true,
|
|
305
304
|
headers: await getCaptchaHeaders('/sign-up/email')
|
|
306
305
|
};
|
|
@@ -343,9 +342,9 @@
|
|
|
343
342
|
// Note: This handles token-based email verification (default).
|
|
344
343
|
// If the server uses emailOTP with overrideDefaultEmailVerification,
|
|
345
344
|
// users receive OTP codes via email instead of verification links.
|
|
346
|
-
const
|
|
347
|
-
searchParams.set('email', email); // URLSearchParams handles encoding automatically
|
|
348
|
-
navigate(`${basePath}/${viewPaths.VERIFY_EMAIL}?${searchParams.toString()}`);
|
|
345
|
+
const url = new URL(window.location.href);
|
|
346
|
+
url.searchParams.set('email', email as string); // URLSearchParams handles encoding automatically
|
|
347
|
+
navigate(`${basePath}/${viewPaths.VERIFY_EMAIL}?${url.searchParams.toString()}`);
|
|
349
348
|
// Don't show a toast here since the verify-email view will show all needed info
|
|
350
349
|
}
|
|
351
350
|
} catch (error) {
|
|
@@ -383,7 +382,7 @@
|
|
|
383
382
|
|
|
384
383
|
// Create validators for additional fields dynamically
|
|
385
384
|
function getAdditionalFieldValidator(field: string) {
|
|
386
|
-
return (formSchema.shape as
|
|
385
|
+
return (formSchema.shape as Record<string, z.ZodTypeAny>)[field];
|
|
387
386
|
}
|
|
388
387
|
|
|
389
388
|
// Combine isSubmitting states
|
|
@@ -431,18 +430,29 @@
|
|
|
431
430
|
<div class="flex items-center gap-4">
|
|
432
431
|
<DropdownMenu.Root>
|
|
433
432
|
<DropdownMenu.Trigger class="size-fit rounded-full">
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
433
|
+
{#snippet child({ props })}
|
|
434
|
+
<Button
|
|
435
|
+
{...props}
|
|
436
|
+
class="size-fit rounded-full"
|
|
437
|
+
size="icon"
|
|
438
|
+
type="button"
|
|
439
|
+
variant="ghost"
|
|
440
|
+
disabled={uploadingAvatar}
|
|
441
|
+
>
|
|
442
|
+
<UserAvatar
|
|
443
|
+
isPending={uploadingAvatar}
|
|
444
|
+
className="size-16"
|
|
445
|
+
user={avatarImage
|
|
446
|
+
? {
|
|
447
|
+
name: form.getFieldValue('name') as string,
|
|
448
|
+
email: form.getFieldValue('email') as string,
|
|
449
|
+
image: avatarImage
|
|
450
|
+
}
|
|
451
|
+
: null}
|
|
452
|
+
{localization}
|
|
453
|
+
/>
|
|
454
|
+
</Button>
|
|
455
|
+
{/snippet}
|
|
446
456
|
</DropdownMenu.Trigger>
|
|
447
457
|
|
|
448
458
|
<DropdownMenu.Content align="start">
|
|
@@ -622,11 +632,11 @@
|
|
|
622
632
|
|
|
623
633
|
<!-- Additional Fields -->
|
|
624
634
|
{#if signUpFields}
|
|
625
|
-
{#each signUpFields.filter((field) => field !== 'name' && field !== 'image') as field}
|
|
635
|
+
{#each signUpFields.filter((field) => field !== 'name' && field !== 'image') as field (field)}
|
|
626
636
|
{@const additionalField = additionalFields?.[field]}
|
|
627
637
|
{#if additionalField}
|
|
628
638
|
<form.Field
|
|
629
|
-
name={field as
|
|
639
|
+
name={field as never}
|
|
630
640
|
validators={{ onChange: getAdditionalFieldValidator(field) }}
|
|
631
641
|
>
|
|
632
642
|
{#snippet children(fieldState)}
|
|
@@ -638,7 +648,7 @@
|
|
|
638
648
|
id={field}
|
|
639
649
|
checked={fieldState.state.value as boolean}
|
|
640
650
|
onCheckedChange={(checked) => {
|
|
641
|
-
fieldState.handleChange(checked as
|
|
651
|
+
fieldState.handleChange(checked as never);
|
|
642
652
|
}}
|
|
643
653
|
disabled={isSubmitting}
|
|
644
654
|
/>
|
|
@@ -6,11 +6,7 @@
|
|
|
6
6
|
import SendIcon from '@lucide/svelte/icons/send';
|
|
7
7
|
import { useIsHydrated } from '../../../hooks/use-hydrated.svelte';
|
|
8
8
|
import { useOnSuccessTransition } from '../../../hooks/use-success-transition.svelte';
|
|
9
|
-
import {
|
|
10
|
-
getAuthUIConfig,
|
|
11
|
-
getAuthClient,
|
|
12
|
-
getLocalization
|
|
13
|
-
} from '../../../context/auth-ui-config.svelte';
|
|
9
|
+
import { getAuthUIConfig, getAuthClient } from '../../../context/auth-ui-config.svelte';
|
|
14
10
|
import { cn, getLocalizedError, getSearchParam, getFieldError } from '../../../utils/utils.js';
|
|
15
11
|
import type { AuthLocalization } from '../../../localization/auth-localization.js';
|
|
16
12
|
import type { User } from '../../../types/index.js';
|
|
@@ -102,9 +102,6 @@
|
|
|
102
102
|
|
|
103
103
|
try {
|
|
104
104
|
// Build the callback URL - this should go to wherever the magic link takes users
|
|
105
|
-
const magicLinkSentPath = `${config.basePath}/${config.viewPaths.MAGIC_LINK_SENT}`;
|
|
106
|
-
const magicLinkConfig = typeof config.magicLink === 'object' ? config.magicLink : {};
|
|
107
|
-
|
|
108
105
|
await config.authClient.signIn.magicLink(
|
|
109
106
|
{
|
|
110
107
|
email,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { Snippet
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
3
|
import { setAuthUIConfig } from '../context/auth-ui-config.svelte.js';
|
|
4
4
|
import { authLocalization } from '../localization/auth-localization.js';
|
|
5
5
|
import { BASE_ERROR_CODES } from '../localization/base-error-codes.js';
|
|
@@ -241,7 +241,7 @@
|
|
|
241
241
|
/**
|
|
242
242
|
* All other props
|
|
243
243
|
*/
|
|
244
|
-
[key: string]:
|
|
244
|
+
[key: string]: unknown;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
let {
|
|
@@ -512,7 +512,7 @@
|
|
|
512
512
|
useAuthData({
|
|
513
513
|
queryFn: authClient.listAccounts,
|
|
514
514
|
cacheKey: 'listAccounts'
|
|
515
|
-
}) as
|
|
515
|
+
}) as unknown,
|
|
516
516
|
useAccountInfo: (params) =>
|
|
517
517
|
useAuthData({
|
|
518
518
|
queryFn: () => authClient.accountInfo({ accountId: params.providerId }),
|
|
@@ -746,8 +746,8 @@
|
|
|
746
746
|
$effect(() => {
|
|
747
747
|
if (typeof window === 'undefined') return;
|
|
748
748
|
|
|
749
|
-
const searchParams = new
|
|
750
|
-
const errorCode = searchParams
|
|
749
|
+
const searchParams = window.location.search ? new URL(window.location.href).searchParams : null;
|
|
750
|
+
const errorCode = searchParams?.get('error');
|
|
751
751
|
|
|
752
752
|
if (errorCode) {
|
|
753
753
|
const errorMessage = BASE_ERROR_CODES[errorCode as keyof typeof BASE_ERROR_CODES];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Snippet
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { AuthClient, AuthHooks, AuthMutators, AccountOptions, OrganizationOptions, AvatarOptions, DeleteUserOptions, SocialOptions, GenericOAuthOptions, CredentialsOptions, SignUpOptions, Link, RenderToast, AuthLocalization, AdditionalFields, GravatarOptions } from '../types/index.js';
|
|
3
3
|
import type { AuthViewPaths } from '../utils/view-paths.js';
|
|
4
4
|
interface Props {
|
|
@@ -206,8 +206,8 @@ interface Props {
|
|
|
206
206
|
/**
|
|
207
207
|
* All other props
|
|
208
208
|
*/
|
|
209
|
-
[key: string]:
|
|
209
|
+
[key: string]: unknown;
|
|
210
210
|
}
|
|
211
|
-
declare const AuthUiProvider: Component<Props, {}, "">;
|
|
211
|
+
declare const AuthUiProvider: import("svelte").Component<Props, {}, "">;
|
|
212
212
|
type AuthUiProvider = ReturnType<typeof AuthUiProvider>;
|
|
213
213
|
export default AuthUiProvider;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getAuthUIConfig } from '../../context/auth-ui-config.svelte';
|
|
3
|
-
import { useTheme } from '../../hooks/use-theme.svelte';
|
|
4
3
|
import type { AuthLocalization } from '../../types/index.js';
|
|
5
4
|
import RecaptchaBadge from './recaptcha-badge.svelte';
|
|
6
5
|
import RecaptchaV2 from './recaptcha-v2.svelte';
|
|
@@ -9,7 +8,7 @@
|
|
|
9
8
|
const DEFAULT_CAPTCHA_ENDPOINTS = ['/sign-up/email', '/sign-in/email', '/forget-password'];
|
|
10
9
|
|
|
11
10
|
interface Props {
|
|
12
|
-
ref?:
|
|
11
|
+
ref?: unknown;
|
|
13
12
|
localization?: Partial<AuthLocalization>;
|
|
14
13
|
action?: string; // Optional action to check if it's in the endpoints list
|
|
15
14
|
}
|
|
@@ -18,7 +17,6 @@
|
|
|
18
17
|
|
|
19
18
|
const config = getAuthUIConfig();
|
|
20
19
|
const { captcha } = config;
|
|
21
|
-
const { theme } = useTheme();
|
|
22
20
|
|
|
23
21
|
// If action is provided, check if it's in the list of captcha-enabled endpoints
|
|
24
22
|
const shouldShowCaptcha = $derived(() => {
|
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { onMount } from 'svelte';
|
|
3
3
|
import { getAuthUIConfig } from '../../context/auth-ui-config.svelte';
|
|
4
|
-
import { useLang } from '../../hooks/use-lang.svelte';
|
|
5
|
-
import { useTheme } from '../../hooks/use-theme.svelte';
|
|
6
|
-
import { cn } from '../../utils/utils.js';
|
|
7
4
|
|
|
8
5
|
interface Props {
|
|
9
|
-
captchaRef?:
|
|
6
|
+
captchaRef?: unknown;
|
|
10
7
|
}
|
|
11
8
|
|
|
12
9
|
let { captchaRef = $bindable() }: Props = $props();
|
|
13
10
|
|
|
14
11
|
const config = getAuthUIConfig();
|
|
15
12
|
const { captcha } = config;
|
|
16
|
-
const { theme } = useTheme();
|
|
17
|
-
const { lang } = useLang();
|
|
18
13
|
|
|
19
14
|
onMount(() => {
|
|
20
15
|
// Set global recaptcha options
|
|
21
16
|
if (typeof window !== 'undefined') {
|
|
22
|
-
(window as
|
|
17
|
+
(window as unknown as Record<string, unknown>).recaptchaOptions = {
|
|
23
18
|
useRecaptchaNet: captcha?.recaptchaNet,
|
|
24
19
|
enterprise: captcha?.enterprise
|
|
25
20
|
};
|
|
@@ -32,14 +32,13 @@
|
|
|
32
32
|
const baseUrl = captcha.recaptchaNet
|
|
33
33
|
? 'https://www.recaptcha.net/recaptcha/api.js'
|
|
34
34
|
: 'https://www.google.com/recaptcha/api.js';
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
});
|
|
35
|
+
const url = new URL(baseUrl);
|
|
36
|
+
url.searchParams.set('render', captcha.siteKey);
|
|
38
37
|
if (captcha.enterprise) {
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
url.searchParams.set('onload', 'onRecaptchaLoadCallback');
|
|
39
|
+
url.searchParams.set('render', 'explicit');
|
|
41
40
|
}
|
|
42
|
-
script.src =
|
|
41
|
+
script.src = url.toString();
|
|
43
42
|
script.async = true;
|
|
44
43
|
script.defer = true;
|
|
45
44
|
document.head.appendChild(script);
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
let { href, class: className, children }: Props = $props();
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
|
|
14
|
+
<a {href} data-sveltekit-reload class={className}>
|
|
14
15
|
{@render children()}
|
|
15
16
|
</a>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import OrganizationCellView from './organization-cell-view.svelte';
|
|
18
18
|
import { browser } from '$app/environment';
|
|
19
19
|
|
|
20
|
-
export
|
|
20
|
+
export type AcceptInvitationCardClassNames = SettingsCardClassNames;
|
|
21
21
|
|
|
22
22
|
interface Props {
|
|
23
23
|
class?: string;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { AuthLocalization } from '../../types/index.js';
|
|
2
2
|
import type { SettingsCardClassNames } from '../settings/shared/settings-card.svelte';
|
|
3
|
-
export
|
|
4
|
-
}
|
|
3
|
+
export type AcceptInvitationCardClassNames = SettingsCardClassNames;
|
|
5
4
|
interface Props {
|
|
6
5
|
class?: string;
|
|
7
6
|
classNames?: AcceptInvitationCardClassNames;
|
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
interface Props {
|
|
36
|
-
class?: string;
|
|
37
36
|
classNames?: SettingsCardClassNames;
|
|
38
37
|
open?: boolean;
|
|
39
38
|
onOpenChange?: (open: boolean) => void;
|
|
@@ -41,7 +40,6 @@
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
let {
|
|
44
|
-
class: className,
|
|
45
43
|
classNames,
|
|
46
44
|
open = $bindable(false),
|
|
47
45
|
onOpenChange,
|