From 3477d098b740bbaec1c6bf7f2e7320f6be422298 Mon Sep 17 00:00:00 2001 From: xion Date: Wed, 26 Feb 2025 01:59:46 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20fix=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 8 ++------ src/app.ts | 15 ++++++++++----- src/index.ts | 6 ------ src/load-apps.ts | 28 ---------------------------- src/models/user.ts | 11 +++-------- src/modules/domain.ts | 3 +++ src/modules/redis.ts | 1 - src/modules/self-restart.ts | 2 +- src/route.ts | 27 ++++++++++++++++++--------- src/routes-simple/router.ts | 3 ++- src/routes-simple/upload.ts | 3 +++ src/routes/app-manager/module/app.ts | 9 ++++++++- src/routes/user/org.ts | 16 ++++++++++++---- src/routes/user/web-login.ts | 14 +++++++++----- 14 files changed, 71 insertions(+), 75 deletions(-) delete mode 100644 src/load-apps.ts diff --git a/package.json b/package.json index 3c5c978..cd1e52c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kevisual/code-center", - "version": "0.0.3", + "version": "0.0.4", "description": "code center", "type": "module", "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\" ", "build": "rimraf dist && rollup -c rollup.config.mjs", "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", "reload": "ssh light pm2 restart codecenter", "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", "release": "node ./script/release/index.mjs" }, @@ -34,7 +30,7 @@ "@kevisual/auth": "1.0.5", "@kevisual/local-app-manager": "0.1.9", "@kevisual/router": "^0.0.6", - "@kevisual/use-config": "^1.0.7", + "@kevisual/use-config": "^1.0.8", "@types/semver": "^7.5.8", "archiver": "^7.0.1", "crypto-js": "^4.2.0", diff --git a/src/app.ts b/src/app.ts index 84b6e86..088d1e5 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,15 +1,20 @@ import { App } from '@kevisual/router'; import { useConfig } from '@kevisual/use-config'; import { dynamicImport } from './lib/dynamic-import.ts'; -import { redisPublisher, redisSubscriber, redis } from './modules/redis.ts'; -import { minioClient } from './modules/minio.ts'; -import { sequelize } from './modules/sequelize.ts'; +import * as redisLib from './modules/redis.ts'; +import * as minioLib from './modules/minio.ts'; +import * as sequelizeLib from './modules/sequelize.ts'; import { useContextKey, useContext } from '@kevisual/use-config/context'; + 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 = () => { - console.log('init app', global.context); return new App<{ import: any; sequelize: typeof sequelize }>({ serverOptions: { cors: { diff --git a/src/index.ts b/src/index.ts index fab712e..1c1f37a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,18 +2,12 @@ import { useConfig } from '@kevisual/use-config'; import { app } from './app.ts'; import './route.ts'; const config = useConfig(); -// import { app as aiApp } from '@kevisual/ai-lang/src/index.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]}`) { app.listen(config.port, () => { console.log(`server is running at http://localhost:${config.port}`); }); app.server.on(uploadMiddleware); -// } console.log(`run ${config.appName} done`); diff --git a/src/load-apps.ts b/src/load-apps.ts deleted file mode 100644 index 482fae8..0000000 --- a/src/load-apps.ts +++ /dev/null @@ -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) - } - } -} diff --git a/src/models/user.ts b/src/models/user.ts index 6cf8d6b..f239d11 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -128,7 +128,7 @@ export class User extends Model { } const cache = await redis.get(`user:${id}:orgs`); if (cache) { - return JSON.parse(cache); + return JSON.parse(cache) as string[]; } const orgs = await Org.findAll({ order: [['updatedAt', 'DESC']], @@ -229,9 +229,8 @@ User.sync({ alter: true, logging: false }) const letter = 'abcdefghijklmnopqrstuvwxyz'; const custom = customAlphabet(letter, 6); export const initializeUser = async (pwd = custom()) => { - const w = await User.findAndCountAll(); - console.info('[User count]', w.count); - if (w.count < 1) { + const w = await User.findOne({ where: { username: 'root' }, logging: false }); + if (!w) { const root = await User.createUser('root', pwd, '系统管理员'); const org = await User.createOrg('admin', root.id, '管理员'); 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()) => { - const w = await User.findAndCountAll({ - logging: false, - }); - console.info('[User count]', w.count); const u = await User.findOne({ where: { username }, logging: false }); if (!u) { const user = await User.createUser(username, pwd, 'demo'); diff --git a/src/modules/domain.ts b/src/modules/domain.ts index d56a22d..3516ce6 100644 --- a/src/modules/domain.ts +++ b/src/modules/domain.ts @@ -5,4 +5,7 @@ type MinioConfig = { }; const config = useConfig(); +/** + * 用来放cookie的域名 + */ export const domain = config.domain || 'xiongxiao.me'; diff --git a/src/modules/redis.ts b/src/modules/redis.ts index 286ca20..e83ff13 100644 --- a/src/modules/redis.ts +++ b/src/modules/redis.ts @@ -18,7 +18,6 @@ export const redis = new Redis({ maxRetriesPerRequest: null, // 允许请求重试的次数 (如果需要无限次重试) ...config.redis, }); -console.log('redis', config.redis); // 监听连接事件 redis.on('connect', () => { diff --git a/src/modules/self-restart.ts b/src/modules/self-restart.ts index 2dbbcd2..34cc101 100644 --- a/src/modules/self-restart.ts +++ b/src/modules/self-restart.ts @@ -5,7 +5,7 @@ const config = useConfig<{ }>(); export const selfRestart = async () => { - const appName = config.appName || 'codeflow'; + const appName = config.appName || 'codecenter'; // 检测 pm2 是否安装和是否有 appName 这个应用 try { const res = childProcess.execSync(`pm2 list`); diff --git a/src/route.ts b/src/route.ts index 1390a34..7ac46c8 100644 --- a/src/route.ts +++ b/src/route.ts @@ -1,8 +1,7 @@ -// import './demo/index.ts'; -// import { app as adminApp, appendTo } from './admin/index.ts'; import './routes/index.ts'; import { app } from './app.ts'; import { useConfig } from '@kevisual/use-config'; +import { User } from './models/user.ts'; import { createAuthRoute } from '@kevisual/auth'; const config = useConfig<{ tokenSecret: string }>(); @@ -16,18 +15,28 @@ app path: 'auth', key: 'admin', id: 'auth-admin', + middleware: ['auth'], }) .define(async (ctx) => { - // ctx.body = 'admin'; - const token = ctx.query?.token; - // + const tokenUser = ctx.state.tokenUser; + 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); -// app.importApp(adminApp); - -// appendTo(app); - app .route({ path: 'test', diff --git a/src/routes-simple/router.ts b/src/routes-simple/router.ts index 180e91e..7cb2f61 100644 --- a/src/routes-simple/router.ts +++ b/src/routes-simple/router.ts @@ -1,2 +1,3 @@ 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()); diff --git a/src/routes-simple/upload.ts b/src/routes-simple/upload.ts index c8d5134..5edd078 100644 --- a/src/routes-simple/upload.ts +++ b/src/routes-simple/upload.ts @@ -259,5 +259,8 @@ router.get('/api/code/version', async (req, res) => { }); export const uploadMiddleware = async (req: http.IncomingMessage, res: http.ServerResponse) => { + if (req.url?.startsWith('/api/router')) { + return; + } return router.parse(req, res); }; diff --git a/src/routes/app-manager/module/app.ts b/src/routes/app-manager/module/app.ts index 0a1daf5..01af206 100644 --- a/src/routes/app-manager/module/app.ts +++ b/src/routes/app-manager/module/app.ts @@ -1,8 +1,15 @@ import { sequelize } from '../../../modules/sequelize.ts'; import { DataTypes, Model } from 'sequelize'; +type AppPermissionType = 'public' | 'private' | 'protected'; export interface AppData { 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 enum AppStatus { @@ -45,7 +52,7 @@ AppModel.init( defaultValue: '', }, data: { - type: DataTypes.JSON, + type: DataTypes.JSONB, defaultValue: {}, }, version: { diff --git a/src/routes/user/org.ts b/src/routes/user/org.ts index 65725e8..8e0f24d 100644 --- a/src/routes/user/org.ts +++ b/src/routes/user/org.ts @@ -60,11 +60,19 @@ app }; 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 = { - id: user.id, - username: user.username, - description: user.description, + id: newUser.id, + username: newUser.username, + description: newUser.description, }; }) .addTo(app); diff --git a/src/routes/user/web-login.ts b/src/routes/user/web-login.ts index aa8bb84..5d80328 100644 --- a/src/routes/user/web-login.ts +++ b/src/routes/user/web-login.ts @@ -1,11 +1,12 @@ import { app } from '@/app.ts'; import { User } from '@/models/user.ts'; -import { log } from 'console'; import MD5 from 'crypto-js/md5.js'; import jsonwebtoken from 'jsonwebtoken'; -const tokenData: Record = {}; +// const tokenData: Record = {}; +import { redis } from '@/app.ts'; + app .route({ path: 'user', @@ -39,7 +40,7 @@ app ctx.throw(400, 'sign error'); } const user = await User.findByPk(tokenUser.id); - console.log('tokenUser', tokenUser) + console.log('tokenUser', tokenUser); if (!user) { ctx.throw(400, 'user not found'); } @@ -59,7 +60,9 @@ app ); // ctx.body = data; - tokenData[loginToken] = data; + // tokenData[loginToken] = data; + await redis.set(loginToken, data, 'EX', 3600); // 1小时 + ctx.body = 'success'; }) .addTo(app); @@ -73,7 +76,8 @@ app if (!loginToken) { ctx.throw(400, 'loginToken is required'); } - const data = tokenData[loginToken]; + // const data = tokenData[loginToken]; + const data = await redis.get(loginToken); if (data) { ctx.body = data; } else {