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\" ",
|
||||
"build": "rimraf dist && rollup -c rollup.config.mjs",
|
||||
"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",
|
||||
"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:sky": "npm run build && npm run deploy:sky && npm run reload:sky",
|
||||
"start": "pm2 start dist/app.mjs --name codecenter",
|
||||
"release": "node ./config/release/index.mjs",
|
||||
"pub": "envision pack -p -u",
|
||||
|
@ -2,8 +2,8 @@ import { App, CustomError } from '@kevisual/router';
|
||||
import { AppModel, AppListModel } from './module/index.ts';
|
||||
import { app, redis } from '@/app.ts';
|
||||
import _ from 'lodash';
|
||||
import { prefixFix } from './util.ts';
|
||||
import { deleteFiles } from '../file/index.ts';
|
||||
import { getUidByUsername, prefixFix } from './util.ts';
|
||||
import { deleteFiles, getMinioListAndSetToAppList } from '../file/index.ts';
|
||||
import { setExpire } from './revoke.ts';
|
||||
import { User } from '@/models/user.ts';
|
||||
app
|
||||
@ -67,7 +67,7 @@ app
|
||||
const newData = { ...app.data, ...data };
|
||||
const newApp = await app.update({ data: newData, ...rest });
|
||||
ctx.body = newApp;
|
||||
setExpire(newApp.id, tokenUser.username);
|
||||
setExpire(newApp.id, 'test');
|
||||
} else {
|
||||
throw new CustomError('app not found');
|
||||
}
|
||||
@ -194,7 +194,7 @@ app
|
||||
const dataFiles = app.data.files || [];
|
||||
const newFiles = _.uniqBy([...dataFiles, ...files], 'name');
|
||||
const res = await app.update({ data: { ...app.data, files: newFiles } });
|
||||
setExpire(app.id, userPrefix);
|
||||
setExpire(app.id, 'test');
|
||||
ctx.body = prefixFix(res, userPrefix);
|
||||
} catch (e) {
|
||||
console.log('update error', e);
|
||||
@ -211,24 +211,26 @@ app
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id } = ctx.query.data;
|
||||
const { id, username } = ctx.query.data;
|
||||
if (!id) {
|
||||
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');
|
||||
}
|
||||
const files = app.data.files || [];
|
||||
const am = await AppModel.findOne({ where: { key: app.key, uid: tokenUser.id } });
|
||||
const files = appList.data.files || [];
|
||||
const am = await AppModel.findOne({ where: { key: appList.key, uid: uid } });
|
||||
if (!am) {
|
||||
throw new CustomError('app not found');
|
||||
}
|
||||
await am.update({ data: { ...am.data, files }, version: app.version });
|
||||
setExpire(app.key, am.user);
|
||||
await am.update({ data: { ...am.data, files }, version: appList.version });
|
||||
setExpire(appList.key, am.user);
|
||||
ctx.body = {
|
||||
key: app.key,
|
||||
version: app.version,
|
||||
key: appList.key,
|
||||
version: appList.version,
|
||||
appManager: am,
|
||||
user: am.user,
|
||||
};
|
||||
@ -274,3 +276,66 @@ app
|
||||
return ctx;
|
||||
})
|
||||
.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 { app } from '@/app.ts';
|
||||
import { setExpire } from './revoke.ts';
|
||||
import { getMinioListAndSetToAppList } from '../file/index.ts';
|
||||
import { getUidByUsername } from './util.ts';
|
||||
|
||||
app
|
||||
.route({
|
||||
@ -111,6 +113,9 @@ app
|
||||
if (!am) {
|
||||
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 } });
|
||||
await am.destroy({ force: true });
|
||||
await Promise.all(list.map((item) => item.destroy({ force: true })));
|
||||
@ -123,6 +128,7 @@ app
|
||||
.route({
|
||||
path: 'user-app',
|
||||
key: 'test',
|
||||
description: '对user-app的数据进行测试, 获取版本的信息',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const id = ctx.query.id;
|
||||
@ -133,6 +139,12 @@ app
|
||||
if (!am) {
|
||||
throw new CustomError('app not found');
|
||||
}
|
||||
ctx.body = am;
|
||||
const amJson = am.toJSON();
|
||||
ctx.body = {
|
||||
...amJson,
|
||||
proxy: true,
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { App } from '@kevisual/router';
|
||||
|
||||
type Opts = {
|
||||
prefix: string;
|
||||
};
|
||||
@ -13,3 +15,34 @@ export const prefixFix = (data: any, prefix: string, opts?: Opts) => {
|
||||
}
|
||||
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;
|
||||
};
|
||||
/**
|
||||
* 根据用户名获取prefix
|
||||
* @param data
|
||||
* @param tokenUser
|
||||
* @returns
|
||||
*/
|
||||
const getPrefixByUser = (data: { prefix: string }, tokenUser: { username: string }) => {
|
||||
const prefixBase = '/' + tokenUser.username;
|
||||
const _prefix = handlePrefix(data.prefix);
|
||||
@ -63,3 +69,28 @@ app
|
||||
return ctx;
|
||||
})
|
||||
.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;
|
||||
}
|
||||
};
|
||||
|
||||
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 './packages/index.ts';
|
||||
// import './packages/index.ts';
|
||||
|
||||
import './micro-app/index.ts';
|
||||
|
@ -64,6 +64,7 @@ app
|
||||
if (!user) {
|
||||
ctx.throw('user not found');
|
||||
}
|
||||
user.setTokenUser(tokenUser);
|
||||
const orgs = await user.getOrgs();
|
||||
if (!orgs.includes('admin')) {
|
||||
ctx.throw('Permission denied');
|
||||
@ -136,3 +137,38 @@ 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