fix
This commit is contained in:
		| @@ -8,13 +8,18 @@ import { useContextKey } from '@kevisual/use-config/context'; | |||||||
| const manualParse = parseHomeArg(HomeConfigDir); | const manualParse = parseHomeArg(HomeConfigDir); | ||||||
| const _configDir = manualParse.configDir; | const _configDir = manualParse.configDir; | ||||||
| export const configDir = AssistantInit.detectConfigDir(_configDir); | export const configDir = AssistantInit.detectConfigDir(_configDir); | ||||||
|  | const isInit = manualParse?.options?.help ? false : true; | ||||||
| export const assistantConfig = new AssistantInit({ | export const assistantConfig = new AssistantInit({ | ||||||
|   path: configDir, |   path: configDir, | ||||||
|   init: manualParse?.options?.help ? false : true, |   init: isInit, | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const httpsPem = new HttpsPem(assistantConfig); | const httpsPem = new HttpsPem(assistantConfig); | ||||||
| export const app = useContextKey('app', () => { | export const app = useContextKey('app', () => { | ||||||
|  |   const init = isInit; | ||||||
|  |   if (init) { | ||||||
|  |     // const config = assistantConfig.getConfig(); | ||||||
|  |   } | ||||||
|   return new App({ |   return new App({ | ||||||
|     serverOptions: { |     serverOptions: { | ||||||
|       path: '/client/router', |       path: '/client/router', | ||||||
|   | |||||||
| @@ -62,6 +62,8 @@ export type ReturnInitConfigType = ReturnType<typeof initConfig>; | |||||||
|  |  | ||||||
| type AuthPermission = { | type AuthPermission = { | ||||||
|   type?: 'auth-proxy' | 'public' | 'private' | 'project'; |   type?: 'auth-proxy' | 'public' | 'private' | 'project'; | ||||||
|  |   username?: string; // 用户名 | ||||||
|  |   admin?: Omit<AuthPermission, 'admin'>; | ||||||
| }; | }; | ||||||
| export type AssistantConfigData = { | export type AssistantConfigData = { | ||||||
|   pageApi?: string; // https://kevisual.cn |   pageApi?: string; // https://kevisual.cn | ||||||
| @@ -99,6 +101,11 @@ export type AssistantConfigData = { | |||||||
|     [key: string]: string; |     [key: string]: string; | ||||||
|   }; |   }; | ||||||
|   auth?: AuthPermission; |   auth?: AuthPermission; | ||||||
|  |   https?: { | ||||||
|  |     type?: 'https' | 'http'; | ||||||
|  |     keyPath?: string; // 证书私钥路径 | ||||||
|  |     certPath?: string; // 证书路径 | ||||||
|  |   }; | ||||||
| }; | }; | ||||||
| let assistantConfig: AssistantConfigData; | let assistantConfig: AssistantConfigData; | ||||||
| type AssistantConfigOptions = { | type AssistantConfigOptions = { | ||||||
|   | |||||||
| @@ -21,6 +21,30 @@ export class HttpsPem { | |||||||
|   cert: string; |   cert: string; | ||||||
|   constructor(assistantConfig: AssistantConfig) { |   constructor(assistantConfig: AssistantConfig) { | ||||||
|     this.assistantConfig = assistantConfig; |     this.assistantConfig = assistantConfig; | ||||||
|  |     this.#initKeyCert(); | ||||||
|  |   } | ||||||
|  |   #initKeyCert() { | ||||||
|  |     this.assistantConfig.checkMounted(); | ||||||
|  |     const config = this.assistantConfig.getConfig(); | ||||||
|  |     if (config.https) { | ||||||
|  |       const httpsType = config.https?.type || 'https'; | ||||||
|  |       if (httpsType !== 'https') { | ||||||
|  |         console.log(chalk.yellow('当前配置文件 https.type 不是 https, 不使用证书')); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       if (config.https.keyPath) { | ||||||
|  |         const keyPath = config.https.keyPath; | ||||||
|  |         const certPath = config.https.certPath; | ||||||
|  |         if (checkFileExists(keyPath) && checkFileExists(certPath)) { | ||||||
|  |           this.key = fs.readFileSync(keyPath, 'utf-8'); | ||||||
|  |           this.cert = fs.readFileSync(certPath, 'utf-8'); | ||||||
|  |           console.log(chalk.green('使用配置文件 https.keyPath 和 https.certPath 的证书'), keyPath, certPath); | ||||||
|  |           return; | ||||||
|  |         } else { | ||||||
|  |           console.log(chalk.red('证书路径不存在,请检查配置文件 https.keyPath 和 https.certPath 是否正确')); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|     const { key, cert } = this.getCert(); |     const { key, cert } = this.getCert(); | ||||||
|     this.key = key; |     this.key = key; | ||||||
|     this.cert = cert; |     this.cert = cert; | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								assistant/src/module/reload-server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								assistant/src/module/reload-server.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | import pm2 from 'pm2'; | ||||||
|  | import { logger } from './logger.js'; | ||||||
|  |  | ||||||
|  | export async function reload() { | ||||||
|  |   return new Promise<void>((resolve, reject) => { | ||||||
|  |     pm2.connect((err) => { | ||||||
|  |       if (err) { | ||||||
|  |         logger.error('PM2 connection error:', err); | ||||||
|  |         return reject(err); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       pm2.reload('assistant-server', (err) => { | ||||||
|  |         if (err) { | ||||||
|  |           logger.error('PM2 reload error:', err); | ||||||
|  |           pm2.disconnect(); | ||||||
|  |           return reject(err); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         logger.info('PM2 server reloaded successfully'); | ||||||
|  |         pm2.disconnect(); | ||||||
|  |         resolve(); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | } | ||||||
| @@ -1,12 +1,11 @@ | |||||||
| import { app, assistantConfig } from '@/app.ts'; | import { app, assistantConfig } from '@/app.ts'; | ||||||
| // import { getCacheAssistantConfig, setConfig } from '@/modules/config/index.ts'; | import { reload } from '../../module/reload-server.ts'; | ||||||
| // import { reload } from '@/modules/parent-msg.ts'; |  | ||||||
|  |  | ||||||
| app | app | ||||||
|   .route({ |   .route({ | ||||||
|     path: 'config', |     path: 'config', | ||||||
|     description: '获取配置', |     description: '获取配置', | ||||||
|     middleware: ['auth'], |     middleware: ['admin-auth'], | ||||||
|   }) |   }) | ||||||
|   .define(async (ctx) => { |   .define(async (ctx) => { | ||||||
|     ctx.body = assistantConfig.getCacheAssistantConfig(); |     ctx.body = assistantConfig.getCacheAssistantConfig(); | ||||||
| @@ -18,12 +17,11 @@ app | |||||||
|     path: 'config', |     path: 'config', | ||||||
|     key: 'set', |     key: 'set', | ||||||
|     description: '设置配置', |     description: '设置配置', | ||||||
|     middleware: ['auth'], |     middleware: ['admin-auth'], | ||||||
|   }) |   }) | ||||||
|   .define(async (ctx) => { |   .define(async (ctx) => { | ||||||
|     const { data } = ctx.query; |     const { data } = ctx.query; | ||||||
|     // reload(); |  | ||||||
|  |  | ||||||
|     ctx.body = assistantConfig.setConfig(data); |     ctx.body = assistantConfig.setConfig(data); | ||||||
|  |     reload(); | ||||||
|   }) |   }) | ||||||
|   .addTo(app); |   .addTo(app); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { Query } from '@kevisual/query'; | import { Query } from '@kevisual/query/query'; | ||||||
| import { app, assistantConfig } from '../app.ts'; | import { app, assistantConfig } from '../app.ts'; | ||||||
| import './config/index.ts'; | import './config/index.ts'; | ||||||
| import './shop-install/index.ts'; | import './shop-install/index.ts'; | ||||||
| @@ -6,40 +6,58 @@ import './ai/index.ts'; | |||||||
|  |  | ||||||
| import os from 'node:os'; | import os from 'node:os'; | ||||||
|  |  | ||||||
|  | const checkAuth = async (ctx: any, isAdmin = false) => { | ||||||
|  |   const config = assistantConfig.getConfig(); | ||||||
|  |   const { auth } = config; | ||||||
|  |   const host = config.pageApi || config.registry || 'https://kevisual.cn'; | ||||||
|  |   const url = new URL('/api/router', host); | ||||||
|  |   const token = ctx.query.token; | ||||||
|  |   if (auth && auth.type !== 'public') { | ||||||
|  |     if (!token) { | ||||||
|  |       return ctx.throw(401, 'not login'); | ||||||
|  |     } | ||||||
|  |     url.searchParams.set('token', token); | ||||||
|  |     // 鉴权代理 | ||||||
|  |     // TODO: | ||||||
|  |     const query = new Query({ url: url.toString() }); | ||||||
|  |     const res = await query.post({ | ||||||
|  |       path: 'user', | ||||||
|  |       key: 'me', | ||||||
|  |     }); | ||||||
|  |     if (res.code !== 200) { | ||||||
|  |       return ctx.throw(401, 'not login'); | ||||||
|  |     } | ||||||
|  |     const tokenUser = res.data || {}; | ||||||
|  |     ctx.state = { | ||||||
|  |       ...ctx.state, | ||||||
|  |       tokenUser, | ||||||
|  |     }; | ||||||
|  |     const { username } = tokenUser; | ||||||
|  |     if (isAdmin) { | ||||||
|  |       if (auth.username && auth.username !== username) { | ||||||
|  |         return ctx.throw(403, 'not admin user'); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }; | ||||||
| app | app | ||||||
|   .route({ |   .route({ | ||||||
|     path: 'auth', |     path: 'auth', | ||||||
|     id: 'auth', |     id: 'auth', | ||||||
|  |     isDebug: true, | ||||||
|  |     description: '获取当前登录用户信息', | ||||||
|   }) |   }) | ||||||
|   .define(async (ctx) => { |   .define(async (ctx) => { | ||||||
|     const config = assistantConfig.getConfig(); |     await checkAuth(ctx); | ||||||
|     const { auth } = config; |   }) | ||||||
|     const host = config.pageApi || config.registry || 'https://kevisual.cn'; |   .addTo(app); | ||||||
|     const url = new URL('/api/router', host); | app | ||||||
|     const token = ctx.token; |   .route({ | ||||||
|     if (auth && auth.type !== 'public') { |     path: 'admin-auth', | ||||||
|       if (!token) { |     id: 'admin-auth', | ||||||
|         return ctx.throw(4001, 'not login'); |   }) | ||||||
|       } |   .define(async (ctx) => { | ||||||
|       url.searchParams.set('token', token); |     await checkAuth(ctx, true); | ||||||
|       // 鉴权代理 |  | ||||||
|       // TODO: |  | ||||||
|       const query = new Query({ baseURL: url.toString() }); |  | ||||||
|       const res = await query.post({ |  | ||||||
|         path: 'user', |  | ||||||
|         key: 'me', |  | ||||||
|       }); |  | ||||||
|       console.log('res', res); |  | ||||||
|       if (res.code !== 200) { |  | ||||||
|         return ctx.throw(4001, 'not login'); |  | ||||||
|       } |  | ||||||
|       const tokenUser = res.data || {}; |  | ||||||
|       ctx.state = { |  | ||||||
|         ...ctx.state, |  | ||||||
|         tokenUser, |  | ||||||
|       }; |  | ||||||
|       const { username } = tokenUser; |  | ||||||
|     } |  | ||||||
|   }) |   }) | ||||||
|   .addTo(app); |   .addTo(app); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "@kevisual/cli", |   "name": "@kevisual/cli", | ||||||
|   "version": "0.0.55-beta-3", |   "version": "0.0.56-beta.4", | ||||||
|   "description": "envision command tools", |   "description": "envision command tools", | ||||||
|   "main": "dist/app.mjs", |   "main": "dist/app.mjs", | ||||||
|   "type": "module", |   "type": "module", | ||||||
| @@ -31,6 +31,7 @@ | |||||||
|     "dev": "NODE_ENV=development bun src/run.ts ", |     "dev": "NODE_ENV=development bun src/run.ts ", | ||||||
|     "dev:tsx": "tsx src/run.ts  ", |     "dev:tsx": "tsx src/run.ts  ", | ||||||
|     "build": "rimraf dist && bun run bun.config.mjs", |     "build": "rimraf dist && bun run bun.config.mjs", | ||||||
|  |     "pub:me": "npm publish --registry https://npm.xiongxiao.me --tag beta", | ||||||
|     "postbuild": "cd assistant && pnpm build ", |     "postbuild": "cd assistant && pnpm build ", | ||||||
|     "dts": "dts-bundle-generator --external-inlines=@types/jsonwebtoken  src/index.ts -o dist/index.d.ts ", |     "dts": "dts-bundle-generator --external-inlines=@types/jsonwebtoken  src/index.ts -o dist/index.d.ts ", | ||||||
|     "build:all": "rimraf dist && bun run bun.config.mjs && bun run assistant/bun.config.mjs" |     "build:all": "rimraf dist && bun run bun.config.mjs && bun run assistant/bun.config.mjs" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user