feat(auth): persist login provider for restored sessions

This commit is contained in:
2026-06-30 12:50:18 +08:00
parent 768b24774d
commit a99a6e056d
5 changed files with 67 additions and 12 deletions
+26 -3
View File
@@ -11,9 +11,10 @@
* - 浏览器 → `localStorage` driverSSR → memory driverunstorage 自动)
* - 单例挂在 class 静态字段,规避 HMR 复用污染
* - `hasXxx` = `token != null && token.length > 0`,对齐 Dart 端 `isNotEmpty` 语义
* - `clearAuthData` 顺序清理:loginToken → guestToken → refreshToken,任一失败立即返回
* - `clearAuthData` 顺序清理:loginToken → loginProvider → guestToken → refreshToken,任一失败立即返回
*/
import { LoginStatus, type LoginStatus as LoginStatusT } from "@/data/dto/auth";
import { Result, type Result as ResultT, SpAsyncUtil } from "@/utils";
import { StorageKeys } from "../storage_keys";
import type { IAuthStorage } from "./iauth_storage";
@@ -48,6 +49,22 @@ export class AuthStorage implements IAuthStorage {
return SpAsyncUtil.remove(StorageKeys.loginToken);
}
// ---- login provider ----
async getLoginProvider(): Promise<ResultT<LoginStatusT | null>> {
const r = await SpAsyncUtil.getString(StorageKeys.loginProvider);
if (!r.success) return Result.err(r.error);
if (r.data === null || r.data.length === 0) return Result.ok(null);
if (isLoginStatus(r.data)) return Result.ok(r.data);
return Result.ok(null);
}
setLoginProvider(provider: LoginStatusT): Promise<ResultT<void>> {
return SpAsyncUtil.setString(StorageKeys.loginProvider, provider);
}
clearLoginProvider(): Promise<ResultT<void>> {
return SpAsyncUtil.remove(StorageKeys.loginProvider);
}
// ---- guest token ----
getGuestToken(): Promise<ResultT<string | null>> {
@@ -103,10 +120,16 @@ export class AuthStorage implements IAuthStorage {
async clearAuthData(): Promise<ResultT<void>> {
const r1 = await this.clearLoginToken();
if (!r1.success) return r1;
const r2 = await this.clearGuestToken();
const r2 = await this.clearLoginProvider();
if (!r2.success) return r2;
const r3 = await this.clearRefreshToken();
const r3 = await this.clearGuestToken();
if (!r3.success) return r3;
const r4 = await this.clearRefreshToken();
if (!r4.success) return r4;
return this.clearFacebookId();
}
}
function isLoginStatus(value: string): value is LoginStatusT {
return Object.values(LoginStatus).includes(value as LoginStatusT);
}