From 3f7ca52983e7d50ac73d87e49fb7a43c904c963c Mon Sep 17 00:00:00 2001 From: shuaiplus <2327005759@qq.com> Date: Wed, 18 Mar 2026 00:24:45 +0800 Subject: [PATCH] feat: refactor authentication flow and improve token verification process --- src/index.ts | 3 +-- src/router.ts | 11 +++-------- src/services/auth.ts | 21 +++++++++++++++------ src/services/storage.ts | 10 +++++++++- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/index.ts b/src/index.ts index 73f53f0..b80b2f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import { NotificationsHub } from './durable/notifications-hub'; import { handleRequest } from './router'; import { StorageService } from './services/storage'; import { applyCors, jsonResponse } from './utils/response'; -import { runScheduledBackupIfDue, seedDefaultBackupSettings } from './handlers/backup'; +import { runScheduledBackupIfDue } from './handlers/backup'; import { buildWebBootstrapResponse } from './router-public'; let dbInitialized = false; @@ -59,7 +59,6 @@ async function ensureDatabaseInitialized(env: Env): Promise { dbInitPromise = (async () => { const storage = new StorageService(env.DB); await storage.initializeDatabase(); - await seedDefaultBackupSettings(env); dbInitialized = true; dbInitError = null; })() diff --git a/src/router.ts b/src/router.ts index 1626f53..93c6298 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,6 +1,5 @@ import { DEFAULT_DEV_SECRET, Env } from './types'; import { AuthService } from './services/auth'; -import { StorageService } from './services/storage'; import { RateLimitService, getClientIdentifier } from './services/ratelimit'; import { handleCors, errorResponse } from './utils/response'; import { LIMITS } from './config/limits'; @@ -96,10 +95,11 @@ export async function handleRequest(request: Request, env: Env): Promise { + async verifyAccessTokenWithUser(authHeader: string | null): Promise { if (!authHeader) return null; const parts = authHeader.split(' '); @@ -93,12 +97,11 @@ export class AuthService { const payload = await verifyJWT(parts[1], this.env.JWT_SECRET); if (!payload) return null; - // Verify security stamp - ensures token is invalidated after password change const user = await this.storage.getUserById(payload.sub); if (!user) return null; - + if (payload.sstamp !== user.securityStamp) { - return null; // Token was issued before password change + return null; } if (payload.did) { @@ -107,7 +110,13 @@ export class AuthService { if (!payload.dstamp || payload.dstamp !== device.sessionStamp) return null; } - return payload; + return { payload, user }; + } + + // Verify access token from Authorization header + async verifyAccessToken(authHeader: string | null): Promise { + const verified = await this.verifyAccessTokenWithUser(authHeader); + return verified?.payload ?? null; } // Refresh access token diff --git a/src/services/storage.ts b/src/services/storage.ts index 0292025..f600949 100644 --- a/src/services/storage.ts +++ b/src/services/storage.ts @@ -101,6 +101,8 @@ import { } from './storage-revision-repo'; const TWO_FACTOR_REMEMBER_TTL_MS = 30 * 24 * 60 * 60 * 1000; +const STORAGE_SCHEMA_VERSION_KEY = 'schema.version'; +const STORAGE_SCHEMA_VERSION = '2026-03-18.1'; // D1-backed storage. // Contract: @@ -171,7 +173,13 @@ export class StorageService { // - Keep statements idempotent so updates are safe. async initializeDatabase(): Promise { if (StorageService.schemaVerified) return; - await ensureStorageSchema(this.db); + + await this.db.prepare('CREATE TABLE IF NOT EXISTS config (key TEXT PRIMARY KEY, value TEXT NOT NULL)').run(); + const schemaVersion = await getStoredConfigValue(this.db, STORAGE_SCHEMA_VERSION_KEY); + if (schemaVersion !== STORAGE_SCHEMA_VERSION) { + await ensureStorageSchema(this.db); + await saveConfigValue(this.db, STORAGE_SCHEMA_VERSION_KEY, STORAGE_SCHEMA_VERSION); + } StorageService.schemaVerified = true; }