diff --git a/packages/app/package.json b/packages/app/package.json index de04b2b4..40e61a79 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -19,6 +19,7 @@ "axios": "^1.3.5", "cookies": "^0.9.1", "file-saver": "^2.0.5", + "formidable": "^3.5.1", "jsonwebtoken": "^9.0.2", "lottie-web": "^5.12.2", "next": "13.5.6", @@ -33,6 +34,7 @@ "@next/bundle-analyzer": "^13.5.2", "@types/cookies": "^0.9.0", "@types/file-saver": "^2.0.5", + "@types/formidable": "^3.4.5", "@types/jsonwebtoken": "^9.0.2", "@types/node": "^18.15.11", "@types/qs": "^6.9.7", diff --git a/packages/app/src/pages/api/server/file/image.ts b/packages/app/src/pages/api/server/file/image.ts new file mode 100644 index 00000000..1cf8adea --- /dev/null +++ b/packages/app/src/pages/api/server/file/image.ts @@ -0,0 +1,38 @@ +import fs from 'fs' +import formidable from 'formidable' +import serverApi from '@api/serverApi' +import { withHandler } from '@features/server/libs' + +export const config = { + api: { + bodyParser: false, + }, +} + +export default withHandler({ + methods: ['POST'], + checkAccess: true, + handler: async ({ req, res, accessToken }) => { + const form = formidable({}) + const [_, files] = await form.parse(req) + + const file = files.file?.[0] + if (!file || !file.originalFilename) return + + const fileStream = fs.readFileSync(file.filepath) + const formData = new FormData() + formData.append('file', new Blob([fileStream]), file.originalFilename) + + const { data, status } = await serverApi({ + method: 'POST', + url: '/file/image', + data: formData, + headers: { + ...req.headers, + Authorization: `Bearer ${accessToken}`, + }, + }) + + return res.status(status).json(data) + }, +}) diff --git a/packages/app/src/pages/api/server/file/index.ts b/packages/app/src/pages/api/server/file/index.ts new file mode 100644 index 00000000..033528c5 --- /dev/null +++ b/packages/app/src/pages/api/server/file/index.ts @@ -0,0 +1,38 @@ +import fs from 'fs' +import formidable from 'formidable' +import serverApi from '@api/serverApi' +import { withHandler } from '@features/server/libs' + +export const config = { + api: { + bodyParser: false, + }, +} + +export default withHandler({ + methods: ['POST'], + checkAccess: true, + handler: async ({ req, res, accessToken }) => { + const form = formidable({}) + const [_, files] = await form.parse(req) + + const file = files.file?.[0] + if (!file || !file.originalFilename) return + + const fileStream = fs.readFileSync(file.filepath) + const formData = new FormData() + formData.append('file', new Blob([fileStream]), file.originalFilename) + + const { data, status } = await serverApi({ + method: 'POST', + url: '/file', + data: formData, + headers: { + ...req.headers, + Authorization: `Bearer ${accessToken}`, + }, + }) + + return res.status(status).json(data) + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2a7658ce..7893ce77 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -116,6 +116,9 @@ importers: file-saver: specifier: ^2.0.5 version: 2.0.5 + formidable: + specifier: ^3.5.1 + version: 3.5.1 jsonwebtoken: specifier: ^9.0.2 version: 9.0.2 @@ -153,6 +156,9 @@ importers: '@types/file-saver': specifier: ^2.0.5 version: 2.0.7 + '@types/formidable': + specifier: ^3.4.5 + version: 3.4.5 '@types/jsonwebtoken': specifier: ^9.0.2 version: 9.0.6 @@ -2259,6 +2265,9 @@ packages: '@types/find-cache-dir@3.2.1': resolution: {integrity: sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==} + '@types/formidable@3.4.5': + resolution: {integrity: sha512-s7YPsNVfnsng5L8sKnG/Gbb2tiwwJTY1conOkJzTMRvJAlLFW1nEua+ADsJQu8N1c0oTHx9+d5nqg10WuT9gHQ==} + '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -2682,6 +2691,9 @@ packages: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} @@ -3317,6 +3329,9 @@ packages: engines: {node: '>= 4.0.0'} hasBin: true + dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -3769,6 +3784,9 @@ packages: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} + formidable@3.5.1: + resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -3983,6 +4001,10 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + hexoid@1.0.0: + resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} + engines: {node: '>=8'} + hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} @@ -9176,6 +9198,10 @@ snapshots: '@types/find-cache-dir@3.2.1': {} + '@types/formidable@3.4.5': + dependencies: + '@types/node': 18.19.37 + '@types/graceful-fs@4.1.9': dependencies: '@types/node': 18.19.37 @@ -9663,6 +9689,8 @@ snapshots: arrify@1.0.1: {} + asap@2.0.6: {} + asn1.js@4.10.1: dependencies: bn.js: 4.12.0 @@ -10388,6 +10416,11 @@ snapshots: transitivePeerDependencies: - supports-color + dezalgo@1.0.4: + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + diff@4.0.2: {} diffie-hellman@5.0.3: @@ -11061,6 +11094,12 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + formidable@3.5.1: + dependencies: + dezalgo: 1.0.4 + hexoid: 1.0.0 + once: 1.4.0 + forwarded@0.2.0: {} fresh@0.5.2: {} @@ -11284,6 +11323,8 @@ snapshots: he@1.2.0: {} + hexoid@1.0.0: {} + hmac-drbg@1.0.1: dependencies: hash.js: 1.1.7