feat(auth): remember encrypted local login credentials

This commit is contained in:
justme committed 2026-10-13 01:39:24 +08:00
1 parent f6cfb12716
commit b65e32885f
9 files changed
+148 -30

No files matched your search

+10 -4
View File
@@ -11,9 +11,10 @@ import { initialShareData } from './shareReduce';
interface AccountState extends AccountStatus {
busy: boolean;
hydrated: boolean;
login: (username: string, password: string, create: boolean) => Promise<void>;
login: (username: string, password: string, create: boolean, remember?: boolean) => Promise<void>;
refresh: () => Promise<void>;
logout: () => Promise<void>;
clearSavedLogin: () => Promise<void>;
sync: () => Promise<void>;
updatePersonal: (displayName: string, avatar?: string) => Promise<void>;
}
@@ -26,10 +27,10 @@ export const useAccount = create<AccountState>()((set, get) => ({
error: undefined,
busy: false,
hydrated: false,
login: async (username, password, create) => {
login: async (username, password, create, remember = true) => {
set({ busy: true, error: undefined });
try {
const status = create ? await accountApi.register(username, password) : await accountApi.login(username, password);
const status = create ? await accountApi.register(username, password, remember) : await accountApi.login(username, password, remember);
clearViews(); await refreshResources();
set({ ...status, busy: false, hydrated: true });
} catch (error) {
@@ -48,13 +49,18 @@ export const useAccount = create<AccountState>()((set, get) => ({
logout: async () => {
set({ busy: true });
try { await accountApi.logout(); clearViews(); await refreshResources(); }
finally { set({ username: null, personal: undefined, revision: 0, busy: false, error: undefined }); }
finally { set({ username: null, personal: undefined, remembered: false, revision: 0, busy: false, error: undefined }); }
},
sync: async () => {
set({ busy: true, error: undefined });
try { const status = await accountApi.sync(); await refreshResources(); set({ ...status, busy: false }); }
catch (error) { set({ error: error instanceof Error ? error.message : '同步失败', busy: false }); throw error; }
},
clearSavedLogin: async () => {
set({ busy: true, error: undefined });
try { const status = await accountApi.clearSavedLogin(); set({ ...status, busy: false }); }
catch (error) { set({ error: error instanceof Error ? error.message : '本机保存清除失败', busy: false }); throw error; }
},
updatePersonal: async (displayName, avatar) => {
set({ busy: true, error: undefined });
try { const status = await accountApi.updatePersonal(displayName, avatar); set({ ...status, busy: false }); }