feat(api): formats for uploaded images
This commit is contained in:
parent
762d2927f7
commit
2b9af0e0de
9 changed files with 53 additions and 13 deletions
|
@ -16,6 +16,9 @@
|
|||
- Fast
|
||||
- Built with Next.js & React
|
||||
- Token protected uploading
|
||||
- Image uploading
|
||||
- URL shortening
|
||||
- Text uploading
|
||||
- Easy setup instructions on [docs](https://zipline.diced.tech/) (One command install `docker-compose up`)
|
||||
|
||||
## Installing
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"build": "npm-run-all build:schema build:next",
|
||||
"build:next": "next build",
|
||||
"build:schema": "prisma generate --schema=prisma/schema.prisma",
|
||||
"migrate:dev": "prisma migrate dev --create-only",
|
||||
"start": "node server",
|
||||
"lint": "next lint",
|
||||
"seed": "ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\" --transpile-only prisma/seed.ts"
|
||||
|
@ -39,6 +40,7 @@
|
|||
"react-redux": "^7.2.4",
|
||||
"redux": "^4.1.0",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"uuid": "^8.3.2",
|
||||
"yup": "^0.32.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
5
prisma/migrations/20220221053815_format/migration.sql
Normal file
5
prisma/migrations/20220221053815_format/migration.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- CreateEnum
|
||||
CREATE TYPE "ImageFormat" AS ENUM ('UUID', 'DATE', 'RANDOM');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Image" ADD COLUMN "format" "ImageFormat" NOT NULL DEFAULT E'RANDOM';
|
2
prisma/migrations/20220221055817_name/migration.sql
Normal file
2
prisma/migrations/20220221055817_name/migration.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- AlterEnum
|
||||
ALTER TYPE "ImageFormat" ADD VALUE 'NAME';
|
|
@ -38,6 +38,13 @@ model Theme {
|
|||
userId Int
|
||||
}
|
||||
|
||||
enum ImageFormat {
|
||||
UUID
|
||||
DATE
|
||||
RANDOM
|
||||
NAME
|
||||
}
|
||||
|
||||
model Image {
|
||||
id Int @id @default(autoincrement())
|
||||
file String
|
||||
|
@ -47,6 +54,7 @@ model Image {
|
|||
favorite Boolean @default(false)
|
||||
embed Boolean @default(false)
|
||||
invisible InvisibleImage?
|
||||
format ImageFormat @default(RANDOM)
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const NextServer = require('next/dist/server/next-server').default;
|
||||
const next = require('next').default;
|
||||
const defaultConfig = require('next/dist/server/config-shared').defaultConfig;
|
||||
const { createServer } = require('http');
|
||||
const { stat, mkdir } = require('fs/promises');
|
||||
|
@ -41,18 +41,17 @@ async function run() {
|
|||
await migrations();
|
||||
|
||||
await mkdir(config.uploader.directory, { recursive: true });
|
||||
const app = new NextServer({
|
||||
|
||||
const app = next({
|
||||
dir: '.',
|
||||
dev,
|
||||
quiet: dev,
|
||||
customServer: false,
|
||||
host: config.core.host,
|
||||
quiet: !dev,
|
||||
hostname: config.core.host,
|
||||
port: config.core.port,
|
||||
conf: Object.assign(defaultConfig, nextConfig),
|
||||
});
|
||||
|
||||
await app.prepare();
|
||||
await stat('./.next');
|
||||
|
||||
const handle = app.getRequestHandler();
|
||||
const prisma = new PrismaClient();
|
||||
|
|
|
@ -126,4 +126,5 @@ module.exports = {
|
|||
getStats,
|
||||
log,
|
||||
sizeOfDir,
|
||||
shouldUseYarn,
|
||||
};
|
|
@ -6,6 +6,9 @@ import { createInvisImage, randomChars } from 'lib/util';
|
|||
import { writeFile } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
import Logger from 'lib/logger';
|
||||
import { ImageFormat, InvisibleImage } from '@prisma/client';
|
||||
import { format as formatDate } from 'fecha';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
const uploader = multer({
|
||||
storage: multer.memoryStorage(),
|
||||
|
@ -22,29 +25,46 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
|||
});
|
||||
|
||||
if (!user) return res.forbid('authorization incorect');
|
||||
|
||||
if (user.ratelimited) return res.ratelimited();
|
||||
|
||||
if (!req.files) return res.error('no files');
|
||||
if (req.files && req.files.length === 0) return res.error('no files');
|
||||
|
||||
const rawFormat = ((req.headers.format || '') as string).toUpperCase() || 'RANDOM';
|
||||
const format: ImageFormat = Object.keys(ImageFormat).includes(rawFormat) && ImageFormat[rawFormat];
|
||||
const files = [];
|
||||
|
||||
for (let i = 0; i !== req.files.length; ++i) {
|
||||
const file = req.files[i];
|
||||
if (file.size > zconfig.uploader[user.administrator ? 'admin_limit' : 'user_limit']) return res.error('file size too big');
|
||||
if (file.size > zconfig.uploader[user.administrator ? 'admin_limit' : 'user_limit']) return res.error(`file[${i}] size too big`);
|
||||
|
||||
const ext = file.originalname.split('.').pop();
|
||||
if (zconfig.uploader.disabled_extentions.includes(ext)) return res.error('disabled extension recieved: ' + ext);
|
||||
const rand = randomChars(zconfig.uploader.length);
|
||||
let fileName: string;
|
||||
|
||||
let invis;
|
||||
switch (format) {
|
||||
case ImageFormat.RANDOM:
|
||||
fileName = randomChars(zconfig.uploader.length);
|
||||
break;
|
||||
case ImageFormat.DATE:
|
||||
fileName = formatDate(new Date(), 'YYYY-MM-DD_HH:mm:ss');
|
||||
break;
|
||||
case ImageFormat.UUID:
|
||||
fileName = v4();
|
||||
break;
|
||||
case ImageFormat.NAME:
|
||||
fileName = file.originalname.split('.')[0];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
let invis: InvisibleImage;
|
||||
const image = await prisma.image.create({
|
||||
data: {
|
||||
file: `${rand}.${ext}`,
|
||||
file: `${fileName}.${ext}`,
|
||||
mimetype: file.mimetype,
|
||||
userId: user.id,
|
||||
embed: !!req.headers.embed,
|
||||
format,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -6346,7 +6346,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
|||
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
uuid@8.3.2, uuid@^8.3.0:
|
||||
uuid@8.3.2, uuid@^8.3.0, uuid@^8.3.2:
|
||||
version "8.3.2"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
|
Loading…
Reference in a new issue