temp
This commit is contained in:
@@ -28,7 +28,7 @@ export const runtime = useContextKey('runtime', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
export const app = useContextKey('app', () => {
|
export const app: App = useContextKey<App>('app', () => {
|
||||||
const init = isInit;
|
const init = isInit;
|
||||||
if (init) {
|
if (init) {
|
||||||
const config = assistantConfig.getConfig();
|
const config = assistantConfig.getConfig();
|
||||||
|
|||||||
0
assistant/src/module/assistant/query.ts
Normal file
0
assistant/src/module/assistant/query.ts
Normal file
@@ -11,7 +11,10 @@ app
|
|||||||
path: 'ai',
|
path: 'ai',
|
||||||
key: 'chat',
|
key: 'chat',
|
||||||
description: '与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。',
|
description: '与 AI 进行对话, 调用 GPT 的AI 服务,生成结果,并返回。',
|
||||||
middleware: ['auth'],
|
middleware: ['admin-auth'],
|
||||||
|
metadata: {
|
||||||
|
admin: true,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const { messages = [], username, group, question, chatOpts = {} } = ctx.query;
|
const { messages = [], username, group, question, chatOpts = {} } = ctx.query;
|
||||||
|
|||||||
@@ -1,52 +1,61 @@
|
|||||||
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';
|
||||||
import './ai/index.ts';
|
import './ai/index.ts';
|
||||||
import './light-code/index.ts';
|
import './light-code/index.ts';
|
||||||
|
import './user/index.ts';
|
||||||
|
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
|
import { authCache } from '@/module/cache/auth.ts';
|
||||||
const checkAuth = async (ctx: any, isAdmin = false) => {
|
export const getTokenUser = async (ctx: any) => {
|
||||||
const config = assistantConfig.getConfig();
|
const query = assistantConfig.query
|
||||||
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({
|
const res = await query.post({
|
||||||
path: 'user',
|
path: 'user',
|
||||||
key: 'me',
|
key: 'me',
|
||||||
|
token: ctx.state.token,
|
||||||
});
|
});
|
||||||
if (res.code !== 200) {
|
if (res.code !== 200) {
|
||||||
return ctx.throw(401, 'not login');
|
return ctx.throw(401, 'not login');
|
||||||
}
|
}
|
||||||
const tokenUser = res.data || {};
|
const tokenUser = res.data || {};
|
||||||
|
return tokenUser;
|
||||||
|
}
|
||||||
|
const checkAuth = async (ctx: any, isAdmin = false) => {
|
||||||
|
const config = assistantConfig.getConfig();
|
||||||
|
const { auth = {} } = config;
|
||||||
|
const token = ctx.query.token;
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return ctx.throw(401, 'not login');
|
||||||
|
}
|
||||||
|
// 鉴权代理
|
||||||
|
let tokenUser = await authCache.get(token);
|
||||||
|
if (!tokenUser) {
|
||||||
|
tokenUser = await getTokenUser(ctx);
|
||||||
|
authCache.set(token, tokenUser);
|
||||||
|
}
|
||||||
ctx.state = {
|
ctx.state = {
|
||||||
...ctx.state,
|
...ctx.state,
|
||||||
|
token,
|
||||||
tokenUser,
|
tokenUser,
|
||||||
};
|
};
|
||||||
const { username } = tokenUser;
|
const { username } = tokenUser;
|
||||||
|
if (!auth.username) {
|
||||||
|
// 初始管理员账号
|
||||||
|
auth.username = username;
|
||||||
|
assistantConfig.setConfig({ auth });
|
||||||
|
}
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
if (auth.username && auth.username !== username) {
|
if (auth.username && auth.username !== username) {
|
||||||
return ctx.throw(403, 'not admin user');
|
return ctx.throw(403, 'not admin user');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
app
|
app
|
||||||
.route({
|
.route({
|
||||||
path: 'auth',
|
path: 'auth',
|
||||||
id: 'auth',
|
id: 'auth',
|
||||||
isDebug: true,
|
description: '获取当前登录用户信息, 第一个登录的用户为管理员用户',
|
||||||
description: '获取当前登录用户信息',
|
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
await checkAuth(ctx);
|
await checkAuth(ctx);
|
||||||
@@ -56,6 +65,7 @@ app
|
|||||||
.route({
|
.route({
|
||||||
path: 'admin-auth',
|
path: 'admin-auth',
|
||||||
id: 'admin-auth',
|
id: 'admin-auth',
|
||||||
|
description: '管理员鉴权, 获取用户信息,并验证是否为管理员。',
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
await checkAuth(ctx, true);
|
await checkAuth(ctx, true);
|
||||||
@@ -66,6 +76,7 @@ app
|
|||||||
.route({
|
.route({
|
||||||
path: 'client',
|
path: 'client',
|
||||||
key: 'version',
|
key: 'version',
|
||||||
|
description: '获取客户端版本号',
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
ctx.body = 'v1.0.0';
|
ctx.body = 'v1.0.0';
|
||||||
@@ -76,6 +87,7 @@ app
|
|||||||
.route({
|
.route({
|
||||||
path: 'client',
|
path: 'client',
|
||||||
key: 'time',
|
key: 'time',
|
||||||
|
description: '获取当前时间',
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
import './call.ts'
|
import './call.ts'
|
||||||
|
|
||||||
|
import './upload.ts'
|
||||||
10
assistant/src/routes/light-code/upload.ts
Normal file
10
assistant/src/routes/light-code/upload.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { app } from '../../app.ts';
|
||||||
|
|
||||||
|
app.route({
|
||||||
|
path: 'light-code',
|
||||||
|
key: 'upload',
|
||||||
|
middleware: ['auth'],
|
||||||
|
description: '上传轻代码应用代码',
|
||||||
|
}).define(async (ctx) => {
|
||||||
|
const files = ctx.query.files;
|
||||||
|
}).addTo(app);
|
||||||
@@ -5,7 +5,10 @@ import { shopDefine } from './define.ts';
|
|||||||
app
|
app
|
||||||
.route({
|
.route({
|
||||||
...shopDefine.get('getRegistry'),
|
...shopDefine.get('getRegistry'),
|
||||||
middleware: ['auth'],
|
middleware: ['admin-auth'],
|
||||||
|
metadata: {
|
||||||
|
admin: true,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const registry = assistantConfig.getRegistry();
|
const registry = assistantConfig.getRegistry();
|
||||||
@@ -17,7 +20,10 @@ app
|
|||||||
app
|
app
|
||||||
.route({
|
.route({
|
||||||
...shopDefine.get('listInstalled'),
|
...shopDefine.get('listInstalled'),
|
||||||
middleware: ['auth'],
|
middleware: ['admin-auth'],
|
||||||
|
metadata: {
|
||||||
|
admin: true,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const manager = new AssistantApp(assistantConfig);
|
const manager = new AssistantApp(assistantConfig);
|
||||||
@@ -30,7 +36,10 @@ app
|
|||||||
app
|
app
|
||||||
.route({
|
.route({
|
||||||
...shopDefine.get('install'),
|
...shopDefine.get('install'),
|
||||||
middleware: ['auth'],
|
middleware: ['admin-auth'],
|
||||||
|
metadata: {
|
||||||
|
admin: true,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
// https://localhost:51015/client/router?path=shop&key=install
|
// https://localhost:51015/client/router?path=shop&key=install
|
||||||
@@ -52,7 +61,10 @@ app
|
|||||||
app
|
app
|
||||||
.route({
|
.route({
|
||||||
...shopDefine.get('uninstall'),
|
...shopDefine.get('uninstall'),
|
||||||
middleware: ['auth'],
|
middleware: ['admin-auth'],
|
||||||
|
metadata: {
|
||||||
|
admin: true,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
// https://localhost:51015/client/router?path=shop&key=uninstall
|
// https://localhost:51015/client/router?path=shop&key=uninstall
|
||||||
|
|||||||
34
assistant/src/routes/user/index.ts
Normal file
34
assistant/src/routes/user/index.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { app, assistantConfig } from '../../app.ts';
|
||||||
|
|
||||||
|
app.route({
|
||||||
|
path: 'admin',
|
||||||
|
key: 'login',
|
||||||
|
description: '管理员用户登录',
|
||||||
|
}).define(async (ctx) => {
|
||||||
|
const { username, password } = ctx.query;
|
||||||
|
const query = assistantConfig.query;
|
||||||
|
const auth = assistantConfig.getConfig().auth;
|
||||||
|
const res = await query.post({
|
||||||
|
path: 'user',
|
||||||
|
key: 'login',
|
||||||
|
data: {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (res.code !== 200) {
|
||||||
|
return ctx.throw(401, 'login failed');
|
||||||
|
}
|
||||||
|
const loginUser = res.data.username;
|
||||||
|
if (auth.username && loginUser !== auth.username) {
|
||||||
|
return ctx.throw(403, 'login user is not admin user');
|
||||||
|
}
|
||||||
|
if (!auth.username) {
|
||||||
|
// 初始管理员账号
|
||||||
|
auth.username = 'admin';
|
||||||
|
assistantConfig.setConfig({ auth });
|
||||||
|
}
|
||||||
|
// 保存配置
|
||||||
|
|
||||||
|
ctx.body = res.data;
|
||||||
|
}).addTo(app);
|
||||||
@@ -3,6 +3,8 @@ import path from 'node:path';
|
|||||||
import { checkFileExists, AssistantConfig, AssistantConfigData, parseHomeArg, parseHelpArg } from '@/module/assistant/index.ts';
|
import { checkFileExists, AssistantConfig, AssistantConfigData, parseHomeArg, parseHelpArg } from '@/module/assistant/index.ts';
|
||||||
import { chalk } from '@/module/chalk.ts';
|
import { chalk } from '@/module/chalk.ts';
|
||||||
import { HttpsPem } from '@/module/assistant/https/sign.ts';
|
import { HttpsPem } from '@/module/assistant/https/sign.ts';
|
||||||
|
import { Query } from '@kevisual/query/query';
|
||||||
|
|
||||||
export { parseHomeArg, parseHelpArg };
|
export { parseHomeArg, parseHelpArg };
|
||||||
export type AssistantInitOptions = {
|
export type AssistantInitOptions = {
|
||||||
path?: string;
|
path?: string;
|
||||||
@@ -13,6 +15,7 @@ export type AssistantInitOptions = {
|
|||||||
* @class AssistantInit
|
* @class AssistantInit
|
||||||
*/
|
*/
|
||||||
export class AssistantInit extends AssistantConfig {
|
export class AssistantInit extends AssistantConfig {
|
||||||
|
#query: Query
|
||||||
constructor(opts?: AssistantInitOptions) {
|
constructor(opts?: AssistantInitOptions) {
|
||||||
const configDir = opts?.path || process.cwd();
|
const configDir = opts?.path || process.cwd();
|
||||||
super({
|
super({
|
||||||
@@ -39,6 +42,17 @@ export class AssistantInit extends AssistantConfig {
|
|||||||
this.createOtherConfig();
|
this.createOtherConfig();
|
||||||
this.initPnpm();
|
this.initPnpm();
|
||||||
}
|
}
|
||||||
|
get query() {
|
||||||
|
if (!this.#query) {
|
||||||
|
this.setQuery();
|
||||||
|
}
|
||||||
|
return this.#query;
|
||||||
|
}
|
||||||
|
setQuery(query?: Query) {
|
||||||
|
this.#query = query || new Query({
|
||||||
|
url: `${this.getConfig()?.pageApi || 'https://kevisual.cn'}/api/router`,
|
||||||
|
});
|
||||||
|
}
|
||||||
checkConfigPath() {
|
checkConfigPath() {
|
||||||
const assistantPath = path.join(this.configDir, 'assistant-app', 'assistant-config.json');
|
const assistantPath = path.join(this.configDir, 'assistant-app', 'assistant-config.json');
|
||||||
return checkFileExists(assistantPath);
|
return checkFileExists(assistantPath);
|
||||||
|
|||||||
@@ -5,18 +5,6 @@ const config = getConfig();
|
|||||||
export const baseURL = config?.baseURL || 'https://kevisual.cn';
|
export const baseURL = config?.baseURL || 'https://kevisual.cn';
|
||||||
export { storage };
|
export { storage };
|
||||||
export const getBaseURL = () => {
|
export const getBaseURL = () => {
|
||||||
if (typeof config?.dev === 'undefined') {
|
|
||||||
return baseURL;
|
|
||||||
}
|
|
||||||
if (typeof config?.dev === 'string') {
|
|
||||||
if (config?.dev === 'true') {
|
|
||||||
return 'http://localhost:4002';
|
|
||||||
}
|
|
||||||
return baseURL;
|
|
||||||
}
|
|
||||||
if (config?.dev === true) {
|
|
||||||
return 'http://localhost:4002';
|
|
||||||
}
|
|
||||||
return baseURL;
|
return baseURL;
|
||||||
};
|
};
|
||||||
export const query = new Query({
|
export const query = new Query({
|
||||||
|
|||||||
Reference in New Issue
Block a user