fix: fix login-node-cache error
This commit is contained in:
parent
9ba45c37c2
commit
54672a5574
@ -18,7 +18,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@kevisual/query": "^0.0.14"
|
||||
"@kevisual/query": "^0.0.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.13.11",
|
||||
|
@ -11,6 +11,10 @@ export interface Cache {
|
||||
* @update 删除缓存
|
||||
*/
|
||||
del(): Promise<void>;
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
init?: () => Promise<any>;
|
||||
}
|
||||
|
||||
export type CacheLoginUser = {
|
||||
@ -23,7 +27,7 @@ type CacheLogin = {
|
||||
loginUsers: CacheLoginUser[];
|
||||
} & CacheLoginUser;
|
||||
|
||||
export type CacheStore<T = any> = {
|
||||
export type CacheStore<T = Cache> = {
|
||||
name: string;
|
||||
cacheData: CacheLogin;
|
||||
/**
|
||||
@ -51,10 +55,6 @@ export type CacheStore<T = any> = {
|
||||
* 获取缓存的accessToken
|
||||
*/
|
||||
getAccessToken(): Promise<string>;
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
init(): Promise<void>;
|
||||
/**
|
||||
* 清除当前用户
|
||||
*/
|
||||
@ -63,9 +63,14 @@ export type CacheStore<T = any> = {
|
||||
* 清除所有用户
|
||||
*/
|
||||
clearAll(): Promise<void>;
|
||||
} & Cache;
|
||||
|
||||
type LoginCacheStoreOpts = {
|
||||
getValue(): Promise<CacheLogin>;
|
||||
setValue(value: CacheLogin): Promise<CacheLogin>;
|
||||
delValue(): Promise<void>;
|
||||
init(): Promise<any>;
|
||||
};
|
||||
|
||||
export type LoginCacheStoreOpts = {
|
||||
name: string;
|
||||
cache: Cache;
|
||||
};
|
||||
@ -94,28 +99,41 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
* @param value
|
||||
* @returns
|
||||
*/
|
||||
async set(key: string, value: CacheLogin) {
|
||||
await this.cache.set(key, value);
|
||||
async setValue(value: CacheLogin) {
|
||||
await this.cache.set(this.name, value);
|
||||
this.cacheData = value;
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 删除缓存
|
||||
*/
|
||||
async del() {
|
||||
async delValue() {
|
||||
await this.cache.del();
|
||||
}
|
||||
get(key: string): Promise<CacheLogin> {
|
||||
return this.cache.get(key);
|
||||
getValue(): Promise<CacheLogin> {
|
||||
return this.cache.get(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化,设置默认值
|
||||
*/
|
||||
async init() {
|
||||
this.cacheData = (await this.get(this.name)) || {
|
||||
const defaultData = {
|
||||
loginUsers: [],
|
||||
user: null,
|
||||
id: null,
|
||||
accessToken: null,
|
||||
refreshToken: null,
|
||||
};
|
||||
if (this.cache.init) {
|
||||
try {
|
||||
const cacheData = await this.cache.init();
|
||||
this.cacheData = cacheData || defaultData;
|
||||
} catch (error) {
|
||||
console.log('cacheInit error', error);
|
||||
}
|
||||
} else {
|
||||
this.cacheData = (await this.getValue()) || defaultData;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 设置当前用户
|
||||
@ -131,7 +149,7 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
this.cacheData.id = user.id;
|
||||
this.cacheData.accessToken = user.accessToken;
|
||||
this.cacheData.refreshToken = user.refreshToken;
|
||||
await this.set(this.name, this.cacheData);
|
||||
await this.setValue(this.cacheData);
|
||||
}
|
||||
|
||||
getCurrentUser(): Promise<CacheLoginUser> {
|
||||
@ -160,7 +178,7 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
this.cacheData.id = undefined;
|
||||
this.cacheData.accessToken = undefined;
|
||||
this.cacheData.refreshToken = undefined;
|
||||
await this.set(this.name, this.cacheData);
|
||||
await this.setValue(this.cacheData);
|
||||
}
|
||||
async clearAll() {
|
||||
this.cacheData.loginUsers = [];
|
||||
@ -168,6 +186,6 @@ export class LoginCacheStore implements CacheStore<any> {
|
||||
this.cacheData.id = undefined;
|
||||
this.cacheData.accessToken = undefined;
|
||||
this.cacheData.refreshToken = undefined;
|
||||
await this.set(this.name, this.cacheData);
|
||||
await this.setValue(this.cacheData);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { Cache } from './login-cache.ts';
|
||||
import { Cache, LoginCacheStore, LoginCacheStoreOpts } from './login-cache.ts';
|
||||
import { homedir } from 'node:os';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { readFile, writeFile, unlink, stat, mkdir } from 'node:fs/promises';
|
||||
import fs from 'node:fs';
|
||||
import { readFileSync, writeFileSync, accessSync } from 'node:fs';
|
||||
import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises';
|
||||
export const fileExists = async (filePath: string, createIfNotExists = false) => {
|
||||
try {
|
||||
await stat(filePath);
|
||||
accessSync(filePath, fs.constants.F_OK);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (createIfNotExists) {
|
||||
@ -76,37 +77,48 @@ export class StorageNode implements Storage {
|
||||
}
|
||||
}
|
||||
export class LoginNodeCache implements Cache {
|
||||
name: string;
|
||||
cacheData: any;
|
||||
filePath: string;
|
||||
constructor(name: string) {
|
||||
this.name = name;
|
||||
const hostname = getHostName();
|
||||
this.filePath = join(homedir(), '.config', 'envision', 'config', `${hostname}-${name}.json`);
|
||||
fileExists(this.filePath, true);
|
||||
this.loadCache(this.filePath);
|
||||
}
|
||||
filepath: string;
|
||||
|
||||
constructor(filepath?: string) {
|
||||
this.filepath = filepath || join(homedir(), '.config', 'envision', 'config', `${getHostName()}-login.json`);
|
||||
fileExists(this.filepath, true);
|
||||
}
|
||||
async get(_key: string) {
|
||||
const data = readFileSync(this.filepath, 'utf-8');
|
||||
try {
|
||||
const jsonData = JSON.parse(data);
|
||||
return jsonData;
|
||||
} catch (error) {
|
||||
console.log('get error', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
async set(_key: string, value: any) {
|
||||
const data = readFileSync(this.filepath, 'utf-8');
|
||||
try {
|
||||
const jsonData = JSON.parse(data);
|
||||
const newData = { ...jsonData, ...value };
|
||||
writeFileSync(this.filepath, JSON.stringify(newData, null, 2));
|
||||
} catch (error) {
|
||||
console.log('set error', error);
|
||||
}
|
||||
}
|
||||
async del() {
|
||||
await unlink(this.filepath);
|
||||
}
|
||||
async loadCache(filePath: string) {
|
||||
try {
|
||||
const data = await readFile(filePath, 'utf-8');
|
||||
const jsonData = JSON.parse(data);
|
||||
this.cacheData = jsonData;
|
||||
return jsonData;
|
||||
} catch (error) {
|
||||
console.log('loadCache error', error);
|
||||
const defaultData = { loginUsers: [] };
|
||||
this.cacheData = defaultData;
|
||||
await writeFile(filePath, JSON.stringify(defaultData, null, 2));
|
||||
return defaultData;
|
||||
}
|
||||
}
|
||||
|
||||
async get() {
|
||||
return this.cacheData;
|
||||
}
|
||||
async set(key: string, value: any) {
|
||||
this.cacheData = value;
|
||||
await writeFile(this.filePath, JSON.stringify(this.cacheData, null, 2));
|
||||
}
|
||||
async del() {
|
||||
await unlink(this.filePath);
|
||||
async init() {
|
||||
return await this.loadCache(this.filepath);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ export class QueryLoginNode extends QueryLogin {
|
||||
super({
|
||||
...opts,
|
||||
storage,
|
||||
cache: new LoginNodeCache('login'),
|
||||
cache: new LoginNodeCache(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export class QueryLogin {
|
||||
/**
|
||||
* query login cache, 非实际操作, 一个cache的包裹模块
|
||||
*/
|
||||
cache: CacheStore;
|
||||
cacheStore: CacheStore;
|
||||
isBrowser: boolean;
|
||||
load?: boolean;
|
||||
storage: Storage;
|
||||
@ -34,7 +34,7 @@ export class QueryLogin {
|
||||
|
||||
constructor(opts?: QueryLoginOpts) {
|
||||
this.query = opts?.query || new Query();
|
||||
this.cache = new LoginCacheStore({ name: 'login', cache: opts.cache });
|
||||
this.cacheStore = new LoginCacheStore({ name: 'login', cache: opts.cache });
|
||||
this.isBrowser = opts?.isBrowser ?? true;
|
||||
this.init();
|
||||
this.onLoad = opts?.onLoad;
|
||||
@ -44,12 +44,19 @@ export class QueryLogin {
|
||||
this.query = query;
|
||||
}
|
||||
private async init() {
|
||||
await this.cache.init();
|
||||
await this.cacheStore.init()
|
||||
this.load = true;
|
||||
this.onLoad?.();
|
||||
}
|
||||
async post<T = any>(data: any, opts?: DataOpts) {
|
||||
return this.query.post<T>({ path: 'user', ...data }, opts);
|
||||
try {
|
||||
return this.query.post<T>({ path: 'user', ...data }, opts);
|
||||
} catch (error) {
|
||||
console.log('error', error);
|
||||
return {
|
||||
code: 400,
|
||||
} as any;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 登录,
|
||||
@ -89,7 +96,7 @@ export class QueryLogin {
|
||||
if (resUser.code === 200) {
|
||||
const user = resUser.data;
|
||||
if (user) {
|
||||
this.cache.setLoginUser({
|
||||
this.cacheStore.setLoginUser({
|
||||
user,
|
||||
id: user.id,
|
||||
accessToken,
|
||||
@ -107,10 +114,10 @@ export class QueryLogin {
|
||||
* @returns
|
||||
*/
|
||||
async queryRefreshToken(refreshToken?: string) {
|
||||
const _refreshToken = refreshToken || this.cache.getRefreshToken();
|
||||
const _refreshToken = refreshToken || this.cacheStore.getRefreshToken();
|
||||
let data = { refreshToken: _refreshToken };
|
||||
if (!_refreshToken) {
|
||||
await this.cache.clearCurrentUser();
|
||||
await this.cacheStore.clearCurrentUser();
|
||||
return {
|
||||
code: 401,
|
||||
message: '请先登录',
|
||||
@ -137,7 +144,7 @@ export class QueryLogin {
|
||||
async afterCheck401ToRefreshToken(response: Result, ctx?: { req?: any; res?: any; fetch?: any }, refetch?: boolean) {
|
||||
const that = this;
|
||||
if (response?.code === 401) {
|
||||
const hasRefreshToken = await that.cache.getRefreshToken();
|
||||
const hasRefreshToken = await that.cacheStore.getRefreshToken();
|
||||
if (hasRefreshToken) {
|
||||
const res = await that.queryRefreshToken(hasRefreshToken);
|
||||
if (res.code === 200) {
|
||||
@ -159,7 +166,7 @@ export class QueryLogin {
|
||||
}
|
||||
} else {
|
||||
that.storage.removeItem('token');
|
||||
await that.cache.clearCurrentUser();
|
||||
await that.cacheStore.clearCurrentUser();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -250,7 +257,7 @@ export class QueryLogin {
|
||||
* @returns
|
||||
*/
|
||||
async switchUser(username: string) {
|
||||
const localUserList = await this.cache.getCurrentUserList();
|
||||
const localUserList = await this.cacheStore.getCurrentUserList();
|
||||
const user = localUserList.find((userItem) => userItem.user.username === username);
|
||||
if (user) {
|
||||
this.storage.setItem('token', user.accessToken || '');
|
||||
@ -275,18 +282,18 @@ export class QueryLogin {
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* 退出登陆,去掉token, 并删除缓存
|
||||
* 退出登陆,去掉token, 并删除缓存
|
||||
* @returns
|
||||
*/
|
||||
async logout() {
|
||||
this.storage.removeItem('token');
|
||||
const users = await this.cache.getCurrentUserList();
|
||||
const users = await this.cacheStore.getCurrentUserList();
|
||||
const tokens = users
|
||||
.map((user) => {
|
||||
return user?.accessToken;
|
||||
})
|
||||
.filter(Boolean);
|
||||
this.cache.del();
|
||||
this.cacheStore.delValue();
|
||||
return this.post<Result>({ key: 'logout', data: { tokens } });
|
||||
}
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user