{t.title}
++ {#if success} + {t.success} + {:else if hasToken} + {t.subtitle} + {:else} + {t.invalidToken} + {/if} +
+diff --git a/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts b/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts
index 1e0aba3fc..170418e5a 100644
--- a/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts
+++ b/apps/calendar/apps/web/src/lib/stores/auth.svelte.ts
@@ -192,7 +192,32 @@ export const authStore = {
}
try {
- const result = await authService.forgotPassword(email);
+ // Pass current app origin so user is redirected back here after clicking email link
+ const redirectTo = browser ? window.location.origin : undefined;
+ const result = await authService.forgotPassword(email, redirectTo);
+
+ if (!result.success) {
+ return { success: false, error: result.error || 'Password reset failed' };
+ }
+
+ return { success: true };
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
+ return { success: false, error: errorMessage };
+ }
+ },
+
+ /**
+ * Reset password with token (from email link)
+ */
+ async resetPasswordWithToken(token: string, newPassword: string) {
+ const authService = getAuthService();
+ if (!authService) {
+ return { success: false, error: 'Auth not available on server' };
+ }
+
+ try {
+ const result = await authService.resetPassword(token, newPassword);
if (!result.success) {
return { success: false, error: result.error || 'Password reset failed' };
diff --git a/apps/calendar/apps/web/src/routes/(auth)/reset-password/+page.svelte b/apps/calendar/apps/web/src/routes/(auth)/reset-password/+page.svelte
new file mode 100644
index 000000000..fe6b028e2
--- /dev/null
+++ b/apps/calendar/apps/web/src/routes/(auth)/reset-password/+page.svelte
@@ -0,0 +1,231 @@
+
+
+
+ {#if success} + {t.success} + {:else if hasToken} + {t.subtitle} + {:else} + {t.invalidToken} + {/if} +
+