feat: add unlimited upload api in admin

pull/90/head
moonrailgun 2 years ago
parent e6bc8fe425
commit 5ab4829565

@ -11,7 +11,6 @@ MONGO_URL=mongodb://mongo/tailchat
SECRET=
# file
STAIC_HOST="{BACKEND}"
API_URL=https://tailchat-nightly.moonrailgun.com
# minio

@ -1003,6 +1003,7 @@ importers:
server/admin:
specifiers:
'@fastify/busboy': ^1.1.0
'@mui/icons-material': ^5.11.0
'@mui/material': ^5.11.3
'@remix-run/dev': ^1.9.0
@ -1043,6 +1044,7 @@ importers:
ts-node: ^10.9.1
typescript: ^4.8.4
dependencies:
'@fastify/busboy': 1.1.0
'@mui/icons-material': 5.11.0_oiuuhmk4wjjpe4qb2sby7usney
'@mui/material': 5.11.3_ib3m5ricvtkl2cll7qpr2f6lvq
'@remix-run/express': 1.9.0_cwk4saenierp7pa7l5cpbeswge
@ -6593,15 +6595,15 @@ packages:
'@commitlint/execute-rule': 17.4.0
'@commitlint/resolve-extends': 17.4.4
'@commitlint/types': 17.4.4
'@types/node': 15.14.9
'@types/node': 18.14.1
chalk: 4.1.2
cosmiconfig: 8.0.0
cosmiconfig-typescript-loader: 4.3.0_p3jpu2hnimj66lgtzn2mehlr2m
cosmiconfig-typescript-loader: 4.3.0_s4dpre5ezutgdzsn47klmddvia
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
lodash.uniq: 4.5.0
resolve-from: 5.0.0
ts-node: 10.9.1_zlol4fzmmjgb3bdeviopae4asm
ts-node: 10.9.1_uayvamxqnl5yeiojjysxwopmsy
typescript: 4.9.5
transitivePeerDependencies:
- '@swc/core'
@ -14143,7 +14145,7 @@ packages:
dependencies:
'@types/http-cache-semantics': 4.0.1
'@types/keyv': 3.1.4
'@types/node': 18.11.18
'@types/node': 18.14.1
'@types/responselike': 1.0.0
/@types/codemirror/5.60.5:
@ -14863,7 +14865,7 @@ packages:
/@types/react-color/3.0.6:
resolution: {integrity: sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w==}
dependencies:
'@types/react': 18.0.26
'@types/react': 17.0.53
'@types/reactcss': 1.2.6
dev: false
@ -14892,7 +14894,7 @@ packages:
/@types/react-is/17.0.3:
resolution: {integrity: sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==}
dependencies:
'@types/react': 18.0.26
'@types/react': 17.0.53
dev: false
/@types/react-mentions/4.1.8:
@ -14994,7 +14996,7 @@ packages:
/@types/reactcss/1.2.6:
resolution: {integrity: sha512-qaIzpCuXNWomGR1Xq8SCFTtF4v8V27Y6f+b9+bzHiv087MylI/nTCqqdChNeWS7tslgROmYB7yeiruWX7WnqNg==}
dependencies:
'@types/react': 18.0.26
'@types/react': 17.0.53
dev: false
/@types/refractor/3.0.2:
@ -15673,7 +15675,6 @@ packages:
dependencies:
webpack: 5.75.0_webpack-cli@4.10.0
webpack-cli: 4.10.0_hdfrwtmlewz4o7kkfxfrhnzu24
dev: true
/@webpack-cli/info/1.5.0_webpack-cli@4.10.0:
resolution: {integrity: sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==}
@ -15682,7 +15683,6 @@ packages:
dependencies:
envinfo: 7.8.1
webpack-cli: 4.10.0_hdfrwtmlewz4o7kkfxfrhnzu24
dev: true
/@webpack-cli/serve/1.7.0_ud4agclah7rahur6ntojouq57y:
resolution: {integrity: sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==}
@ -15695,7 +15695,6 @@ packages:
dependencies:
webpack-cli: 4.10.0_hdfrwtmlewz4o7kkfxfrhnzu24
webpack-dev-server: 4.11.1_pda42hcaj7d62cr262fr632kue
dev: true
/@xobotyi/scrollbar-width/1.9.5:
resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==}
@ -18681,7 +18680,7 @@ packages:
dependencies:
buffer-from: 1.1.2
inherits: 2.0.4
readable-stream: 2.3.7
readable-stream: 2.3.8
typedarray: 0.0.6
dev: true
@ -19231,7 +19230,7 @@ packages:
normalize-path: 3.0.0
schema-utils: 4.0.0
serialize-javascript: 6.0.1
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/core-js-compat/3.28.0:
resolution: {integrity: sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg==}
@ -19276,7 +19275,7 @@ packages:
vary: 1.1.2
dev: false
/cosmiconfig-typescript-loader/4.3.0_p3jpu2hnimj66lgtzn2mehlr2m:
/cosmiconfig-typescript-loader/4.3.0_s4dpre5ezutgdzsn47klmddvia:
resolution: {integrity: sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==}
engines: {node: '>=12', npm: '>=6'}
peerDependencies:
@ -19285,9 +19284,9 @@ packages:
ts-node: '>=10'
typescript: '>=3'
dependencies:
'@types/node': 15.14.9
'@types/node': 18.14.1
cosmiconfig: 8.0.0
ts-node: 10.9.1_zlol4fzmmjgb3bdeviopae4asm
ts-node: 10.9.1_uayvamxqnl5yeiojjysxwopmsy
typescript: 4.9.5
dev: true
@ -21075,7 +21074,6 @@ packages:
resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==}
engines: {node: '>=4'}
hasBin: true
dev: true
/eol/0.9.1:
resolution: {integrity: sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==}
@ -22244,7 +22242,6 @@ packages:
/fastest-levenshtein/1.0.16:
resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
engines: {node: '>= 4.9.1'}
dev: true
/fastest-stable-stringify/2.0.2:
resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==}
@ -22398,7 +22395,7 @@ packages:
dependencies:
loader-utils: 2.0.4
schema-utils: 3.1.1
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/file-selector/0.5.0:
resolution: {integrity: sha512-s8KNnmIDTBoD0p9uJ9uD0XY38SCeBOtj0UMXyQSLg1Ypfrfj8+dAvwsLjYQkQ2GjhVtp2HrnF5cJzMhBjfD8HA==}
@ -24106,7 +24103,7 @@ packages:
lodash: 4.17.21
pretty-error: 4.0.0
tapable: 2.2.1
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/htmlparser2/6.1.0:
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
@ -24473,7 +24470,6 @@ packages:
dependencies:
pkg-dir: 4.2.0
resolve-cwd: 3.0.0
dev: true
/imurmurhash/0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
@ -28128,7 +28124,7 @@ packages:
webpack: ^5.0.0
dependencies:
schema-utils: 4.0.0
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/mini-star/1.3.1:
resolution: {integrity: sha512-u9Rw8mPZibaAkEVXBsOQJ1irAURTgjqdKoITFd24+KxIGVXCDK+RYR8KjKRF99VLaCbK6TwTqiJ6iNsqq0G+wA==}
@ -34093,7 +34089,6 @@ packages:
engines: {node: '>= 0.10'}
dependencies:
resolve: 1.22.1
dev: true
/rechoir/0.8.0:
resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
@ -34660,7 +34655,6 @@ packages:
engines: {node: '>=8'}
dependencies:
resolve-from: 5.0.0
dev: true
/resolve-dir/1.0.1:
resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==}
@ -34681,7 +34675,6 @@ packages:
/resolve-from/5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
dev: true
/resolve-global/1.0.0:
resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==}
@ -37044,7 +37037,7 @@ packages:
end-of-stream: 1.4.4
fs-constants: 1.0.0
inherits: 2.0.4
readable-stream: 3.6.0
readable-stream: 3.6.1
/tar/6.1.13:
resolution: {integrity: sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==}
@ -37189,7 +37182,7 @@ packages:
schema-utils: 3.1.1
serialize-javascript: 6.0.1
terser: 5.16.5
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/terser/4.8.1:
resolution: {integrity: sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==}
@ -37965,6 +37958,37 @@ packages:
yn: 3.1.1
dev: true
/ts-node/10.9.1_uayvamxqnl5yeiojjysxwopmsy:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
'@types/node': 18.14.1
acorn: 8.8.1
acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 4.9.5
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
/ts-node/10.9.1_zlol4fzmmjgb3bdeviopae4asm:
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
@ -38904,7 +38928,7 @@ packages:
loader-utils: 2.0.4
mime-types: 2.1.35
schema-utils: 3.1.1
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/url-parse-lax/3.0.0:
resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==}
@ -39539,7 +39563,6 @@ packages:
webpack-bundle-analyzer: 4.8.0
webpack-dev-server: 4.11.1_pda42hcaj7d62cr262fr632kue
webpack-merge: 5.8.0
dev: true
/webpack-dev-middleware/3.7.3_webpack@4.46.0:
resolution: {integrity: sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==}
@ -39566,7 +39589,7 @@ packages:
mime-types: 2.1.35
range-parser: 1.2.1
schema-utils: 4.0.0
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/webpack-dev-server/4.11.1_pda42hcaj7d62cr262fr632kue:
resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==}
@ -39615,7 +39638,6 @@ packages:
- debug
- supports-color
- utf-8-validate
dev: true
/webpack-dev-server/4.11.1_webpack@5.75.0:
resolution: {integrity: sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==}
@ -39896,7 +39918,6 @@ packages:
- '@swc/core'
- esbuild
- uglify-js
dev: true
/webpackbar/5.0.2_webpack@5.75.0:
resolution: {integrity: sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==}
@ -39908,7 +39929,7 @@ packages:
consola: 2.15.3
pretty-time: 1.1.0
std-env: 3.3.2
webpack: 5.75.0
webpack: 5.75.0_webpack-cli@4.10.0
/websocket-driver/0.7.4:
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}

