refactor: renamed from 'draconic' to 'void'
|
@ -36,7 +36,7 @@ package.lock.json
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
|
|
||||||
# draconic
|
# void
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
config.toml
|
config.toml
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "draconic",
|
"name": "void",
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ALTER COLUMN "embedSiteName" SET DEFAULT E'Void';
|
|
@ -14,7 +14,7 @@ model User {
|
||||||
token String @unique
|
token String @unique
|
||||||
isAdmin Boolean @default(false)
|
isAdmin Boolean @default(false)
|
||||||
useEmbed Boolean? @default(false)
|
useEmbed Boolean? @default(false)
|
||||||
embedSiteName String? @default("Draconic")
|
embedSiteName String? @default("Void")
|
||||||
embedTitle String?
|
embedTitle String?
|
||||||
embedColor String @default("#B794F4")
|
embedColor String @default("#B794F4")
|
||||||
embedDesc String?
|
embedDesc String?
|
||||||
|
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 123 KiB |
BIN
public/logo.png
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 37 KiB |
20
readme.md
|
@ -1,12 +1,12 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="https://raw.githubusercontent.com/AlphaNecron/Draconic/v0/public/banner.png"/>
|
<img src="https://raw.githubusercontent.com/AlphaNecron/Void/v0/public/banner.png"/>
|
||||||
A self-hosted file hosting service based on Zipline with many features.
|
A self-hosted file hosting service based on Zipline with many features.
|
||||||
|
|
||||||
![Build stable](https://img.shields.io/github/workflow/status/AlphaNecron/Draconic/CI:%20Build/v0?color=%2368D391&label=stable&logo=github&style=for-the-badge)
|
![Build stable](https://img.shields.io/github/workflow/status/AlphaNecron/Void/CI:%20Build/v0?color=%2368D391&label=stable&logo=github&style=for-the-badge)
|
||||||
![Build stable](https://img.shields.io/github/workflow/status/AlphaNecron/Draconic/CI:%20Build/dev?color=%2368D391&label=dev&logo=github&style=for-the-badge)
|
![Build stable](https://img.shields.io/github/workflow/status/AlphaNecron/Void/CI:%20Build/dev?color=%2368D391&label=dev&logo=github&style=for-the-badge)
|
||||||
![Stars](https://img.shields.io/github/stars/AlphaNecron/Draconic?color=%23B794F4&logo=github&style=for-the-badge)
|
![Stars](https://img.shields.io/github/stars/AlphaNecron/Void?color=%23B794F4&logo=github&style=for-the-badge)
|
||||||
![Version](https://img.shields.io/github/package-json/v/AlphaNecron/Draconic/v0?color=%23B794F4&label=latest&logo=react&logoColor=ffffff&style=for-the-badge)
|
![Version](https://img.shields.io/github/package-json/v/AlphaNecron/Void/v0?color=%23B794F4&label=latest&logo=react&logoColor=ffffff&style=for-the-badge)
|
||||||
![Last commit](https://img.shields.io/github/last-commit/AlphaNecron/Draconic/dev?color=%234FD1C5&logo=github&style=for-the-badge)
|
![Last commit](https://img.shields.io/github/last-commit/AlphaNecron/Void/dev?color=%234FD1C5&logo=github&style=for-the-badge)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
@ -16,8 +16,8 @@ A self-hosted file hosting service based on Zipline with many features.
|
||||||
|
|
||||||
### Installation / Deployment
|
### Installation / Deployment
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/AlphaNecron/Draconic.git
|
git clone https://github.com/AlphaNecron/Void.git
|
||||||
cd Draconic
|
cd Void
|
||||||
yarn install # or npm install
|
yarn install # or npm install
|
||||||
cp config.example.toml config.toml
|
cp config.example.toml config.toml
|
||||||
nano config.toml # edit the config file
|
nano config.toml # edit the config file
|
||||||
|
@ -50,8 +50,8 @@ A self-hosted file hosting service based on Zipline with many features.
|
||||||
[core]
|
[core]
|
||||||
secure = false # Whether to use https or not
|
secure = false # Whether to use https or not
|
||||||
secret = 'supersecretpassphrase' # The secret used to sign cookie
|
secret = 'supersecretpassphrase' # The secret used to sign cookie
|
||||||
host = '0.0.0.0' # The host Draconic should run on
|
host = '0.0.0.0' # The host Void should run on
|
||||||
port = 3000 # The port Draconic should run on
|
port = 3000 # The port Void should run on
|
||||||
database_url = 'postgres://username:password@localhost:5432/db_name' # PostgreSQL database url
|
database_url = 'postgres://username:password@localhost:5432/db_name' # PostgreSQL database url
|
||||||
|
|
||||||
[bot]
|
[bot]
|
||||||
|
|
|
@ -11,7 +11,7 @@ const mimes = require('../src/lib/mimetype');
|
||||||
const deployDb = require('../scripts/deployDb');
|
const deployDb = require('../scripts/deployDb');
|
||||||
const { join } = require('path');
|
const { join } = require('path');
|
||||||
|
|
||||||
info('SERVER', 'Starting Draconic server');
|
info('SERVER', 'Starting Void server');
|
||||||
|
|
||||||
const dev = process.env.NODE_ENV === 'development';
|
const dev = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Download, X } from 'react-feather';
|
||||||
|
|
||||||
export default function ShareXDialog({ open, onClose, token }) {
|
export default function ShareXDialog({ open, onClose, token }) {
|
||||||
const ref = React.useRef();
|
const ref = React.useRef();
|
||||||
const [name, setName] = useState('Draconic');
|
const [name, setName] = useState('Void');
|
||||||
const [generator, setGenerator] = useState('random');
|
const [generator, setGenerator] = useState('random');
|
||||||
const [preserveFileName, setPreserveFileName] = useState(false);
|
const [preserveFileName, setPreserveFileName] = useState(false);
|
||||||
const generateConfig = shortener => {
|
const generateConfig = shortener => {
|
||||||
|
@ -64,7 +64,7 @@ export default function ShareXDialog({ open, onClose, token }) {
|
||||||
<Input
|
<Input
|
||||||
value={name}
|
value={name}
|
||||||
onChange={n => setName(n.target.value)}
|
onChange={n => setName(n.target.value)}
|
||||||
placeholder='Draconic'
|
placeholder='Void'
|
||||||
size='sm'
|
size='sm'
|
||||||
/>
|
/>
|
||||||
<Heading mt={2} mb={1} size='sm'>URL generator</Heading>
|
<Heading mt={2} mb={1} size='sm'>URL generator</Heading>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Box, Button, Checkbox, Flex, Heading, HStack, Select, Text, useColorModeValue, useToast, VStack } from '@chakra-ui/react';
|
import { Button, Center, Checkbox, Heading, HStack, Select, Text, useColorModeValue, useToast, VStack } from '@chakra-ui/react';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from 'copy-to-clipboard';
|
||||||
import { useStoreSelector } from 'lib/redux/store';
|
import { useStoreSelector } from 'lib/redux/store';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
@ -55,48 +55,42 @@ export default function Upload() {
|
||||||
const bg = useColorModeValue('gray.100', 'gray.700');
|
const bg = useColorModeValue('gray.100', 'gray.700');
|
||||||
const shadow = useColorModeValue('outline', 'dark-lg');
|
const shadow = useColorModeValue('outline', 'dark-lg');
|
||||||
return (
|
return (
|
||||||
<Flex minHeight='92vh' width='full' align='center' justifyContent='center'>
|
<Center h='92vh'>
|
||||||
<Box
|
<VStack
|
||||||
px={2}
|
px={2}
|
||||||
boxShadow='xl'
|
boxShadow='xl'
|
||||||
bg={bg}
|
bg={bg}
|
||||||
fg={fg}
|
fg={fg}
|
||||||
justify='center'
|
|
||||||
align='center'
|
|
||||||
p={2}
|
p={2}
|
||||||
borderRadius={4}
|
borderRadius={4}
|
||||||
textAlign='left'
|
shadow={shadow}>
|
||||||
shadow={shadow}
|
<Heading fontSize='lg' m={1} align='left'>Upload a file</Heading>
|
||||||
>
|
<Button m={2} variant='ghost' width='385' height='200'>
|
||||||
<VStack>
|
<Dropzone disabled={busy} onDrop={acceptedFiles => setFile(acceptedFiles[0])}>
|
||||||
<Heading fontSize='lg' m={1} align='left'>Upload a file</Heading>
|
{({ getRootProps, getInputProps, isDragActive }) => (
|
||||||
<Button m={2} variant='ghost' width='385' height='200'>
|
<VStack {...getRootProps()}>
|
||||||
<Dropzone disabled={busy} onDrop={acceptedFiles => setFile(acceptedFiles[0])}>
|
<input {...getInputProps()}/>
|
||||||
{({ getRootProps, getInputProps, isDragActive }) => (
|
<UploadIcon size={56}/>
|
||||||
<VStack {...getRootProps()}>
|
{isDragActive ? (
|
||||||
<input {...getInputProps()}/>
|
<Text fontSize='xl'>Drop the file here</Text>
|
||||||
<UploadIcon size={56}/>
|
) : (
|
||||||
{isDragActive ? (
|
<Text fontSize='xl'>Drag a file here or click to upload one</Text>
|
||||||
<Text fontSize='xl'>Drop the file here</Text>
|
)}
|
||||||
) : (
|
<Text fontSize='lg' colorScheme='yellow' isTruncated maxWidth='350'>{file && file.name}</Text>
|
||||||
<Text fontSize='xl'>Drag a file here or click to upload one</Text>
|
</VStack>
|
||||||
)}
|
)}
|
||||||
<Text fontSize='lg' colorScheme='yellow' isTruncated maxWidth='350'>{file && file.name}</Text>
|
</Dropzone>
|
||||||
</VStack>
|
</Button>
|
||||||
)}
|
<HStack justify='stretch' width='385'>
|
||||||
</Dropzone>
|
<Checkbox width='160' isChecked={preserve} colorScheme='purple' onChange={p => setPreserve(p.target.checked)}>Preserve filename</Checkbox>
|
||||||
</Button>
|
<Select size='sm' variant='filled' width='110' value={generator} onChange={selection => setGenerator(selection.target.value)}>
|
||||||
<HStack justify='stretch' width='385'>
|
<option value='random'>Random</option>
|
||||||
<Checkbox width='160' isChecked={preserve} colorScheme='purple' onChange={p => setPreserve(p.target.checked)}>Preserve filename</Checkbox>
|
<option value='zws'>Invisible</option>
|
||||||
<Select size='sm' variant='filled' width='110' value={generator} onChange={selection => setGenerator(selection.target.value)}>
|
<option value='emoji'>Emoji</option>
|
||||||
<option value='random'>Random</option>
|
</Select>
|
||||||
<option value='zws'>Invisible</option>
|
<Button size='sm' width='100' isDisabled={busy || !file} isLoading={busy} loadingText='Uploading' onClick={handleFileUpload} colorScheme='purple' leftIcon={<UploadIcon size={16}/>}>Upload</Button>
|
||||||
<option value='emoji'>Emoji</option>
|
</HStack>
|
||||||
</Select>
|
</VStack>
|
||||||
<Button size='sm' width='100' isDisabled={busy || !file} isLoading={busy} loadingText='Uploading' onClick={handleFileUpload} colorScheme='purple' leftIcon={<UploadIcon size={16}/>}>Upload</Button>
|
</Center>
|
||||||
</HStack>
|
|
||||||
</VStack>
|
|
||||||
</Box>
|
|
||||||
</Flex>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -40,7 +40,7 @@ export type NextApiRes = NextApiResponse & {
|
||||||
setCookie: (name: string, value: unknown, options: CookieSerializeOptions) => void;
|
setCookie: (name: string, value: unknown, options: CookieSerializeOptions) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const withDraconic = (handler: (req: NextApiRequest, res: NextApiResponse) => unknown) => (req: NextApiReq, res: NextApiRes) => {
|
export const withVoid = (handler: (req: NextApiRequest, res: NextApiResponse) => unknown) => (req: NextApiReq, res: NextApiRes) => {
|
||||||
res.error = (message: string) => {
|
res.error = (message: string) => {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.status(400);
|
res.status(400);
|
|
@ -17,24 +17,15 @@ export default function Embed({ file, embed, username, content = undefined, misc
|
||||||
a.href = misc.src;
|
a.href = misc.src;
|
||||||
a.click();
|
a.click();
|
||||||
};
|
};
|
||||||
const replace = text => {
|
|
||||||
const time = new Date(file.uploadedAt);
|
|
||||||
return (text ?? '').replace(/{size}/ig, misc.size)
|
|
||||||
.replace(/{filename}/ig, file.fileName)
|
|
||||||
.replace(/{orig}/ig, file.origFileName)
|
|
||||||
.replace(/{date}/ig, time.toLocaleDateString())
|
|
||||||
.replace(/{time}/ig, time.toLocaleTimeString())
|
|
||||||
.replace(/{author}/ig, username);
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<>
|
<>
|
||||||
{embed.enabled && (
|
{embed.enabled && (
|
||||||
<>
|
<>
|
||||||
<meta property='og:site_name' content={replace(embed.siteName)}/>
|
<meta property='og:site_name' content={embed.siteName}/>
|
||||||
<meta property='og:title' content={replace(embed.title)}/>
|
<meta property='og:title' content={embed.title}/>
|
||||||
<meta property='og:description' content={replace(embed.desc)}/>
|
<meta property='og:description' content={embed.desc}/>
|
||||||
<meta property='theme-color' content={embed.color}/>
|
<meta property='theme-color' content={embed.color}/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -58,11 +49,10 @@ export default function Embed({ file, embed, username, content = undefined, misc
|
||||||
<title>Uploaded by {username}</title>
|
<title>Uploaded by {username}</title>
|
||||||
</>
|
</>
|
||||||
</Head>
|
</Head>
|
||||||
<Center>
|
<Center h='100vh'>
|
||||||
<Box
|
<Box
|
||||||
m={4}
|
m={4}
|
||||||
boxShadow='xl'
|
boxShadow='xl'
|
||||||
flexDirection='column'
|
|
||||||
bg={useColorModeValue('gray.100', 'gray.700')}
|
bg={useColorModeValue('gray.100', 'gray.700')}
|
||||||
fg={useColorModeValue('gray.800', 'white')}
|
fg={useColorModeValue('gray.800', 'white')}
|
||||||
p={1}
|
p={1}
|
||||||
|
@ -150,54 +140,63 @@ export const getServerSideProps: GetServerSideProps = async context => {
|
||||||
embedDesc: true
|
embedDesc: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const embed = {
|
||||||
|
enabled,
|
||||||
|
siteName,
|
||||||
|
title,
|
||||||
|
color,
|
||||||
|
desc
|
||||||
|
};
|
||||||
const ext = file.fileName.split('.').pop();
|
const ext = file.fileName.split('.').pop();
|
||||||
const type = file.mimetype.split('/').shift();
|
const type = file.mimetype.split('/').shift();
|
||||||
const src = `${config.uploader.raw_route}/${file.fileName}`;
|
const src = `${config.uploader.raw_route}/${file.fileName}`;
|
||||||
const url = `http${config.core.secure ? 's' : ''}://${context.req.headers.host}/${config.uploader.raw_route}`;
|
const url = `http${config.core.secure ? 's' : ''}://${context.req.headers.host}/${config.uploader.raw_route}`;
|
||||||
const isCode = Object.keys(languages).some(name => languages[name] === ext);
|
const isCode = Object.keys(languages).some(name => languages[name] === ext);
|
||||||
|
const replace = size => {
|
||||||
|
const time = new Date(file.uploadedAt);
|
||||||
|
const replace = text => {
|
||||||
|
return (text ?? '').replace(/{size}/ig, size)
|
||||||
|
.replace(/{filename}/ig, file.fileName)
|
||||||
|
.replace(/{orig}/ig, file.origFileName)
|
||||||
|
.replace(/{date}/ig, time.toLocaleDateString())
|
||||||
|
.replace(/{time}/ig, time.toLocaleTimeString())
|
||||||
|
.replace(/{author}/ig, username);
|
||||||
|
};
|
||||||
|
['siteName', 'title', 'desc'].forEach(prop => embed[prop] = replace(embed[prop]));
|
||||||
|
};
|
||||||
if (file.mimetype.startsWith('text') || isCode) {
|
if (file.mimetype.startsWith('text') || isCode) {
|
||||||
const res = await fetch(`${url}/${file.fileName}`);
|
const res = await fetch(`${url}/${file.fileName}`);
|
||||||
if (!res.ok) return { notFound: true };
|
if (!res.ok) return { notFound: true };
|
||||||
const content = await res.text();
|
const content = await res.text();
|
||||||
const size = bytesToHr(res.headers.get('content-length'));
|
const size = bytesToHr(res.headers.get('content-length'));
|
||||||
|
replace(size);
|
||||||
|
delete file.uploadedAt;
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
file,
|
file,
|
||||||
embed: {
|
embed,
|
||||||
enabled,
|
|
||||||
siteName,
|
|
||||||
title,
|
|
||||||
color,
|
|
||||||
desc
|
|
||||||
},
|
|
||||||
username,
|
username,
|
||||||
misc: {
|
misc: {
|
||||||
ext,
|
ext,
|
||||||
type,
|
type,
|
||||||
language: isCode ? ext : 'text',
|
language: isCode ? ext : 'text'
|
||||||
size
|
|
||||||
},
|
},
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
const size = bytesToHr((await fetch(`${url}/${file.fileName}`)).headers.get('content-length'));
|
const size = bytesToHr((await fetch(`${url}/${file.fileName}`)).headers.get('content-length'));
|
||||||
|
replace(size);
|
||||||
|
delete file.uploadedAt;
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
file,
|
file,
|
||||||
embed: {
|
embed,
|
||||||
enabled,
|
|
||||||
siteName,
|
|
||||||
title,
|
|
||||||
color,
|
|
||||||
desc
|
|
||||||
},
|
|
||||||
username,
|
username,
|
||||||
misc: {
|
misc: {
|
||||||
ext,
|
ext,
|
||||||
type,
|
type,
|
||||||
src,
|
src
|
||||||
size
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
export default function Draconic({ Component, pageProps }) {
|
export default function Void({ Component, pageProps }) {
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { Button, Center, Heading, VStack } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { ArrowLeftCircle } from 'react-feather';
|
||||||
|
|
||||||
|
export default function Error({ code }) {
|
||||||
|
const errors = {
|
||||||
|
'400': 'Bad Request',
|
||||||
|
'401': 'Unauthorized',
|
||||||
|
'402': 'Payment Required',
|
||||||
|
'403': 'Forbidden',
|
||||||
|
'404': 'Not Found',
|
||||||
|
'405': 'Method Not Allowed',
|
||||||
|
'406': 'Not Acceptable',
|
||||||
|
'407': 'Proxy Authentication Required',
|
||||||
|
'408': 'Request Timeout',
|
||||||
|
'409': 'Conflict',
|
||||||
|
'410': 'Gone',
|
||||||
|
'411': 'Length Required',
|
||||||
|
'412': 'Precondition Required',
|
||||||
|
'413': 'Request Entry Too Large',
|
||||||
|
'414': 'Request-URI Too Long',
|
||||||
|
'415': 'Unsupported Media Type',
|
||||||
|
'416': 'Requested Range Not Satisfiable',
|
||||||
|
'417': 'Expectation Failed',
|
||||||
|
'418': 'I\'m a teapot',
|
||||||
|
'429': 'Too Many Requests',
|
||||||
|
'500': 'Internal Server Error',
|
||||||
|
'501': 'Not Implemented',
|
||||||
|
'502': 'Bad Gateway',
|
||||||
|
'503': 'Service Unavailable',
|
||||||
|
'504': 'Gateway Timeout',
|
||||||
|
'505': 'HTTP Version Not Supported'
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Center h='100vh'>
|
||||||
|
<VStack>
|
||||||
|
<Heading>{code}: {errors[String(code)]}</Heading>
|
||||||
|
<Link href='/dash' passHref>
|
||||||
|
<Button justifyContent='flex-start' colorScheme='purple' leftIcon={<ArrowLeftCircle/>}>Go back</Button>
|
||||||
|
</Link>
|
||||||
|
</VStack>
|
||||||
|
</Center>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error.getInitialProps = ({ res, err }) => {
|
||||||
|
const code = res ? res.statusCode : err ? err.statusCode : 404;
|
||||||
|
return { code };
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { checkPassword, createToken, hashPassword } from 'lib/utils';
|
import { checkPassword, createToken, hashPassword } from 'lib/utils';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
if (req.method !== 'POST') return res.status(405).end();
|
if (req.method !== 'POST') return res.status(405).end();
|
||||||
|
@ -11,12 +11,12 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
const user = await prisma.user.create({
|
const user = await prisma.user.create({
|
||||||
data: {
|
data: {
|
||||||
username: 'admin',
|
username: 'admin',
|
||||||
password: await hashPassword('draconicuser'),
|
password: await hashPassword('voiduser'),
|
||||||
token: createToken(),
|
token: createToken(),
|
||||||
isAdmin: true
|
isAdmin: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
info('SEED', `Created default user with username "${user.username}" and password "draconicuser"`);
|
info('SEED', `Created default user with username "${user.username}" and password "voiduser"`);
|
||||||
}
|
}
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
where: {
|
where: {
|
||||||
|
@ -31,4 +31,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
return res.json({ success: true });
|
return res.json({ success: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -1,5 +1,5 @@
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
const user = await req.user();
|
const user = await req.user();
|
||||||
|
@ -9,4 +9,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
return res.json({ success: true });
|
return res.json({ success: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -2,7 +2,7 @@ import { rm } from 'fs/promises';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import cfg from '../../lib/config';
|
import cfg from '../../lib/config';
|
||||||
import { info } from '../../lib/logger';
|
import { info } from '../../lib/logger';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from '../../lib/middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from '../../lib/middleware/withVoid';
|
||||||
import prisma from '../../lib/prisma';
|
import prisma from '../../lib/prisma';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
|
@ -47,4 +47,4 @@ export const config = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -1,7 +1,7 @@
|
||||||
import { default as cfg, default as config } from 'lib/config';
|
import { default as cfg, default as config } from 'lib/config';
|
||||||
import generate from 'lib/generators';
|
import generate from 'lib/generators';
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'lib/middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'lib/middleware/withVoid';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
|
@ -38,4 +38,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -1,7 +1,7 @@
|
||||||
import config from 'lib/config';
|
import config from 'lib/config';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { bytesToHr, sizeOfDir } from 'lib/utils';
|
import { bytesToHr, sizeOfDir } from 'lib/utils';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
|
@ -69,4 +69,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -2,7 +2,7 @@ import { writeFile } from 'fs/promises';
|
||||||
import cfg from 'lib/config';
|
import cfg from 'lib/config';
|
||||||
import generate, { emoji, zws } from 'lib/generators';
|
import generate, { emoji, zws } from 'lib/generators';
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'lib/middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'lib/middleware/withVoid';
|
||||||
import mimetypes from 'lib/mimetype';
|
import mimetypes from 'lib/mimetype';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import multer from 'multer';
|
import multer from 'multer';
|
||||||
|
@ -82,7 +82,7 @@ function run(middleware: any) {
|
||||||
|
|
||||||
export default async function handlers(req, res) {
|
export default async function handlers(req, res) {
|
||||||
await run(uploader.single('file'))(req, res);
|
await run(uploader.single('file'))(req, res);
|
||||||
return withDraconic(handler)(req, res);
|
return withVoid(handler)(req, res);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import config from 'lib/config';
|
import config from 'lib/config';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
const user = await req.user();
|
const user = await req.user();
|
||||||
|
@ -35,4 +35,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -1,7 +1,7 @@
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { hashPassword } from 'lib/utils';
|
import { hashPassword } from 'lib/utils';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
const user = await req.user();
|
const user = await req.user();
|
||||||
|
@ -74,4 +74,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -1,7 +1,7 @@
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { createToken } from 'lib/utils';
|
import { createToken } from 'lib/utils';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
const user = await req.user();
|
const user = await req.user();
|
||||||
|
@ -23,4 +23,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -1,7 +1,7 @@
|
||||||
import config from 'lib/config';
|
import config from 'lib/config';
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
const user = await req.user();
|
const user = await req.user();
|
||||||
|
@ -37,4 +37,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -1,7 +1,7 @@
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { createToken, hashPassword } from 'lib/utils';
|
import { createToken, hashPassword } from 'lib/utils';
|
||||||
import { NextApiReq, NextApiRes, withDraconic } from 'middleware/withDraconic';
|
import { NextApiReq, NextApiRes, withVoid } from 'middleware/withVoid';
|
||||||
|
|
||||||
async function handler(req: NextApiReq, res: NextApiRes) {
|
async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
const user = await req.user();
|
const user = await req.user();
|
||||||
|
@ -62,4 +62,4 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withDraconic(handler);
|
export default withVoid(handler);
|
|
@ -67,7 +67,7 @@ export default function Login() {
|
||||||
{props => (
|
{props => (
|
||||||
<Form>
|
<Form>
|
||||||
<VStack>
|
<VStack>
|
||||||
<Heading fontSize='xl' mb={2} align='center'>Draconic</Heading>
|
<Heading fontSize='xl' mb={2} align='center'>Void</Heading>
|
||||||
<Field name='username'>
|
<Field name='username'>
|
||||||
{({ field, form }) => (
|
{({ field, form }) => (
|
||||||
<FormControl isInvalid={form.errors.username && form.touched.username} isRequired mb={4}>
|
<FormControl isInvalid={form.errors.username && form.touched.username} isRequired mb={4}>
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default function Index() {
|
||||||
}, [router]);
|
}, [router]);
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<meta property='og:title' content='Draconic'/>
|
<meta property='og:title' content='Void'/>
|
||||||
<meta property='og:description' content='Free and open source file hosting service.'/>
|
<meta property='og:description' content='Free and open source file hosting service.'/>
|
||||||
</Head>
|
</Head>
|
||||||
);
|
);
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
"draconic-env.d.ts",
|
"void-env.d.ts",
|
||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
"**/*.tsx",
|
"**/*.tsx",
|
||||||
"twilight/**/*.ts"
|
"twilight/**/*.ts"
|
||||||
|
|