feat: add minio list detect
This commit is contained in:
parent
1c820c3083
commit
efef48a1b0
@ -12,9 +12,12 @@
|
|||||||
"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",
|
||||||
|
"deploy:sky": "rsync -avz --delete ./dist/ --exclude='app.config.json5' sky:~/kevisual/dist",
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"reload": "ssh light pm2 restart codecenter",
|
"reload": "ssh light pm2 restart codecenter",
|
||||||
|
"reload:sky": "ssh sky pm2 restart codecenter",
|
||||||
"pub:me": "npm run build && npm run deploy && npm run reload",
|
"pub:me": "npm run build && npm run deploy && npm run reload",
|
||||||
|
"pub:sky": "npm run build && npm run deploy:sky && npm run reload:sky",
|
||||||
"start": "pm2 start dist/app.mjs --name codecenter",
|
"start": "pm2 start dist/app.mjs --name codecenter",
|
||||||
"release": "node ./config/release/index.mjs",
|
"release": "node ./config/release/index.mjs",
|
||||||
"pub": "envision pack -p -u",
|
"pub": "envision pack -p -u",
|
||||||
|
@ -2,8 +2,8 @@ import { App, CustomError } from '@kevisual/router';
|
|||||||
import { AppModel, AppListModel } from './module/index.ts';
|
import { AppModel, AppListModel } from './module/index.ts';
|
||||||
import { app, redis } from '@/app.ts';
|
import { app, redis } from '@/app.ts';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { prefixFix } from './util.ts';
|
import { getUidByUsername, prefixFix } from './util.ts';
|
||||||
import { deleteFiles } from '../file/index.ts';
|
import { deleteFiles, getMinioListAndSetToAppList } from '../file/index.ts';
|
||||||
import { setExpire } from './revoke.ts';
|
import { setExpire } from './revoke.ts';
|
||||||
import { User } from '@/models/user.ts';
|
import { User } from '@/models/user.ts';
|
||||||
app
|
app
|
||||||
@ -67,7 +67,7 @@ app
|
|||||||
const newData = { ...app.data, ...data };
|
const newData = { ...app.data, ...data };
|
||||||
const newApp = await app.update({ data: newData, ...rest });
|
const newApp = await app.update({ data: newData, ...rest });
|
||||||
ctx.body = newApp;
|
ctx.body = newApp;
|
||||||
setExpire(newApp.id, tokenUser.username);
|
setExpire(newApp.id, 'test');
|
||||||
} else {
|
} else {
|
||||||
throw new CustomError('app not found');
|
throw new CustomError('app not found');
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ app
|
|||||||
const dataFiles = app.data.files || [];
|
const dataFiles = app.data.files || [];
|
||||||
const newFiles = _.uniqBy([...dataFiles, ...files], 'name');
|
const newFiles = _.uniqBy([...dataFiles, ...files], 'name');
|
||||||
const res = await app.update({ data: { ...app.data, files: newFiles } });
|
const res = await app.update({ data: { ...app.data, files: newFiles } });
|
||||||
setExpire(app.id, userPrefix);
|
setExpire(app.id, 'test');
|
||||||
ctx.body = prefixFix(res, userPrefix);
|
ctx.body = prefixFix(res, userPrefix);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('update error', e);
|
console.log('update error', e);
|
||||||
@ -211,24 +211,26 @@ app
|
|||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const tokenUser = ctx.state.tokenUser;
|
const tokenUser = ctx.state.tokenUser;
|
||||||
const { id } = ctx.query.data;
|
const { id, username } = ctx.query.data;
|
||||||
if (!id) {
|
if (!id) {
|
||||||
throw new CustomError('id is required');
|
throw new CustomError('id is required');
|
||||||
}
|
}
|
||||||
const app = await AppListModel.findByPk(id);
|
|
||||||
if (!app) {
|
const uid = await getUidByUsername(app, ctx, username);
|
||||||
|
const appList = await AppListModel.findByPk(id);
|
||||||
|
if (!appList) {
|
||||||
throw new CustomError('app not found');
|
throw new CustomError('app not found');
|
||||||
}
|
}
|
||||||
const files = app.data.files || [];
|
const files = appList.data.files || [];
|
||||||
const am = await AppModel.findOne({ where: { key: app.key, uid: tokenUser.id } });
|
const am = await AppModel.findOne({ where: { key: appList.key, uid: uid } });
|
||||||
if (!am) {
|
if (!am) {
|
||||||
throw new CustomError('app not found');
|
throw new CustomError('app not found');
|
||||||
}
|
}
|
||||||
await am.update({ data: { ...am.data, files }, version: app.version });
|
await am.update({ data: { ...am.data, files }, version: appList.version });
|
||||||
setExpire(app.key, am.user);
|
setExpire(appList.key, am.user);
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
key: app.key,
|
key: appList.key,
|
||||||
version: app.version,
|
version: appList.version,
|
||||||
appManager: am,
|
appManager: am,
|
||||||
user: am.user,
|
user: am.user,
|
||||||
};
|
};
|
||||||
@ -274,3 +276,66 @@ app
|
|||||||
return ctx;
|
return ctx;
|
||||||
})
|
})
|
||||||
.addTo(app);
|
.addTo(app);
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'app',
|
||||||
|
key: 'get-minio-list',
|
||||||
|
description: '获取minio列表',
|
||||||
|
middleware: ['auth'],
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
const tokenUser = ctx.state.tokenUser;
|
||||||
|
const { key, version } = ctx.query?.data || {};
|
||||||
|
if (!key || !version) {
|
||||||
|
throw new CustomError('key and version are required');
|
||||||
|
}
|
||||||
|
const files = await getMinioListAndSetToAppList({ username: tokenUser.username, appKey: key, version });
|
||||||
|
ctx.body = files;
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'app',
|
||||||
|
key: 'detect-version-list',
|
||||||
|
description: '检测版本列表,minio中的数据自己上传后,根据版本信息,进行替换',
|
||||||
|
middleware: ['auth'],
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
const tokenUser = ctx.state.tokenUser;
|
||||||
|
let { key, version, username } = ctx.query?.data || {};
|
||||||
|
if (!key || !version) {
|
||||||
|
throw new CustomError('key and version are required');
|
||||||
|
}
|
||||||
|
const uid = await getUidByUsername(app, ctx, username);
|
||||||
|
const appList = await AppListModel.findOne({ where: { key, version, uid: uid } });
|
||||||
|
if (!appList) {
|
||||||
|
throw new CustomError('app not found');
|
||||||
|
}
|
||||||
|
const checkUsername = username || tokenUser.username;
|
||||||
|
const files = await getMinioListAndSetToAppList({ username: checkUsername, appKey: key, version });
|
||||||
|
const newFiles = files.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.name.replace(`${checkUsername}/${key}/${version}/`, ''),
|
||||||
|
path: item.name,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
let appListFiles = appList.data?.files || [];
|
||||||
|
const needAddFiles = newFiles.map((item) => {
|
||||||
|
const findFile = appListFiles.find((appListFile) => appListFile.name === item.name);
|
||||||
|
if (findFile && findFile.path === item.path) {
|
||||||
|
return findFile;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
await appList.update({ data: { files: needAddFiles } });
|
||||||
|
setExpire(appList.id, 'test');
|
||||||
|
const appModel = await AppModel.findOne({ where: { key, version, uid: uid } });
|
||||||
|
if (appModel) {
|
||||||
|
await appModel.update({ data: { files: needAddFiles } });
|
||||||
|
setExpire(appModel.key, appModel.user);
|
||||||
|
}
|
||||||
|
ctx.body = appList;
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
@ -2,6 +2,8 @@ import { CustomError } from '@kevisual/router';
|
|||||||
import { AppModel, AppListModel } from './module/index.ts';
|
import { AppModel, AppListModel } from './module/index.ts';
|
||||||
import { app } from '@/app.ts';
|
import { app } from '@/app.ts';
|
||||||
import { setExpire } from './revoke.ts';
|
import { setExpire } from './revoke.ts';
|
||||||
|
import { getMinioListAndSetToAppList } from '../file/index.ts';
|
||||||
|
import { getUidByUsername } from './util.ts';
|
||||||
|
|
||||||
app
|
app
|
||||||
.route({
|
.route({
|
||||||
@ -111,6 +113,9 @@ app
|
|||||||
if (!am) {
|
if (!am) {
|
||||||
throw new CustomError('app not found');
|
throw new CustomError('app not found');
|
||||||
}
|
}
|
||||||
|
if (am.uid !== tokenUser.id) {
|
||||||
|
throw new CustomError('app not found');
|
||||||
|
}
|
||||||
const list = await AppListModel.findAll({ where: { key: am.key, uid: tokenUser.id } });
|
const list = await AppListModel.findAll({ where: { key: am.key, uid: tokenUser.id } });
|
||||||
await am.destroy({ force: true });
|
await am.destroy({ force: true });
|
||||||
await Promise.all(list.map((item) => item.destroy({ force: true })));
|
await Promise.all(list.map((item) => item.destroy({ force: true })));
|
||||||
@ -123,6 +128,7 @@ app
|
|||||||
.route({
|
.route({
|
||||||
path: 'user-app',
|
path: 'user-app',
|
||||||
key: 'test',
|
key: 'test',
|
||||||
|
description: '对user-app的数据进行测试, 获取版本的信息',
|
||||||
})
|
})
|
||||||
.define(async (ctx) => {
|
.define(async (ctx) => {
|
||||||
const id = ctx.query.id;
|
const id = ctx.query.id;
|
||||||
@ -133,6 +139,12 @@ app
|
|||||||
if (!am) {
|
if (!am) {
|
||||||
throw new CustomError('app not found');
|
throw new CustomError('app not found');
|
||||||
}
|
}
|
||||||
ctx.body = am;
|
const amJson = am.toJSON();
|
||||||
|
ctx.body = {
|
||||||
|
...amJson,
|
||||||
|
proxy: true,
|
||||||
|
};
|
||||||
})
|
})
|
||||||
.addTo(app);
|
.addTo(app);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { App } from '@kevisual/router';
|
||||||
|
|
||||||
type Opts = {
|
type Opts = {
|
||||||
prefix: string;
|
prefix: string;
|
||||||
};
|
};
|
||||||
@ -13,3 +15,34 @@ export const prefixFix = (data: any, prefix: string, opts?: Opts) => {
|
|||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据username获取uid
|
||||||
|
* @param app
|
||||||
|
* @param ctx
|
||||||
|
* @param username
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getUidByUsername = async (app: App, ctx: any, username?: string) => {
|
||||||
|
const tokenUser = ctx.state.tokenUser;
|
||||||
|
let uid = tokenUser.id; // TODO: 需要根据username来判断
|
||||||
|
if (username) {
|
||||||
|
// 这个用户的数据,tokenUser具有这个org的权限才行。真实用户的那个org
|
||||||
|
const res = await app.call({
|
||||||
|
path: 'org',
|
||||||
|
key: 'hasUser',
|
||||||
|
payload: {
|
||||||
|
data: {
|
||||||
|
username,
|
||||||
|
},
|
||||||
|
token: ctx.query.token,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (res.code === 200 && res.body?.uid) {
|
||||||
|
uid = res.body.uid;
|
||||||
|
} else {
|
||||||
|
ctx.throw(500, 'user not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uid;
|
||||||
|
};
|
||||||
|
@ -12,6 +12,12 @@ const handlePrefix = (prefix: string) => {
|
|||||||
}
|
}
|
||||||
return prefix;
|
return prefix;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 根据用户名获取prefix
|
||||||
|
* @param data
|
||||||
|
* @param tokenUser
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
const getPrefixByUser = (data: { prefix: string }, tokenUser: { username: string }) => {
|
const getPrefixByUser = (data: { prefix: string }, tokenUser: { username: string }) => {
|
||||||
const prefixBase = '/' + tokenUser.username;
|
const prefixBase = '/' + tokenUser.username;
|
||||||
const _prefix = handlePrefix(data.prefix);
|
const _prefix = handlePrefix(data.prefix);
|
||||||
@ -63,3 +69,28 @@ app
|
|||||||
return ctx;
|
return ctx;
|
||||||
})
|
})
|
||||||
.addTo(app);
|
.addTo(app);
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'file',
|
||||||
|
key: 'me-all-file-stat',
|
||||||
|
middleware: ['auth'],
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
const tokenUser = ctx.state.tokenUser;
|
||||||
|
const list = await getMinioList({ prefix: '' + tokenUser.username, recursive: true });
|
||||||
|
const size = list.reduce((acc, item) => {
|
||||||
|
if ('size' in item) {
|
||||||
|
return acc + item.size;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, 0);
|
||||||
|
const sizeMb = size / 1024 / 1024;
|
||||||
|
ctx.body = {
|
||||||
|
list,
|
||||||
|
total: list.length,
|
||||||
|
size,
|
||||||
|
sizeMb,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
@ -77,3 +77,16 @@ export const deleteFiles = async (prefixs: string[]): Promise<any> => {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type GetMinioListAndSetToAppListOpts = {
|
||||||
|
username: string;
|
||||||
|
appKey: string;
|
||||||
|
version: string;
|
||||||
|
};
|
||||||
|
// 批量列出文件,并设置到appList的files中
|
||||||
|
export const getMinioListAndSetToAppList = async (opts: GetMinioListAndSetToAppListOpts) => {
|
||||||
|
const { username, appKey, version } = opts;
|
||||||
|
const minioList = await getMinioList({ prefix: `${username}/${appKey}/${version}`, recursive: true });
|
||||||
|
const files = minioList;
|
||||||
|
return files as MinioFile[];
|
||||||
|
};
|
||||||
|
@ -12,6 +12,6 @@ import './app-manager/index.ts';
|
|||||||
|
|
||||||
import './file/index.ts';
|
import './file/index.ts';
|
||||||
|
|
||||||
import './packages/index.ts';
|
// import './packages/index.ts';
|
||||||
|
|
||||||
import './micro-app/index.ts';
|
import './micro-app/index.ts';
|
||||||
|
@ -64,6 +64,7 @@ app
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
ctx.throw('user not found');
|
ctx.throw('user not found');
|
||||||
}
|
}
|
||||||
|
user.setTokenUser(tokenUser);
|
||||||
const orgs = await user.getOrgs();
|
const orgs = await user.getOrgs();
|
||||||
if (!orgs.includes('admin')) {
|
if (!orgs.includes('admin')) {
|
||||||
ctx.throw('Permission denied');
|
ctx.throw('Permission denied');
|
||||||
@ -136,3 +137,38 @@ app
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
.addTo(app);
|
.addTo(app);
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'org',
|
||||||
|
key: 'hasUser',
|
||||||
|
middleware: ['auth'],
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
const tokenUser = ctx.state.tokenUser;
|
||||||
|
const { username } = ctx.query.data;
|
||||||
|
const user = await User.findByPk(tokenUser.id);
|
||||||
|
if (!user) {
|
||||||
|
ctx.throw('user not found');
|
||||||
|
}
|
||||||
|
user.setTokenUser(tokenUser);
|
||||||
|
const userOrgs = await user.hasUser(username, true);
|
||||||
|
if (!userOrgs) {
|
||||||
|
ctx.body = {
|
||||||
|
uid: null,
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const usernameUser = await User.findOne({ where: { username } });
|
||||||
|
if (!usernameUser) {
|
||||||
|
ctx.body = {
|
||||||
|
uid: null,
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx.body = {
|
||||||
|
uid: usernameUser.id,
|
||||||
|
user: usernameUser,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user