mirror of
https://github.com/diced/zipline.git
synced 2025-12-19 18:45:08 -08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a900daa244 | ||
|
|
42dcd03428 | ||
|
|
353122c169 | ||
|
|
cea5092fd6 | ||
|
|
3d4625f531 | ||
|
|
f5ab288bb3 | ||
|
|
41565b3a62 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zipline-next",
|
||||
"version": "2.3.1",
|
||||
"version": "2.4.2",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@dicedtomato/colors": "^1.0.3",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
module.exports = async (markdown, metaData) => {
|
||||
console.log(metaData);
|
||||
module.exports = async (markdown) => {
|
||||
return markdown;
|
||||
};
|
||||
18
setup.js
18
setup.js
@@ -48,35 +48,33 @@ const base = {
|
||||
{ name: 'mysql' },
|
||||
{ name: 'mariadb' },
|
||||
{ name: 'mssql' },
|
||||
{ name: 'sqlite' },
|
||||
{ name: 'sqlite3' },
|
||||
{ name: 'mongodb', extra: 'No support yet' }
|
||||
{ name: 'sqlite3' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'host',
|
||||
message: 'Database Host'
|
||||
message: 'Database Host (leave blank if sqlite3)'
|
||||
},
|
||||
{
|
||||
type: 'number',
|
||||
name: 'port',
|
||||
message: 'Database Port'
|
||||
message: 'Database Port (leave blank if sqlite3)'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'database',
|
||||
message: 'Database Name'
|
||||
message: 'Database Name (db path if sqlite3)'
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'username',
|
||||
message: 'Database User'
|
||||
message: 'Database User (leave blank if sqlite3)'
|
||||
},
|
||||
{
|
||||
type: 'password',
|
||||
name: 'password',
|
||||
message: 'Database Password'
|
||||
message: 'Database Password (leave blank if sqlite3)'
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -106,7 +104,7 @@ const base = {
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'original',
|
||||
message: 'Keep Original?'
|
||||
message: 'Keep Original File names?'
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -138,7 +136,7 @@ const base = {
|
||||
urls: { ...base.urls, ...urls }
|
||||
};
|
||||
|
||||
writeFileSync('Zipline.toml', stringify(config));
|
||||
writeFileSync('Ziplined.toml', stringify(config));
|
||||
|
||||
if (docker.useDocker) {
|
||||
console.log('Generating docker-compose.yml...');
|
||||
|
||||
@@ -66,29 +66,39 @@ export default function Login() {
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
<Card>
|
||||
<CardContent>
|
||||
<Typography variant='h4'>Login</Typography>
|
||||
<TextField
|
||||
label='Username'
|
||||
className={classes.field}
|
||||
onChange={e => setUsername(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
label='Password'
|
||||
type='password'
|
||||
className={classes.field}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button
|
||||
color='primary'
|
||||
className={classes.field}
|
||||
onClick={handleLogin}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
</CardActions>
|
||||
<form>
|
||||
<CardContent>
|
||||
<Typography variant='h4'>Login</Typography>
|
||||
<TextField
|
||||
label='Username'
|
||||
InputLabelProps={{
|
||||
htmlFor: 'username'
|
||||
}}
|
||||
id='username'
|
||||
className={classes.field}
|
||||
onChange={e => setUsername(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
label='Password'
|
||||
type='password'
|
||||
InputLabelProps={{
|
||||
htmlFor: 'password'
|
||||
}}
|
||||
id='password'
|
||||
className={classes.field}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
/>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button
|
||||
color='primary'
|
||||
className={classes.field}
|
||||
onClick={handleLogin}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
</CardActions>
|
||||
</form>
|
||||
</Card>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
89
src/index.ts
89
src/index.ts
@@ -12,25 +12,34 @@ import { Console } from './lib/logger';
|
||||
import { AddressInfo } from 'net';
|
||||
import { magenta, bold, green, reset, blue, red } from '@dicedtomato/colors';
|
||||
import { Configuration } from './lib/Config';
|
||||
import { UserController } from './controllers/UserController';
|
||||
import { RootController } from './controllers/RootController';
|
||||
import { UserController } from './lib/api/controllers/UserController';
|
||||
import { RootController } from './lib/api/controllers/RootController';
|
||||
import { join } from 'path';
|
||||
import { ImagesController } from './controllers/ImagesController';
|
||||
import { URLSController } from './controllers/URLSController';
|
||||
import { ImagesController } from './lib/api/controllers/ImagesController';
|
||||
import { URLSController } from './lib/api/controllers/URLSController';
|
||||
import { checkVersion } from './lib/Util';
|
||||
import { readFileSync } from 'fs';
|
||||
import { Image } from './entities/Image';
|
||||
import { User } from './entities/User';
|
||||
import { Zipline } from './entities/Zipline';
|
||||
import { URL } from './entities/URL';
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import { Image } from './lib/entities/Image';
|
||||
import { User } from './lib/entities/User';
|
||||
import { Zipline } from './lib/entities/Zipline';
|
||||
import { URL } from './lib/entities/URL';
|
||||
const dev = process.env.NODE_ENV !== 'production';
|
||||
|
||||
(async () => { if (await checkVersion()) Console.logger('Zipline').info('running an outdated version of zipline, please update soon!'); })();
|
||||
(async () => {
|
||||
if (await checkVersion())
|
||||
Console.logger('Zipline').info(
|
||||
'running an outdated version of zipline, please update soon!'
|
||||
);
|
||||
})();
|
||||
|
||||
console.log(`
|
||||
${magenta(text('Zipline'))}
|
||||
|
||||
Version : ${blue(process.env.npm_package_version || readFileSync(join(process.cwd(), 'package.json'), 'utf8'))}
|
||||
Version : ${blue(
|
||||
process.env.npm_package_version ||
|
||||
JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf8'))
|
||||
.version
|
||||
)}
|
||||
GitHub : ${blue('https://github.com/ZiplineProject/zipline')}
|
||||
Issues : ${blue('https://github.com/ZiplineProject/zipline/issues')}
|
||||
Docs : ${blue('https://zipline.diced.wtf/')}
|
||||
@@ -109,6 +118,33 @@ server.get(`${config.urls.route}/:id`, async function (
|
||||
return reply.redirect(urlId.url);
|
||||
});
|
||||
|
||||
server.get(`${config.uploader.rich_content_route || '/a'}/:id`, async function (
|
||||
req: FastifyRequest<{ Params: { id: string } }>,
|
||||
reply: FastifyReply
|
||||
) {
|
||||
if (!existsSync(join(config.uploader.directory, req.params.id))) {
|
||||
await app.render404(req.raw, reply.raw);
|
||||
return (reply.sent = true);
|
||||
}
|
||||
|
||||
return reply.type('text/html').send(`
|
||||
<html>
|
||||
<head>
|
||||
<meta property="theme-color" content="${config.meta.color}">
|
||||
<meta property="og:title" content="${req.params.id}">
|
||||
<meta property="og:url" content="${config.uploader.route}/${req.params.id}">
|
||||
<meta property="og:image" content="${config.uploader.route}/${req.params.id}">
|
||||
<meta property="twitter:card" content="summary_large_image">
|
||||
</head>
|
||||
<body>
|
||||
<div style="text-align:center;vertical-align:middle;">
|
||||
<img src="${config.uploader.route}/${req.params.id}" >
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
});
|
||||
|
||||
server.register(fastifyMultipart);
|
||||
|
||||
server.register(fastifyTypeorm, {
|
||||
@@ -144,19 +180,24 @@ server.register(fastifyStatic, {
|
||||
|
||||
server.register(fastifyFavicon);
|
||||
|
||||
server.listen({
|
||||
port: config.core.port,
|
||||
host: config.core.host
|
||||
}, err => {
|
||||
if (err) throw err;
|
||||
const info = server.server.address() as AddressInfo;
|
||||
server.listen(
|
||||
{
|
||||
port: config.core.port,
|
||||
host: config.core.host
|
||||
},
|
||||
err => {
|
||||
if (err) throw err;
|
||||
const info = server.server.address() as AddressInfo;
|
||||
|
||||
Console.logger('Server').info(
|
||||
`server listening on ${bold(
|
||||
`${green(info.address)}${reset(':')}${bold(green(info.port.toString()))}`
|
||||
)}`
|
||||
);
|
||||
});
|
||||
Console.logger('Server').info(
|
||||
`server listening on ${bold(
|
||||
`${green(info.address)}${reset(':')}${bold(
|
||||
green(info.port.toString())
|
||||
)}`
|
||||
)}`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
server.addHook('preHandler', async (req, reply) => {
|
||||
if (
|
||||
@@ -166,4 +207,4 @@ server.addHook('preHandler', async (req, reply) => {
|
||||
await app.render404(req.raw, reply.raw);
|
||||
return (reply.sent = true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface ConfigMeta {
|
||||
export interface ConfigUploader {
|
||||
directory: string;
|
||||
route: string;
|
||||
rich_content_route?: string;
|
||||
length: number;
|
||||
blacklisted: string[];
|
||||
original: boolean;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { compareSync, hashSync } from 'bcrypt';
|
||||
import { Configuration } from './Config';
|
||||
import { Connection } from 'typeorm';
|
||||
import { compare } from 'semver';
|
||||
import { Zipline } from '../entities/Zipline';
|
||||
import { Zipline } from './entities/Zipline';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Image } from '../entities/Image';
|
||||
import { URL } from '../entities/URL';
|
||||
import { User } from '../entities/User';
|
||||
import { Image } from './entities/Image';
|
||||
import { URL } from './entities/URL';
|
||||
import { User } from './entities/User';
|
||||
import { Config, Configuration, ConfigWebhooks } from './Config';
|
||||
import { Console } from './logger';
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ import {
|
||||
DELETE
|
||||
} from 'fastify-decorators';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Image } from '../entities/Image';
|
||||
import { LoginError } from '../lib/api/APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../lib/Config';
|
||||
import { Console } from '../lib/logger';
|
||||
import { readBaseCookie } from '../lib/Util';
|
||||
import { WebhookHelper, WebhookType } from '../lib/Webhooks';
|
||||
import { Image } from '../../entities/Image';
|
||||
import { LoginError } from '../APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../../Config';
|
||||
import { Console } from '../../logger';
|
||||
import { readBaseCookie } from '../../Util';
|
||||
import { WebhookHelper, WebhookType } from '../../Webhooks';
|
||||
|
||||
const config = Configuration.readConfig();
|
||||
|
||||
@@ -12,18 +12,25 @@ import { join } from 'path';
|
||||
import { Repository } from 'typeorm';
|
||||
import { pipeline } from 'stream';
|
||||
import { promisify } from 'util';
|
||||
import { Image } from '../entities/Image';
|
||||
import { User } from '../entities/User';
|
||||
import { AuthError } from '../lib/api/APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../lib/Config';
|
||||
import { createRandomId, getFirst } from '../lib/Util';
|
||||
import { Console } from '../lib/logger';
|
||||
import { WebhookHelper, WebhookType } from '../lib/Webhooks';
|
||||
import { Image } from '../../entities/Image';
|
||||
import { User } from '../../entities/User';
|
||||
import { AuthError } from '../APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../../Config';
|
||||
import { createRandomId, getFirst } from '../../Util';
|
||||
import { Console } from '../../logger';
|
||||
import { WebhookHelper, WebhookType } from '../../Webhooks';
|
||||
const pump = promisify(pipeline);
|
||||
|
||||
const config = Configuration.readConfig();
|
||||
const rateLimiterConfig = config.core.ratelimiter
|
||||
? { config: { rateLimit: { max: config.core.ratelimiter.requests, timeWindow: config.core.ratelimiter.retry_after } } }
|
||||
? {
|
||||
config: {
|
||||
rateLimit: {
|
||||
max: config.core.ratelimiter.requests,
|
||||
timeWindow: config.core.ratelimiter.retry_after
|
||||
}
|
||||
}
|
||||
}
|
||||
: {};
|
||||
|
||||
@Controller('/api')
|
||||
@@ -135,14 +142,18 @@ export class RootController {
|
||||
`image ${fileName}.${ext} was uploaded by ${user.username} (${user.id})`
|
||||
);
|
||||
|
||||
const host = `${config.core.secure ? 'https' : 'http'}://${req.hostname}${
|
||||
config.uploader.rich_content_route
|
||||
? config.uploader.rich_content_route
|
||||
: config.uploader.route
|
||||
}/`;
|
||||
|
||||
if (this.webhooks.events.includes(WebhookType.UPLOAD))
|
||||
WebhookHelper.sendWebhook(this.webhooks.upload.content, {
|
||||
image,
|
||||
host: `${config.core.secure ? 'https' : 'http'}://${req.hostname}${config.uploader.route}/`
|
||||
host
|
||||
});
|
||||
|
||||
reply.send(
|
||||
`${config.core.secure ? 'https' : 'http'}://${req.hostname}${config.uploader.route}/${fileName}.${ext}`
|
||||
);
|
||||
reply.send(host);
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,13 @@ import {
|
||||
POST
|
||||
} from 'fastify-decorators';
|
||||
import { Repository } from 'typeorm';
|
||||
import { URL } from '../entities/URL';
|
||||
import { User } from '../entities/User';
|
||||
import { LoginError } from '../lib/api/APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../lib/Config';
|
||||
import { Console } from '../lib/logger';
|
||||
import { createRandomId, readBaseCookie } from '../lib/Util';
|
||||
import { WebhookType, WebhookHelper } from '../lib/Webhooks';
|
||||
import { URL } from '../../entities/URL';
|
||||
import { User } from '../../entities/User';
|
||||
import { LoginError } from '../APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../../Config';
|
||||
import { Console } from '../../logger';
|
||||
import { createRandomId, readBaseCookie } from '../../Util';
|
||||
import { WebhookType, WebhookHelper } from '../../Webhooks';
|
||||
|
||||
const config = Configuration.readConfig();
|
||||
|
||||
@@ -9,16 +9,16 @@ import {
|
||||
DELETE
|
||||
} from 'fastify-decorators';
|
||||
import { Repository } from 'typeorm';
|
||||
import { User } from '../entities/User';
|
||||
import { Zipline } from '../entities/Zipline';
|
||||
import { User } from '../../entities/User';
|
||||
import { Zipline } from '../../entities/Zipline';
|
||||
import {
|
||||
UserNotFoundError,
|
||||
MissingBodyData,
|
||||
LoginError,
|
||||
UserExistsError
|
||||
} from '../lib/api/APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../lib/Config';
|
||||
import { Console } from '../lib/logger';
|
||||
} from '../APIErrors';
|
||||
import { Configuration, ConfigWebhooks } from '../../Config';
|
||||
import { Console } from '../../logger';
|
||||
import {
|
||||
checkPassword,
|
||||
createBaseCookie,
|
||||
@@ -26,8 +26,8 @@ import {
|
||||
encryptPassword,
|
||||
getFirst,
|
||||
readBaseCookie
|
||||
} from '../lib/Util';
|
||||
import { WebhookType, WebhookHelper } from '../lib/Webhooks';
|
||||
} from '../../Util';
|
||||
import { WebhookType, WebhookHelper } from '../../Webhooks';
|
||||
|
||||
const config = Configuration.readConfig();
|
||||
|
||||
@@ -16,7 +16,7 @@ import UI from '../../components/UI';
|
||||
import UIPlaceholder from '../../components/UIPlaceholder';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { store } from '../../store';
|
||||
import { Image } from '../../entities/Image';
|
||||
import { Image } from '../../lib/entities/Image';
|
||||
import { Configuration } from '../../lib/Config';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
|
||||
@@ -24,7 +24,7 @@ import copy from 'copy-to-clipboard';
|
||||
import UI from '../../components/UI';
|
||||
import UIPlaceholder from '../../components/UIPlaceholder';
|
||||
import { makeStyles } from '@material-ui/core';
|
||||
import { URL as URLEntity } from '../../entities/URL';
|
||||
import { URL as URLEntity } from '../../lib/entities/URL';
|
||||
import { Configuration } from '../../lib/Config';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable indent */
|
||||
import { User } from './entities/User';
|
||||
import { User } from './lib/entities/User';
|
||||
|
||||
export const LOGIN = 'LOGIN';
|
||||
export const LOGOUT = 'LOGOUT';
|
||||
|
||||
Reference in New Issue
Block a user