@ -10,7 +10,6 @@ REDIS_URL=redis://localhost:6379/
TRANSPORTER=
# 填写服务端可访问的接口地址
STAIC_HOST="{BACKEND}"
API_URL=
# 文件存储

@ -13,9 +13,15 @@ broker.start().then(() => {
console.log('Linked to Tailchat network, TRANSPORTER: ', transporter);
});
export function call<T>(actionName: string, params: any): Promise<T> {
export function callBrokerAction<T>(
actionName: string,
params: any,
opts?: Record<string, any>
): Promise<T> {
return broker.call(actionName, params, {
...opts,
meta: {
...opts?.meta,
userId: SYSTEM_USERID,
},
});

@ -1,10 +1,11 @@
import { Router } from 'express';
import raExpressMongoose from 'express-mongoose-ra-json-server';
import jwt from 'jsonwebtoken';
import { call } from '../broker';
import { callBrokerAction } from '../broker';
import { adminAuth, auth, authSecret } from '../middleware/auth';
import { configRouter } from './config';
import { networkRouter } from './network';
import { fileRouter } from './upload';
const router = Router();
@ -41,6 +42,7 @@ router.post('/login', (req, res) => {
router.use('/network', networkRouter);
router.use('/config', configRouter);
router.use('/file', fileRouter);
router.use(
'/users',
@ -52,7 +54,7 @@ router.use(
router.delete('/messages/:id', auth(), async (req, res) => {
try {
const messageId = req.params.id;
await call('chat.message.deleteMessage', {
await callBrokerAction('chat.message.deleteMessage', {
messageId,
});

@ -0,0 +1,60 @@
/**
* Network
*/
import { Router } from 'express';
import { callBrokerAction } from '../broker';
import { auth } from '../middleware/auth';
import Busboy from '@fastify/busboy';
const router = Router();
router.put('/upload', auth(), async (req, res) => {
const busboy = new Busboy({ headers: req.headers as any });
const promises = [];
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
promises.push(
callBrokerAction('file.save', file, {
filename: filename,
})
.then((data) => {
console.log(data);
return data;
})
.catch((err) => {
file.resume(); // Drain file stream to continue processing form
busboy.emit('error', err);
return err;
})
);
});
busboy.on('finish', async () => {
/* istanbul ignore next */
if (promises.length == 0) {
res.status(500).json('File missing in the request');
return;
}
try {
const files = await Promise.all(promises);
res.json({ files });
} catch (err) {
console.error(err);
res.status(500).json(String(err));
}
});
busboy.on('error', (err) => {
console.error(err);
req.unpipe(busboy);
req.resume();
res.status(500).json({ err });
});
req.pipe(busboy);
});
export { router as fileRouter };

@ -11,6 +11,7 @@
"typecheck": "tsc -b"
},
"dependencies": {
"@fastify/busboy": "^1.1.0",
"@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.3",
"@remix-run/express": "^1.9.0",

@ -8,7 +8,7 @@ dotenv.config();
*/
const port = process.env.PORT ? Number(process.env.PORT) : 11000;
const apiUrl = process.env.API_URL || `http://127.0.0.1:${port}`;
const staticHost = process.env.STAIC_HOST || apiUrl;
const staticHost = process.env.STAIC_HOST || '{BACKEND}';
export const config = {
port,
secret: process.env.SECRET || 'tailchat',

Loading…
Cancel
Save