Accounts Phase 1c: sign-in UI, magic-link landing, auth store
- Shared reactive auth store (auth.user) + postJSON helper (sends the cookie). - SignIn modal: email -> "check your inbox" (calm, no password); Google slots in here in Phase 2. - /auth/verify route exchanges the magic-link token for a session, then home. - Header shows "Sign in" or an account avatar; the You sheet gains "Signed in as …" + Sign out (or a Sign in row). Anonymous browsing is unchanged.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// Shared, reactive auth state (Svelte 5 runes in a module). Components read
|
||||
// `auth.user` and it stays reactive across the app.
|
||||
import { getJSON, postJSON } from './api.js';
|
||||
|
||||
export const auth = $state({ user: null, ready: false });
|
||||
|
||||
export async function refresh() {
|
||||
try {
|
||||
auth.user = await getJSON('/api/auth/me');
|
||||
} catch {
|
||||
auth.user = null;
|
||||
} finally {
|
||||
auth.ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Request a magic link. Reply is intentionally identical for any address.
|
||||
export function startEmail(email) {
|
||||
return postJSON('/api/auth/email/start', { email });
|
||||
}
|
||||
|
||||
// Exchange a magic-link token for a session (cookie set server-side).
|
||||
export async function verifyToken(token) {
|
||||
const res = await postJSON('/api/auth/email/verify', { token });
|
||||
auth.user = res.user;
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function logout() {
|
||||
try {
|
||||
await postJSON('/api/auth/logout', {});
|
||||
} finally {
|
||||
auth.user = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user