fix: fix错误

This commit is contained in:
xion 2025-02-26 01:59:46 +08:00
parent 69721f3944
commit 3477d098b7
14 changed files with 71 additions and 75 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@kevisual/code-center", "name": "@kevisual/code-center",
"version": "0.0.3", "version": "0.0.4",
"description": "code center", "description": "code center",
"type": "module", "type": "module",
"main": "index.js", "main": "index.js",
@ -12,13 +12,9 @@
"dev:watch": "cross-env NODE_ENV=development concurrently -n \"Watch,Dev\" -c \"green,blue\" \"npm run watch\" \"sleep 1 && npm run dev\" ", "dev:watch": "cross-env NODE_ENV=development concurrently -n \"Watch,Dev\" -c \"green,blue\" \"npm run watch\" \"sleep 1 && npm run dev\" ",
"build": "rimraf dist && rollup -c rollup.config.mjs", "build": "rimraf dist && rollup -c rollup.config.mjs",
"deploy": "rsync -avz --delete ./dist/ --exclude='app.config.json5' light:~/apps/codecenter/dist", "deploy": "rsync -avz --delete ./dist/ --exclude='app.config.json5' light:~/apps/codecenter/dist",
"demo": "rsync -avz --delete ./dist/ on:~/docker/kevisual/dist",
"clean": "rm -rf dist", "clean": "rm -rf dist",
"reload": "ssh light pm2 restart codecenter", "reload": "ssh light pm2 restart codecenter",
"pub": "npm run build && npm run deploy && npm run reload", "pub": "npm run build && npm run deploy && npm run reload",
"deploy:nova": "rsync -avz --delete ./dist/ --exclude='app.config.json5' nova:~/apps/codecenter/dist",
"apps:build": "rollup -c rollup.apps.config.mjs",
"apps:watch": "rollup -c rollup.apps.config.mjs -w",
"start": "pm2 start dist/app.mjs --name codecenter", "start": "pm2 start dist/app.mjs --name codecenter",
"release": "node ./script/release/index.mjs" "release": "node ./script/release/index.mjs"
}, },
@ -34,7 +30,7 @@
"@kevisual/auth": "1.0.5", "@kevisual/auth": "1.0.5",
"@kevisual/local-app-manager": "0.1.9", "@kevisual/local-app-manager": "0.1.9",
"@kevisual/router": "^0.0.6", "@kevisual/router": "^0.0.6",
"@kevisual/use-config": "^1.0.7", "@kevisual/use-config": "^1.0.8",
"@types/semver": "^7.5.8", "@types/semver": "^7.5.8",
"archiver": "^7.0.1", "archiver": "^7.0.1",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",

View File

