Add site-wide login gate protecting the whole app

Chat/memory/logs/models APIs were reachable without any auth even
though the app is deployed publicly behind Caddy HTTPS; only the
settings screen had a password. Add an optional SITE_PASSWORD-backed
session cookie gate in front of everything (settings included, on
top of its existing SETTINGS_PASSWORD), with a matching login screen
on the frontend. Stays fully backward compatible: with SITE_PASSWORD
unset the app behaves exactly as before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 23:04:01 +09:00
co-authored by Claude Sonnet 5
parent 002282a8b7
commit 1ad8b130c7
12 changed files with 319 additions and 38 deletions
+51
View File
@@ -0,0 +1,51 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { fetchAuthStatus, login as loginApi, logout as logoutApi } from '../api/client'
export const useAuthStore = defineStore('auth', () => {
const required = ref(false)
const authenticated = ref(false)
const loading = ref(true)
const error = ref<string | null>(null)
async function checkStatus(): Promise<void> {
loading.value = true
try {
const status = await fetchAuthStatus()
required.value = status.required
authenticated.value = status.authenticated
} catch (e) {
error.value = e instanceof Error ? e.message : 'エラーが発生しました'
} finally {
loading.value = false
}
}
async function login(password: string): Promise<boolean> {
loading.value = true
error.value = null
try {
const status = await loginApi(password)
required.value = status.required
authenticated.value = status.authenticated
return true
} catch (e) {
authenticated.value = false
error.value = e instanceof Error ? e.message : 'エラーが発生しました'
return false
} finally {
loading.value = false
}
}
async function logout(): Promise<void> {
await logoutApi().catch(() => {})
authenticated.value = false
}
function markUnauthenticated(): void {
authenticated.value = false
}
return { required, authenticated, loading, error, checkStatus, login, logout, markUnauthenticated }
})