From 4605703e2072ed5fa3cd64963374338829692c93 Mon Sep 17 00:00:00 2001 From: Padreug Date: Sat, 2 May 2026 10:48:35 +0200 Subject: [PATCH] feat(auth): require login on wallet, chat, and castle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These three standalone apps have no meaningful public view — wallet needs the LNbits token to do anything, chat needs Nostr keys to decrypt DMs, castle's accounting only makes sense for an account holder. Their previous router guards only redirected when a route explicitly opted in via meta.requiresAuth: an unauth user could land on the home page and see broken / empty content with no signal. Replaces each app's per-route guard with a strict policy: any navigation to a path other than /login requires auth, otherwise bounce to /login. /login itself bounces an authenticated user back to /. Affected guards: - src/wallet-app/app.ts - src/chat-app/app.ts - src/accounting-app/app.ts Forum / market / tasks / activities keep the existing per-route guard so they remain browseable without an account by default. That browsing-vs-auth choice will become operator-configurable per deployment (tracked separately). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/accounting-app/app.ts | 18 ++++++++++-------- src/chat-app/app.ts | 18 ++++++++++-------- src/wallet-app/app.ts | 18 ++++++++++-------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/accounting-app/app.ts b/src/accounting-app/app.ts index bdf83e4..38d7d99 100644 --- a/src/accounting-app/app.ts +++ b/src/accounting-app/app.ts @@ -136,16 +136,18 @@ export async function createAppInstance() { await auth.initialize() // Auth guard — only redirect for routes that explicitly require auth + // Castle has no public view — every non-login route requires auth. router.beforeEach(async (to, _from, next) => { - const requiresAuth = to.meta.requiresAuth === true - - if (requiresAuth && !auth.isAuthenticated.value) { - next('/login') - } else if (to.path === '/login' && auth.isAuthenticated.value) { - next('/') - } else { - next() + if (to.path === '/login') { + if (auth.isAuthenticated.value) next('/') + else next() + return } + if (!auth.isAuthenticated.value) { + next('/login') + return + } + next() }) // Global error handling diff --git a/src/chat-app/app.ts b/src/chat-app/app.ts index 78a95b7..c058f86 100644 --- a/src/chat-app/app.ts +++ b/src/chat-app/app.ts @@ -91,16 +91,18 @@ export async function createAppInstance() { const { auth } = await import('@/composables/useAuthService') await auth.initialize() + // Chat has no public view — every non-login route requires auth. router.beforeEach(async (to, _from, next) => { - const requiresAuth = to.meta.requiresAuth === true - - if (requiresAuth && !auth.isAuthenticated.value) { - next('/login') - } else if (to.path === '/login' && auth.isAuthenticated.value) { - next('/') - } else { - next() + if (to.path === '/login') { + if (auth.isAuthenticated.value) next('/') + else next() + return } + if (!auth.isAuthenticated.value) { + next('/login') + return + } + next() }) app.config.errorHandler = (err, _vm, info) => { diff --git a/src/wallet-app/app.ts b/src/wallet-app/app.ts index 8c41eee..5380484 100644 --- a/src/wallet-app/app.ts +++ b/src/wallet-app/app.ts @@ -95,16 +95,18 @@ export async function createAppInstance() { const { auth } = await import('@/composables/useAuthService') await auth.initialize() + // Wallet has no public view — every non-login route requires auth. router.beforeEach(async (to, _from, next) => { - const requiresAuth = to.meta.requiresAuth === true - - if (requiresAuth && !auth.isAuthenticated.value) { - next('/login') - } else if (to.path === '/login' && auth.isAuthenticated.value) { - next('/') - } else { - next() + if (to.path === '/login') { + if (auth.isAuthenticated.value) next('/') + else next() + return } + if (!auth.isAuthenticated.value) { + next('/login') + return + } + next() }) app.config.errorHandler = (err, _vm, info) => {