@ -1,15 +1,20 @@
import { App } from '@kevisual/router'; import { App } from '@kevisual/router';
import { useConfig } from '@kevisual/use-config'; import { useConfig } from '@kevisual/use-config';
import { dynamicImport } from './lib/dynamic-import.ts'; import { dynamicImport } from './lib/dynamic-import.ts';
import { redisPublisher, redisSubscriber, redis } from './modules/redis.ts'; import * as redisLib from './modules/redis.ts';
import { minioClient } from './modules/minio.ts'; import * as minioLib from './modules/minio.ts';
import { sequelize } from './modules/sequelize.ts'; import * as sequelizeLib from './modules/sequelize.ts';
import { useContextKey, useContext } from '@kevisual/use-config/context'; import { useContextKey, useContext } from '@kevisual/use-config/context';
useConfig(); useConfig();
export { redis, minioClient, sequelize }; export const redis = useContextKey('redis', () => redisLib.redis);
export const redisPublisher = useContextKey('redisPublisher', () => redisLib.redisPublisher);
export const redisSubscriber = useContextKey('redisSubscriber', () => redisLib.redisSubscriber);
export const minioClient = useContextKey('minioClient', () => minioLib.minioClient);
export const sequelize = useContextKey('sequelize', () => sequelizeLib.sequelize);
export const hasMain = useContextKey('hasMain', () => true);
const init = () => { const init = () => {
console.log('init app', global.context);
return new App<{ import: any; sequelize: typeof sequelize }>({ return new App<{ import: any; sequelize: typeof sequelize }>({
serverOptions: { serverOptions: {
cors: { cors: {

View File

@ -2,18 +2,12 @@ import { useConfig } from '@kevisual/use-config';
import { app } from './app.ts'; import { app } from './app.ts';
import './route.ts'; import './route.ts';
const config = useConfig(); const config = useConfig();
// import { app as aiApp } from '@kevisual/ai-lang/src/index.ts';
import { uploadMiddleware } from './routes-simple/upload.ts'; import { uploadMiddleware } from './routes-simple/upload.ts';
import { loadApps } from './load-apps.ts';
// export { aiApp };
export { app };
loadApps(app);
// if (import.meta.url === `file://${process.argv[1]}`) { // if (import.meta.url === `file://${process.argv[1]}`) {
app.listen(config.port, () => { app.listen(config.port, () => {
console.log(`server is running at http://localhost:${config.port}`); console.log(`server is running at http://localhost:${config.port}`);
}); });
app.server.on(uploadMiddleware); app.server.on(uploadMiddleware);
// }
console.log(`run ${config.appName} done`); console.log(`run ${config.appName} done`);

View File

@ -1,28 +0,0 @@
import path from 'path'
import * as glob from 'fast-glob'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const files = glob.sync(path.resolve(__dirname, './apps/**/index.mjs'))
export const loadApps = async (app: any) => {
const directory = files.map((file: string) => {
const dirname = path.dirname(file)
const lastDirectory = path.basename(dirname)
return lastDirectory
})
console.log('directory', directory)
for (const file of files) {
try {
const module = await import(file)
if (module.render) {
module.render(app)
}
} catch (error) {
console.error(error)
}
}
}

View File

@ -128,7 +128,7 @@ export class User extends Model {
} }
const cache = await redis.get(`user:${id}:orgs`); const cache = await redis.get(`user:${id}:orgs`);
if (cache) { if (cache) {
return JSON.parse(cache); return JSON.parse(cache) as string[];
} }
const orgs = await Org.findAll({ const orgs = await Org.findAll({
order: [['updatedAt', 'DESC']], order: [['updatedAt', 'DESC']],
@ -229,9 +229,8 @@ User.sync({ alter: true, logging: false })
const letter = 'abcdefghijklmnopqrstuvwxyz'; const letter = 'abcdefghijklmnopqrstuvwxyz';
const custom = customAlphabet(letter, 6); const custom = customAlphabet(letter, 6);
export const initializeUser = async (pwd = custom()) => { export const initializeUser = async (pwd = custom()) => {
const w = await User.findAndCountAll(); const w = await User.findOne({ where: { username: 'root' }, logging: false });
console.info('[User count]', w.count); if (!w) {
if (w.count < 1) {
const root = await User.createUser('root', pwd, '系统管理员'); const root = await User.createUser('root', pwd, '系统管理员');
const org = await User.createOrg('admin', root.id, '管理员'); const org = await User.createOrg('admin', root.id, '管理员');
console.info(' new Users name', root.username, org.username); console.info(' new Users name', root.username, org.username);
@ -250,10 +249,6 @@ export const initializeUser = async (pwd = custom()) => {
} }
}; };
export const createDemoUser = async (username = 'demo', pwd = custom()) => { export const createDemoUser = async (username = 'demo', pwd = custom()) => {
const w = await User.findAndCountAll({
logging: false,
});
console.info('[User count]', w.count);
const u = await User.findOne({ where: { username }, logging: false }); const u = await User.findOne({ where: { username }, logging: false });
if (!u) { if (!u) {
const user = await User.createUser(username, pwd, 'demo'); const user = await User.createUser(username, pwd, 'demo');

View File

@ -5,4 +5,7 @@ type MinioConfig = {
}; };
const config = useConfig<MinioConfig>(); const config = useConfig<MinioConfig>();
/**
* cookie的域名
*/
export const domain = config.domain || 'xiongxiao.me'; export const domain = config.domain || 'xiongxiao.me';

View File

@ -18,7 +18,6 @@ export const redis = new Redis({
maxRetriesPerRequest: null, // 允许请求重试的次数 (如果需要无限次重试) maxRetriesPerRequest: null, // 允许请求重试的次数 (如果需要无限次重试)
...config.redis, ...config.redis,
}); });
console.log('redis', config.redis);
// 监听连接事件 // 监听连接事件
redis.on('connect', () => { redis.on('connect', () => {

View File

@ -5,7 +5,7 @@ const config = useConfig<{
}>(); }>();
export const selfRestart = async () => { export const selfRestart = async () => {
const appName = config.appName || 'codeflow'; const appName = config.appName || 'codecenter';
// 检测 pm2 是否安装和是否有 appName 这个应用 // 检测 pm2 是否安装和是否有 appName 这个应用
try { try {
const res = childProcess.execSync(`pm2 list`); const res = childProcess.execSync(`pm2 list`);

View File

@ -1,8 +1,7 @@
// import './demo/index.ts';
// import { app as adminApp, appendTo } from './admin/index.ts';
import './routes/index.ts'; import './routes/index.ts';
import { app } from './app.ts'; import { app } from './app.ts';
import { useConfig } from '@kevisual/use-config'; import { useConfig } from '@kevisual/use-config';
import { User } from './models/user.ts';
import { createAuthRoute } from '@kevisual/auth'; import { createAuthRoute } from '@kevisual/auth';
const config = useConfig<{ tokenSecret: string }>(); const config = useConfig<{ tokenSecret: string }>();
@ -16,18 +15,28 @@ app
path: 'auth', path: 'auth',
key: 'admin', key: 'admin',
id: 'auth-admin', id: 'auth-admin',
middleware: ['auth'],
}) })
.define(async (ctx) => { .define(async (ctx) => {
// ctx.body = 'admin'; const tokenUser = ctx.state.tokenUser;
const token = ctx.query?.token; const user = await User.findOne({
// where: {
id: tokenUser.id,
},
});
if (!user) {
ctx.throw(404, 'user not found');
}
const orgs = await user.getOrgs();
if (orgs.includes('admin')) {
ctx.body = 'admin';
} else {
ctx.throw(403, 'forbidden');
}
}) })
.addTo(app); .addTo(app);
// app.importApp(adminApp);
// appendTo(app);
app app
.route({ .route({
path: 'test', path: 'test',

View File

@ -1,2 +1,3 @@
import { SimpleRouter } from '@kevisual/router/simple'; import { SimpleRouter } from '@kevisual/router/simple';
export const router = new SimpleRouter(); import { useContextKey } from '@kevisual/use-config/context';
export const router = useContextKey('router', () => new SimpleRouter());

View File

@ -259,5 +259,8 @@ router.get('/api/code/version', async (req, res) => {
}); });
export const uploadMiddleware = async (req: http.IncomingMessage, res: http.ServerResponse) => { export const uploadMiddleware = async (req: http.IncomingMessage, res: http.ServerResponse) => {
if (req.url?.startsWith('/api/router')) {
return;
}
return router.parse(req, res); return router.parse(req, res);
}; };

View File

@ -1,8 +1,15 @@
import { sequelize } from '../../../modules/sequelize.ts'; import { sequelize } from '../../../modules/sequelize.ts';
import { DataTypes, Model } from 'sequelize'; import { DataTypes, Model } from 'sequelize';
type AppPermissionType = 'public' | 'private' | 'protected';
export interface AppData { export interface AppData {
files: { name: string; path: string }[]; files: { name: string; path: string }[];
permission?: {
// 访问权限
type: AppPermissionType; // public, private(Only Self), protected(protected, 通过配置访问)
users?: string[];
orgs?: string[];
};
} }
export type AppType = 'web-single' | 'web-module'; export type AppType = 'web-single' | 'web-module';
export enum AppStatus { export enum AppStatus {
@ -45,7 +52,7 @@ AppModel.init(
defaultValue: '', defaultValue: '',
}, },
data: { data: {
type: DataTypes.JSON, type: DataTypes.JSONB,
defaultValue: {}, defaultValue: {},
}, },
version: { version: {

View File

@ -60,11 +60,19 @@ app
}; };
return; return;
} }
const user = await User.createOrg(username, tokenUser.id, description); const user = await User.findByPk(tokenUser.id);
if (!user) {
throw new CustomError('user not found');
}
const orgs = await user.getOrgs();
if (!orgs.includes('admin')) {
throw new CustomError('Permission denied');
}
const newUser = await User.createOrg(username, tokenUser.id, description);
ctx.body = { ctx.body = {
id: user.id, id: newUser.id,
username: user.username, username: newUser.username,
description: user.description, description: newUser.description,
}; };
}) })
.addTo(app); .addTo(app);

View File

@ -1,11 +1,12 @@
import { app } from '@/app.ts'; import { app } from '@/app.ts';
import { User } from '@/models/user.ts'; import { User } from '@/models/user.ts';
import { log } from 'console';
import MD5 from 'crypto-js/md5.js'; import MD5 from 'crypto-js/md5.js';
import jsonwebtoken from 'jsonwebtoken'; import jsonwebtoken from 'jsonwebtoken';
const tokenData: Record<string, string> = {}; // const tokenData: Record<string, string> = {};
import { redis } from '@/app.ts';
app app
.route({ .route({
path: 'user', path: 'user',
@ -39,7 +40,7 @@ app
ctx.throw(400, 'sign error'); ctx.throw(400, 'sign error');
} }
const user = await User.findByPk(tokenUser.id); const user = await User.findByPk(tokenUser.id);
console.log('tokenUser', tokenUser) console.log('tokenUser', tokenUser);
if (!user) { if (!user) {
ctx.throw(400, 'user not found'); ctx.throw(400, 'user not found');
} }
@ -59,7 +60,9 @@ app
); );
// ctx.body = data; // ctx.body = data;
tokenData[loginToken] = data; // tokenData[loginToken] = data;
await redis.set(loginToken, data, 'EX', 3600); // 1小时
ctx.body = 'success';
}) })
.addTo(app); .addTo(app);
@ -73,7 +76,8 @@ app
if (!loginToken) { if (!loginToken) {
ctx.throw(400, 'loginToken is required'); ctx.throw(400, 'loginToken is required');
} }
const data = tokenData[loginToken]; // const data = tokenData[loginToken];
const data = await redis.get(loginToken);
if (data) { if (data) {
ctx.body = data; ctx.body = data;
} else { } else {