fix: fix错误
This commit is contained in:
		| @@ -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", | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								src/app.ts
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/app.ts
									
									
									
									
									
								
							| @@ -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: { | ||||||
|   | |||||||
| @@ -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`); | ||||||
|   | |||||||
| @@ -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) |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -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'); | ||||||
|   | |||||||
| @@ -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'; | ||||||
|   | |||||||
| @@ -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', () => { | ||||||
|   | |||||||
| @@ -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`); | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								src/route.ts
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								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 './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', | ||||||
|   | |||||||
| @@ -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()); | ||||||
|   | |||||||
| @@ -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); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -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: { | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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 { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user