{t.title}
++ {#if success} + {t.success} + {:else if hasToken} + {t.subtitle} + {:else} + {t.invalidToken} + {/if} +
+From 111fc473d9cc0ef99fa3235a3046f0171a415a88 Mon Sep 17 00:00:00 2001
From: Till-JS <101404291+Till-JS@users.noreply.github.com>
Date: Wed, 28 Jan 2026 15:49:33 +0100
Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(auth):=20implement=20passwor?=
=?UTF-8?q?d=20reset=20email=20link=20handler?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Add GET /api/auth/reset-password/:token endpoint to handle email links
- Create password-reset-redirect store to track source app URLs
- Include callbackURL in reset emails for proper app redirection
- Add redirectTo parameter to forgotPassword in shared-auth
- Create /reset-password page in calendar app with DE/EN translations
- Update calendar authStore with resetPasswordWithToken method
Fixes 404 error when clicking password reset link from email
---
.../apps/web/src/lib/stores/auth.svelte.ts | 27 +-
.../routes/(auth)/reset-password/+page.svelte | 231 ++++++++++++++++++
packages/shared-auth/src/core/authService.ts | 6 +-
.../better-auth-passthrough.controller.ts | 49 +++-
.../src/auth/better-auth.config.ts | 17 +-
.../src/auth/services/better-auth.service.ts | 6 +
.../stores/password-reset-redirect.store.ts | 96 ++++++++
7 files changed, 427 insertions(+), 5 deletions(-)
create mode 100644 apps/calendar/apps/web/src/routes/(auth)/reset-password/+page.svelte
create mode 100644 services/mana-core-auth/src/auth/stores/password-reset-redirect.store.ts
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} +
+