Compare commits

...

4 Commits

4 changed files with 91 additions and 21 deletions

24
.turbo/turbo-build.log Normal file
View File

@@ -0,0 +1,24 @@
WARN Issue while reading "/home/ubuntu/kevisual/center/submodules/query-login/.npmrc". Failed to replace env in config: ${ME_NPM_TOKEN}
WARN Issue while reading "/home/ubuntu/kevisual/center/.npmrc". Failed to replace env in config: ${ME_NPM_TOKEN}
> @kevisual/query-login@0.0.2 build /home/ubuntu/kevisual/center/submodules/query-login
> tsup
CLI Building entry: src/query-login-browser.ts, src/query-login-node.ts, src/query-login.ts
CLI Using tsconfig: tsconfig.json
CLI tsup v8.4.0
CLI Using tsup config: /home/ubuntu/kevisual/center/submodules/query-login/tsup.config.ts
CLI Target: esnext
CLI Cleaning output folder
ESM Build start
ESM You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin
ESM dist/query-login-node.js 15.31 KB
ESM dist/query-login-browser.js 11.80 KB
ESM dist/query-login.js 11.58 KB
ESM ⚡️ Build success in 10ms
DTS Build start
DTS ⚡️ Build success in 873ms
DTS dist/query-login-browser.d.ts 332.00 B
DTS dist/query-login-node.d.ts 701.00 B
DTS dist/query-login.d.ts 4.80 KB

View File

