import { tmpdir } from 'os'; import * as fs from 'fs'; import * as AdmZip from 'adm-zip'; import { parseSM } from './lib/smparse'; import { File, User } from './schema'; export function run(app) { const logger = app.get('logger'); app.post('/api/upload', async (req, res) => { // only for testing, very abusable if (!req.files) return res.status(400).send('No files were given'); if (!req.session.uuid) return res.status(401).send('Not authorized, use /discordauth'); const user = (await User.find({uuid: req.session.uuid}))[0]; if (!user) return res.status(401).send('User doesn\'t exist, try re-logging in'); if (!user.get('approvedUpload')) return res.status(403).send('Your account is not allowed to upload files! Contact a moderator to verify your account'); const file = req.files.file; if (file.mimetype !== 'application/zip' && file.mimetype !== 'application/x-zip-compressed') return res.status(400).send('Invalid filetype'); const dir = tmpdir() + '/' + file.md5; fs.writeFile(dir, file.data, async (err) => { if (err) throw err; try { const zip = new AdmZip(dir); const zipEntries = zip.getEntries(); const smFile: any = Object.values(zipEntries).find((f: any) => !f.isDirectory && (f.entryName.endsWith('.sm')) ); if (!smFile) { res.status(400).send('No .sm found'); } else { const data = smFile.getData().toString('utf8'); const chart = parseSM(data.toString()); logger.info(`${chart.artist} - ${chart.title} was just uploaded`); let id = 0; for (const f of await File.find({})) { id = Math.max(Number(f.id), id); } chart.id = id + 1; chart.uploader = req.session.uuid; chart.createdAt = new Date(); fs.writeFile('./storage/files/' + (id + 1) + '.zip', file.data, (err) => { if (err) throw err; const file = new File(chart); file.save(); // TODO: filter out _id and __v? possibly more res.send(chart); }); } fs.unlink(dir, (err) => { if (err) throw err; }); } catch(err) { logger.error(err.toString()); console.error(err); res.status(400); res.send(err.toString()); } }); }); }