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