@@ -16,9 +16,18 @@ export interface Cache {
*/ */
init?: () => Promise<any>; init?: () => Promise<any>;
} }
type User = {
avatar?: string;
description?: string;
id?: string;
needChangePassword?: boolean;
orgs?: string[];
type?: string;
username?: string;
};
export type CacheLoginUser = { export type CacheLoginUser = {
user?: any; user?: User;
id?: string; id?: string;
accessToken?: string; accessToken?: string;
refreshToken?: string; refreshToken?: string;
@@ -29,9 +38,13 @@ type CacheLogin = {
export type CacheStore<T = Cache> = { export type CacheStore<T = Cache> = {
name: string; name: string;
/**
* 缓存数据
* @important 需要先调用init
*/
cacheData: CacheLogin; cacheData: CacheLogin;
/** /**
* 实际操作的cache * 实际操作的cache, 需要先调用init
*/ */
cache: T; cache: T;
@@ -42,7 +55,7 @@ export type CacheStore<T = Cache> = {
/** /**
* 获取当前用户 * 获取当前用户
*/ */
getCurrentUser(): Promise<CacheLoginUser>; getCurrentUser(): Promise<User>;
/** /**
* 获取当前用户列表 * 获取当前用户列表
*/ */

View File

@@ -1,15 +1,21 @@
import { Cache, LoginCacheStore, LoginCacheStoreOpts } from './login-cache.ts'; import { Cache } 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 fs from 'node:fs'; import fs from 'node:fs';
import { readFileSync, writeFileSync, accessSync } from 'node:fs'; import { readFileSync, writeFileSync, accessSync } from 'node:fs';
import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises'; import { readFile, writeFile, unlink, mkdir } from 'node:fs/promises';
export const fileExists = async (filePath: string, createIfNotExists = false) => { export const fileExists = async (
filePath: string,
{ createIfNotExists = true, isFile = true, isDir = false }: { createIfNotExists?: boolean; isFile?: boolean; isDir?: boolean } = {},
) => {
try { try {
accessSync(filePath, fs.constants.F_OK); accessSync(filePath, fs.constants.F_OK);
return true; return true;
} catch (error) { } catch (error) {
if (createIfNotExists) { if (createIfNotExists && isDir) {
await mkdir(filePath, { recursive: true });
return true;
} else if (createIfNotExists && isFile) {
await mkdir(dirname(filePath), { recursive: true }); await mkdir(dirname(filePath), { recursive: true });
return false; return false;
} }
@@ -25,6 +31,9 @@ export const readConfigFile = (filePath: string) => {
return {}; return {};
} }
}; };
export const writeConfigFile = (filePath: string, data: any) => {
writeFileSync(filePath, JSON.stringify(data, null, 2));
};
export const getHostName = () => { export const getHostName = () => {
const configDir = join(homedir(), '.config', 'envision'); const configDir = join(homedir(), '.config', 'envision');
const configFile = join(configDir, 'config.json'); const configFile = join(configDir, 'config.json');
@@ -41,14 +50,13 @@ export class StorageNode implements Storage {
const configDir = join(homedir(), '.config', 'envision'); const configDir = join(homedir(), '.config', 'envision');
const hostname = getHostName(); const hostname = getHostName();
this.filePath = join(configDir, 'config', `${hostname}-storage.json`); this.filePath = join(configDir, 'config', `${hostname}-storage.json`);
fileExists(this.filePath, true); fileExists(this.filePath, { isFile: true });
} }
async loadCache() { async loadCache() {
const filePath = this.filePath; const filePath = this.filePath;
try { try {
const data = await readFile(filePath, 'utf-8'); const data = await readConfigFile(filePath);
const jsonData = JSON.parse(data); this.cacheData = data;
this.cacheData = jsonData;
} catch (error) { } catch (error) {
this.cacheData = {}; this.cacheData = {};
await writeFile(filePath, JSON.stringify(this.cacheData, null, 2)); await writeFile(filePath, JSON.stringify(this.cacheData, null, 2));
@@ -81,24 +89,23 @@ export class LoginNodeCache implements Cache {
constructor(filepath?: string) { constructor(filepath?: string) {
this.filepath = filepath || join(homedir(), '.config', 'envision', 'config', `${getHostName()}-login.json`); this.filepath = filepath || join(homedir(), '.config', 'envision', 'config', `${getHostName()}-login.json`);
fileExists(this.filepath, true); fileExists(this.filepath, { isFile: true });
} }
async get(_key: string) { async get(_key: string) {
const data = readFileSync(this.filepath, 'utf-8');
try { try {
const jsonData = JSON.parse(data); const filePath = this.filepath;
return jsonData; const data = readConfigFile(filePath);
return data;
} catch (error) { } catch (error) {
console.log('get error', error); console.log('get error', error);
return null; return {};
} }
} }
async set(_key: string, value: any) { async set(_key: string, value: any) {
const data = readFileSync(this.filepath, 'utf-8');
try { try {
const jsonData = JSON.parse(data); const data = readConfigFile(this.filepath);
const newData = { ...jsonData, ...value }; const newData = { ...data, ...value };
writeFileSync(this.filepath, JSON.stringify(newData, null, 2)); writeConfigFile(this.filepath, newData);
} catch (error) { } catch (error) {
console.log('set error', error); console.log('set error', error);
} }
@@ -114,7 +121,7 @@ export class LoginNodeCache implements Cache {
} catch (error) { } catch (error) {
console.log('loadCache error', error); console.log('loadCache error', error);
const defaultData = { loginUsers: [] }; const defaultData = { loginUsers: [] };
await writeFile(filePath, JSON.stringify(defaultData, null, 2)); writeConfigFile(filePath, defaultData);
return defaultData; return defaultData;
} }
} }

View File

@@ -86,6 +86,32 @@ export class QueryLogin {
} }
return res; return res;
} }
async loginByWechat(data: { code: string }) {
const res = await this.post<QueryLoginResult>({ path: 'wx', key: 'open-login', code: data.code });
if (res.code === 200) {
const { accessToken, refreshToken } = res?.data || {};
this.storage.setItem('token', accessToken || '');
await this.beforeSetLoginUser({ accessToken, refreshToken });
}
return res;
}
/**
* 检测微信登录登陆成功后调用onSuccess否则调用onError
* @param param0
*/
async checkWechat({ onSuccess, onError }: { onSuccess?: (res: QueryLoginResult) => void; onError?: (res: any) => void }) {
const url = new URL(window.location.href);
const code = url.searchParams.get('code');
const state = url.searchParams.get('state');
if (code && state) {
const res = await this.loginByWechat({ code });
if (res.code === 200) {
onSuccess?.(res.data);
} else {
onError?.(res);
}
}
}
/** /**
* 登陆成功,需要获取用户信息进行缓存 * 登陆成功,需要获取用户信息进行缓存
* @param param0 * @param param0
@@ -177,7 +203,7 @@ export class QueryLogin {
/** /**
* 一个简单的401处理 如果401则刷新token, 如果refreshToken不存在则返回401 * 一个简单的401处理 如果401则刷新token, 如果refreshToken不存在则返回401
* refetch 是否重新请求, 会有bug无限循环按需要使用 * refetch 是否重新请求, 会有bug无限循环按需要使用
* TODO: * TODO:
* @param response * @param response
* @param ctx * @param ctx
* @param opts * @param opts