auth-system
GitHub基于PocketBase的前端认证系统,涵盖用户登录注册、Token管理、路由守卫及会话状态同步,确保受保护页面的安全访问。
Trigger Scenarios
Install
npx skills add fmaclen/canutin --skill auth-system -g -y
SKILL.md
Frontmatter
{
"name": "auth-system",
"description": "PocketBase-based auth - users collection, context store, protected route guard"
}
Authentication System
Overview
Canutin uses PocketBase's built-in users auth collection. The frontend auth state lives in src/lib/auth.svelte.ts. There is no external IdP.
Key Files
| File | Purpose |
|---|---|
src/lib/auth.svelte.ts |
Auth context store (login, logout, state) |
src/lib/pocketbase.svelte.ts |
PocketBase client wrapper |
src/routes/(guest)/auth/ |
Login and signup pages |
src/routes/(app)/+layout.svelte |
Protected route guard |
src/routes/(guest)/+layout.ts |
Guest route layout |
Collections
users— PocketBase auth collection. Email + password withemailVisibilitycontrolled per record._superusers— PocketBase built-in superadmin collection (dev only).
Types are generated in src/lib/pocketbase.schema.ts.
Route Protection
src/routes/(app)/— requires an authenticated user.(app)/+layout.svelteredirects to the auth page whenauthStoreis unauthenticated.src/routes/(guest)/— public routes (auth forms, landing).
Login Flow
- User submits email + password on the auth form.
authStore.login(email, password)callspb.collection('users').authWithPassword(...).- PocketBase SDK persists the token in
localStoragevia its default auth store. - Context store updates;
(app)/+layout.sveltestops redirecting.
Signup Flow
- User submits email + password + confirmation.
pb.collection('users').create(...)thenauthWithPasswordto immediately log in.
Saved sessions
An expired saved token must clear both the SDK auth store and currentUserId before startup
finishes. Otherwise the route guard admits an unauthenticated session and presents incomplete
financial totals. The guard waits for auth loading to finish before mounting protected routes.
Foreground and online recovery also check token expiry. Every StaleSync refresh checks again
before fetching financial records, including refreshes triggered by realtime events.
New user tokens last 14 days. Startup and visible/online returns renew a still-valid session through
the same validateSession() path before the return-triggered financial refetch. Overlapping signals
share one renewal request. Expired sessions require login; renewal does not revive expired tokens.
Renewal uses an isolated SDK auth store, then commits only if the original token and session version still match. Logout, teardown, and a new login invalidate pending renewal results. Network failures retain a still-valid session and log the failure, allowing data sync to retry when connectivity returns. A newer valid token for the same user, received from another tab, also allows data sync to continue.
Dev Credentials
- Superadmin (auto-upserted by
scripts/pb-server.ts):superadmin@example.com/123qweasdzxc - Test users created via
seedUser(name)ine2e/pocketbase.helpers.tsuseDEFAULT_PASSWORD(123qweasdzxc) and a generated email likealice.<8-char-id>@example.com.
Testing
- E2E tests use
seedUser+ theloginhelper ine2e/playwright.helpers.ts. - Never hardcode passwords in tests — always reference
DEFAULT_PASSWORD.
Anti-patterns
- Rolling a custom session store — trust the PocketBase SDK's auth store
- Storing tokens outside the SDK — it handles persistence and refresh
- Protecting a route via manual checks — use the
(app)group layout - Using
superadmin@example.comin production — dev only, never ship
See Also
- pocketbase.md - Backend context
- testing.md - Seeding users for E2E tests
- realtime.md - Auth-aware subscriptions in stores
Version History
- 28eb754 Current 2026-09-23 01:21


