mirror of
https://github.com/diced/zipline.git
synced 2025-04-11 23:31:17 -05:00
cool
This commit is contained in:
parent
5c2ee55994
commit
20c3bf9910
18 changed files with 402 additions and 165 deletions
5
.idea/.gitignore
generated
vendored
Normal file
5
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/typex.iml" filepath="$PROJECT_DIR$/.idea/typex.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
12
.idea/typex.iml
generated
Normal file
12
.idea/typex.iml
generated
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
309
README.md
309
README.md
|
@ -243,159 +243,170 @@ Particles.JS, can be enabled and it's config can be changed willingly.
|
|||
|
||||
```json
|
||||
{
|
||||
"upload": {
|
||||
"fileLength": 6,
|
||||
"tempDir": "./temp",
|
||||
"uploadDir": "./uploads",
|
||||
"route": "/u"
|
||||
},
|
||||
"user": {
|
||||
"tokenLength": 32
|
||||
},
|
||||
"site": {
|
||||
"protocol": "http",
|
||||
"ssl": {
|
||||
"key": "./ssl/server.key",
|
||||
"cert": "./ssl/server.crt"
|
||||
"upload": {
|
||||
"fileLength": 6,
|
||||
"tempDir": "./temp",
|
||||
"uploadDir": "./uploads",
|
||||
"route": "/u"
|
||||
},
|
||||
"serveHTTPS": 8000,
|
||||
"serveHTTP": 8000
|
||||
},
|
||||
"administrator": {
|
||||
"password": "1234",
|
||||
"authorization": "Administrator 1234"
|
||||
},
|
||||
"orm": {
|
||||
"type": "postgres",
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"username": "user",
|
||||
"password": "1234",
|
||||
"database": "typex",
|
||||
"synchronize": true,
|
||||
"logging": false,
|
||||
"entities": [
|
||||
"out/src/entities/**/*.js"
|
||||
]
|
||||
},
|
||||
"sessionSecret": "qwerty",
|
||||
"meta": {
|
||||
"favicon": "/public/assets/typex_small_circle.png",
|
||||
"title": "TypeX"
|
||||
},
|
||||
"particles": {
|
||||
"enabled": true,
|
||||
"settings": {
|
||||
"particles": {
|
||||
"number": {
|
||||
"value": 52,
|
||||
"density": {
|
||||
"enable": true,
|
||||
"value_area": 800
|
||||
}
|
||||
"shorten": {
|
||||
"idLength": 4,
|
||||
"route": "/s"
|
||||
},
|
||||
"user": {
|
||||
"tokenLength": 32
|
||||
},
|
||||
"site": {
|
||||
"protocol": "http",
|
||||
"returnProtocol": "https",
|
||||
"ssl": {
|
||||
"key": "./ssl/server.key",
|
||||
"cert": "./ssl/server.crt"
|
||||
},
|
||||
"color": {
|
||||
"value": "#cd4c4c"
|
||||
},
|
||||
"shape": {
|
||||
"type": "circle",
|
||||
"stroke": {
|
||||
"width": 0,
|
||||
"color": "#000000"
|
||||
},
|
||||
"polygon": {
|
||||
"nb_sides": 9
|
||||
},
|
||||
"image": {
|
||||
"src": "img/github.svg",
|
||||
"width": 60,
|
||||
"height": 100
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"value": 0.5,
|
||||
"random": false,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 1,
|
||||
"opacity_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"value": 0,
|
||||
"random": true,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 40,
|
||||
"size_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"line_linked": {
|
||||
"enable": true,
|
||||
"distance": 150,
|
||||
"color": "#ffffff",
|
||||
"opacity": 0.4,
|
||||
"width": 1
|
||||
},
|
||||
"move": {
|
||||
"enable": true,
|
||||
"speed": 6,
|
||||
"direction": "none",
|
||||
"random": false,
|
||||
"straight": false,
|
||||
"out_mode": "out",
|
||||
"bounce": false,
|
||||
"attract": {
|
||||
"enable": false,
|
||||
"rotateX": 600,
|
||||
"rotateY": 1200
|
||||
}
|
||||
"serveHTTPS": 8000,
|
||||
"serveHTTP": 443,
|
||||
"logRoutes": true
|
||||
},
|
||||
"administrator": {
|
||||
"password": "1234"
|
||||
},
|
||||
"orm": {
|
||||
"type": "postgres",
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"username": "user",
|
||||
"password": "1234",
|
||||
"database": "typex",
|
||||
"synchronize": true,
|
||||
"logging": false,
|
||||
"entities": [
|
||||
"out/src/entities/**/*.js"
|
||||
]
|
||||
},
|
||||
"sessionSecret": "1234",
|
||||
"meta": {
|
||||
"favicon": "/public/assets/typex_small_circle.png",
|
||||
"title": "TypeX"
|
||||
},
|
||||
"discordWebhook": {
|
||||
"enabled": true,
|
||||
"url": "https://canary.discordapp.com/api/webhooks/id/token",
|
||||
"username": "TypeX Logs",
|
||||
"avatarURL": "https://domain/public/assets/typex_small_circle.png"
|
||||
},
|
||||
"particles": {
|
||||
"enabled": true,
|
||||
"settings": {
|
||||
"particles": {
|
||||
"number": {
|
||||
"value": 52,
|
||||
"density": {
|
||||
"enable": true,
|
||||
"value_area": 800
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"value": "#cd4c4c"
|
||||
},
|
||||
"shape": {
|
||||
"type": "circle",
|
||||
"stroke": {
|
||||
"width": 0,
|
||||
"color": "#000000"
|
||||
},
|
||||
"polygon": {
|
||||
"nb_sides": 9
|
||||
},
|
||||
"image": {
|
||||
"src": "img/github.svg",
|
||||
"width": 60,
|
||||
"height": 100
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"value": 0.5,
|
||||
"random": false,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 1,
|
||||
"opacity_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"value": 0,
|
||||
"random": true,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 40,
|
||||
"size_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"line_linked": {
|
||||
"enable": true,
|
||||
"distance": 150,
|
||||
"color": "#ffffff",
|
||||
"opacity": 0.4,
|
||||
"width": 1
|
||||
},
|
||||
"move": {
|
||||
"enable": true,
|
||||
"speed": 6,
|
||||
"direction": "none",
|
||||
"random": false,
|
||||
"straight": false,
|
||||
"out_mode": "out",
|
||||
"bounce": false,
|
||||
"attract": {
|
||||
"enable": false,
|
||||
"rotateX": 600,
|
||||
"rotateY": 1200
|
||||
}
|
||||
}
|
||||
},
|
||||
"interactivity": {
|
||||
"detect_on": "canvas",
|
||||
"events": {
|
||||
"onhover": {
|
||||
"enable": false,
|
||||
"mode": "grab"
|
||||
},
|
||||
"onclick": {
|
||||
"enable": false,
|
||||
"mode": "repulse"
|
||||
},
|
||||
"resize": true
|
||||
},
|
||||
"modes": {
|
||||
"grab": {
|
||||
"distance": 400,
|
||||
"line_linked": {
|
||||
"opacity": 1
|
||||
}
|
||||
},
|
||||
"bubble": {
|
||||
"distance": 400,
|
||||
"size": 40,
|
||||
"duration": 2,
|
||||
"opacity": 8,
|
||||
"speed": 3
|
||||
},
|
||||
"repulse": {
|
||||
"distance": 200,
|
||||
"duration": 0.4
|
||||
},
|
||||
"push": {
|
||||
"particles_nb": 4
|
||||
},
|
||||
"remove": {
|
||||
"particles_nb": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"retina_detect": true
|
||||
}
|
||||
},
|
||||
"interactivity": {
|
||||
"detect_on": "canvas",
|
||||
"events": {
|
||||
"onhover": {
|
||||
"enable": false,
|
||||
"mode": "grab"
|
||||
},
|
||||
"onclick": {
|
||||
"enable": false,
|
||||
"mode": "repulse"
|
||||
},
|
||||
"resize": true
|
||||
},
|
||||
"modes": {
|
||||
"grab": {
|
||||
"distance": 400,
|
||||
"line_linked": {
|
||||
"opacity": 1
|
||||
}
|
||||
},
|
||||
"bubble": {
|
||||
"distance": 400,
|
||||
"size": 40,
|
||||
"duration": 2,
|
||||
"opacity": 8,
|
||||
"speed": 3
|
||||
},
|
||||
"repulse": {
|
||||
"distance": 200,
|
||||
"duration": 0.4
|
||||
},
|
||||
"push": {
|
||||
"particles_nb": 4
|
||||
},
|
||||
"remove": {
|
||||
"particles_nb": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"retina_detect": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
7
package-lock.json
generated
7
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "typex",
|
||||
"version": "0.3.1",
|
||||
"version": "0.3.3",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -852,6 +852,11 @@
|
|||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
"http-status-codes": "^1.4.0",
|
||||
"mime": "^2.4.4",
|
||||
"multer": "^1.4.2",
|
||||
"node-fetch": "^2.6.0",
|
||||
"typeorm": "^0.2.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"pg": "^8.0.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { OK, BAD_REQUEST, FORBIDDEN } from 'http-status-codes';
|
|||
import { Controller, Middleware, Get, Post, Put, Delete, Patch } from '@overnightjs/core';
|
||||
import { Request, Response } from 'express';
|
||||
import { ORMHandler } from '..';
|
||||
import { randomId, getUser, getImage, findFile } from '../util';
|
||||
import { randomId, getUser, getImage, findFile, getShorten } from '../util';
|
||||
import { createReadStream, createWriteStream, unlinkSync, existsSync, mkdirSync, readFileSync } from 'fs'
|
||||
import multer from 'multer'
|
||||
import { getExtension } from 'mime';
|
||||
|
@ -10,6 +10,9 @@ import { User } from '../entities/User';
|
|||
import { sep } from 'path';
|
||||
import { cookiesForAPI } from '../middleware/cookiesForAPI';
|
||||
import Logger from '@ayanaware/logger';
|
||||
import { DiscordWebhook } from '../structures/DiscordWebhook';
|
||||
import { ImageUtil } from '../structures/ImageUtil';
|
||||
import { ShortenUtil } from '../structures/ShortenUtil';
|
||||
|
||||
if (!findFile('config.json', process.cwd())) {
|
||||
Logger.get('FS').error(`No config.json exists in the ${__dirname}, exiting...`)
|
||||
|
@ -42,9 +45,24 @@ export class APIController {
|
|||
source.on("end", function () {
|
||||
unlinkSync(file.path);
|
||||
});
|
||||
const img = await getImage(this.orm, `${config.site.returnProtocol}://${req.headers['host']}/u/${id}.${extension}`, user.id)
|
||||
const img = await getImage(this.orm, `${config.site.returnProtocol}://${req.headers['host']}${config.upload.route}/${id}.${extension}`, user.id)
|
||||
Logger.get('TypeX.Uploader').info(`New image uploaded ${img.url} (${img.id}) by ${user.username} (${user.id})`)
|
||||
return res.status(200).send(`${config.site.returnProtocol}://${req.headers['host']}/u/${id}.${extension}`)
|
||||
if (config.discordWebhook.enabled) new DiscordWebhook(config.discordWebhook.url).sendImageUpdate(user, ImageUtil.parseURL(img.url), config);
|
||||
return res.status(200).send(`${config.site.returnProtocol}://${req.headers['host']}${config.upload.route}/${id}.${extension}`)
|
||||
}
|
||||
|
||||
@Post('shorten')
|
||||
private async shorten(req: Request, res: Response) {
|
||||
if (req.headers['authorization'] === config.administrator.authorization) return res.status(BAD_REQUEST).json({ code: BAD_REQUEST, message: "You can't upload files with the administrator account." })
|
||||
const users = await this.orm.repos.user.find({ where: { token: req.headers['authorization'] } });
|
||||
if (!users[0]) return res.status(FORBIDDEN).json({ code: FORBIDDEN, message: "Unauthorized" })
|
||||
if (req.headers['authorization'] !== users[0].token) return res.status(FORBIDDEN).json({ code: FORBIDDEN, message: "Unauthorized" })
|
||||
const user = users[0];
|
||||
const id = randomId(config.shorten.idLength)
|
||||
const shrt = await getShorten(this.orm, id, req.body.url, `${config.site.returnProtocol}://${req.headers['host']}${config.shorten.route}/${id}`, user.id);
|
||||
Logger.get('TypeX.Shortener').info(`New url shortened ${shrt.url} (${req.body.url}) (${shrt.id}) by ${user.username} (${user.id})`)
|
||||
if (config.discordWebhook.enabled) new DiscordWebhook(config.discordWebhook.url).sendShortenUpdate(user, shrt, ShortenUtil.parseURL(shrt.url), config);
|
||||
return res.status(200).send(`${config.site.returnProtocol}://${req.headers['host']}${config.shorten.route}/${id}`)
|
||||
}
|
||||
|
||||
@Post('user')
|
||||
|
|
|
@ -6,6 +6,8 @@ import { readFileSync } from 'fs'
|
|||
import multer from 'multer';
|
||||
import { cookies } from '../middleware/cookies';
|
||||
import Logger from '@ayanaware/logger';
|
||||
import { ShortenUtil } from '../structures/ShortenUtil';
|
||||
import { ImageUtil } from '../structures/ImageUtil';
|
||||
|
||||
if (!findFile('config.json', process.cwd())) {
|
||||
Logger.get('FS').error(`No config.json exists in the ${__dirname}, exiting...`)
|
||||
|
@ -61,7 +63,14 @@ export class IndexController {
|
|||
if (req.body.password !== user.password) return res.status(200).render('login', { failed: true, config })
|
||||
req.session.user = user;
|
||||
res.cookie('typex_user', req.session.user.id, { maxAge: 1036800000 });
|
||||
return res.redirect('/')
|
||||
return res.redirect('/');
|
||||
}
|
||||
|
||||
@Get(`${config.shorten.route.slice(1)}/:id`)
|
||||
private async getShorten(req: Request, res: Response) {
|
||||
const shorten = await this.orm.repos.shorten.findOne({ key: req.params.id });
|
||||
if (!shorten) return res.render('404');
|
||||
return res.redirect(shorten.origin)
|
||||
}
|
||||
|
||||
public set(orm: ORMHandler) {
|
||||
|
|
|
@ -11,9 +11,13 @@ export class Image {
|
|||
@Column("bigint")
|
||||
user: number;
|
||||
|
||||
@Column("bigint", { default: 0 })
|
||||
views: number;
|
||||
|
||||
set(options: { url: string, user: number }) {
|
||||
this.url = options.url;
|
||||
this.user = options.user;
|
||||
this.views = 0;
|
||||
return this;
|
||||
}
|
||||
}
|
31
src/entities/Shorten.ts
Normal file
31
src/entities/Shorten.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
|
||||
|
||||
@Entity()
|
||||
export class Shorten {
|
||||
@PrimaryGeneratedColumn({ type: 'bigint' })
|
||||
id: number;
|
||||
|
||||
@Column("text")
|
||||
origin: string;
|
||||
|
||||
@Column("text")
|
||||
url: string;
|
||||
|
||||
@Column("text", { default: "" })
|
||||
key: string;
|
||||
|
||||
@Column("bigint")
|
||||
user: number;
|
||||
|
||||
@Column("bigint", { default: 0 })
|
||||
views: number
|
||||
|
||||
set(options: { key: string, origin: string, url: string, user: number }) {
|
||||
this.key = options.key;
|
||||
this.origin = options.origin;
|
||||
this.url = options.url;
|
||||
this.user = options.user;
|
||||
this.views = 0;
|
||||
return this;
|
||||
}
|
||||
}
|
11
src/index.ts
11
src/index.ts
|
@ -3,7 +3,7 @@ import {
|
|||
Repository,
|
||||
Connection,
|
||||
createConnection,
|
||||
ConnectionOptions,
|
||||
ConnectionOptions
|
||||
} from "typeorm";
|
||||
import { User } from "./entities/User";
|
||||
import { TypeXServer } from "./server";
|
||||
|
@ -11,6 +11,7 @@ import Logger from "@ayanaware/logger";
|
|||
import { Image } from "./entities/Image";
|
||||
import { findFile } from "./util";
|
||||
import { readFileSync } from 'fs';
|
||||
import { Shorten } from "./entities/Shorten";
|
||||
|
||||
if (!findFile('config.json', process.cwd())) {
|
||||
Logger.get('FS').error(`No config.json exists in the ${__dirname}, exiting...`)
|
||||
|
@ -22,13 +23,12 @@ const config = JSON.parse(readFileSync(findFile('config.json', process.cwd()), '
|
|||
if (!config.upload?.route) {
|
||||
Logger.get('TypeX.Config').error(`Missing needed property on configuration: upload.route`)
|
||||
process.exit(1);
|
||||
} else if (!config.forever?.route) {
|
||||
Logger.get('TypeX.Config').error(`Missing needed property on configuration: forever.route`)
|
||||
}
|
||||
|
||||
export interface ORMRepos {
|
||||
user?: Repository<User>;
|
||||
image?: Repository<Image>;
|
||||
shorten?: Repository<Shorten>;
|
||||
}
|
||||
|
||||
export interface ORMHandler {
|
||||
|
@ -36,6 +36,10 @@ export interface ORMHandler {
|
|||
connection: Connection;
|
||||
}
|
||||
|
||||
const pk = JSON.parse(readFileSync(findFile('package.json', process.cwd()), 'utf8'));
|
||||
|
||||
Logger.get('TypeX').info(`Starting TypeX ${pk.version}`);
|
||||
|
||||
(async () => {
|
||||
const connection = await createConnection(config.orm as ConnectionOptions);
|
||||
const orm: ORMHandler = {
|
||||
|
@ -43,6 +47,7 @@ export interface ORMHandler {
|
|||
repos: {
|
||||
user: connection.getRepository(User),
|
||||
image: connection.getRepository(Image),
|
||||
shorten: connection.getRepository(Shorten)
|
||||
},
|
||||
};
|
||||
if (orm.connection.isConnected)
|
||||
|
|
|
@ -32,12 +32,23 @@ export class TypeXServer extends Server {
|
|||
saveUninitialized: false,
|
||||
})
|
||||
);
|
||||
this.app.use(async (req, res, next) => {
|
||||
console.log(req.url, req.baseUrl, req.originalUrl)
|
||||
if (!req.url.startsWith(config.upload.route)) return next();
|
||||
console.log(`${config.site.returnProtocol}://${req.headers['host']}${req.url}`)
|
||||
const upload = await orm.repos.image.findOne({ url: `${config.site.returnProtocol}://${req.headers['host']}${req.url}` });
|
||||
console.log(upload);
|
||||
if (!upload) return next();
|
||||
upload.views++;
|
||||
console.log(upload.views);
|
||||
orm.repos.image.save(upload);
|
||||
return next();
|
||||
})
|
||||
this.app.use(cookies());
|
||||
try {
|
||||
this.app.use(config.upload.route, express.static(config.upload.uploadDir));
|
||||
this.app.use(config.forever.route, express.static(config.forever.directory));
|
||||
} catch (e) {
|
||||
Logger.get('TypeX.Routes').error(`Could not formulate upload and forever static routes`)
|
||||
Logger.get('TypeX.Routes').error(`Could not formulate upload static route`)
|
||||
process.exit(1);
|
||||
}
|
||||
this.app.use("/public", express.static("public"));
|
||||
|
@ -46,13 +57,13 @@ export class TypeXServer extends Server {
|
|||
this.app.use(async (req, res, next) => {
|
||||
if (!config.site.logRoutes) return next();
|
||||
if (req.url.startsWith(config.upload.route)) return next();
|
||||
if (req.url.startsWith(config.forever.route)) return next();
|
||||
let user = req.session.user;
|
||||
const users = await orm.repos.user.find({ where: { token: req.headers['authorization'] } });
|
||||
if (users[0]) user = users[0]
|
||||
Logger.get('TypeX.Route').info(`Route ${req.url} was accessed by ${user ? user.username : '<no user found>'}`)
|
||||
return next();
|
||||
})
|
||||
});
|
||||
|
||||
this.setupControllers(orm);
|
||||
}
|
||||
|
||||
|
|
54
src/structures/DiscordWebhook.ts
Normal file
54
src/structures/DiscordWebhook.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import fetch from 'node-fetch';
|
||||
import { User } from '../entities/User';
|
||||
import { Shorten } from '../entities/Shorten';
|
||||
import { Imaged } from './ImageUtil';
|
||||
import { Shortened } from './ShortenUtil';
|
||||
|
||||
export class DiscordWebhook {
|
||||
public url: string;
|
||||
constructor(url: string) {
|
||||
this.url = url;
|
||||
this.checkExists();
|
||||
}
|
||||
async checkExists(): Promise<boolean> {
|
||||
const json = await (await fetch(this.url)).json();
|
||||
if (json.code === 10015) throw new Error('Unknown Webhook')
|
||||
else if (json.code === 50027) throw new Error('Invalid Webhook Token')
|
||||
else if (json.code) throw new Error(`DiscordAPIError[${json.code}]: ${json.message}`);
|
||||
return json.code ? false : true;
|
||||
}
|
||||
async sendImageUpdate(user: User, image: Imaged, config: any) {
|
||||
try {
|
||||
await (await fetch(this.url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
user: config.discordWebhook.username,
|
||||
avatar_url: config.discordWebhook.avatarURL,
|
||||
content: `New image uploaded to ${image.origin} by ${user.username} (${user.id}). [View Image](${image.url})`
|
||||
})
|
||||
}));
|
||||
} catch (e) {
|
||||
throw new Error(`Coulndn't send webhook: ${e.message}`)
|
||||
}
|
||||
}
|
||||
async sendShortenUpdate(user: User, shorten: Shorten, ex: Shortened, config: any) {
|
||||
try {
|
||||
await (await fetch(this.url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
user: config.discordWebhook.username,
|
||||
avatar_url: config.discordWebhook.avatarURL,
|
||||
content: `New shortened url added to ${ex.origin} by ${user.username} (${user.id}). ${shorten.origin} -> ${shorten.url}`
|
||||
})
|
||||
}));
|
||||
} catch (e) {
|
||||
throw new Error(`Coulndn't send webhook: ${e.message}`)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,14 @@
|
|||
import { getType } from 'mime';
|
||||
import { findFile } from '../util';
|
||||
import Logger from '@ayanaware/logger';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
if (!findFile('config.json', process.cwd())) {
|
||||
Logger.get('FS').error(`No config.json exists in the ${__dirname}, exiting...`)
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const config = JSON.parse(readFileSync(findFile('config.json', process.cwd()), 'utf8'))
|
||||
|
||||
export interface Imaged {
|
||||
url: string;
|
||||
|
@ -16,9 +26,9 @@ export class ImageUtil {
|
|||
url: parsed.href,
|
||||
origin: parsed.origin,
|
||||
protocol: parsed.protocol.slice(0, -1),
|
||||
key: parsed.pathname.startsWith('/u/') ? parsed.pathname.slice(3).split('.')[0] : null,
|
||||
extension: parsed.pathname.startsWith('/u/') ? parsed.pathname.slice(3).split('.')[1] : null,
|
||||
mime: parsed.pathname.startsWith('/u/') ? getType(parsed.pathname.slice(3).split('.')[1]) : null
|
||||
key: parsed.pathname.startsWith(config.upload.route) ? parsed.pathname.slice(3).split('.')[0] : null,
|
||||
extension: parsed.pathname.startsWith(config.upload.route) ? parsed.pathname.slice(3).split('.')[1] : null,
|
||||
mime: parsed.pathname.startsWith(config.upload.route) ? getType(parsed.pathname.slice(3).split('.')[1]) : null
|
||||
}
|
||||
}
|
||||
}
|
34
src/structures/ShortenUtil.ts
Normal file
34
src/structures/ShortenUtil.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { getType } from 'mime';
|
||||
import { findFile } from '../util';
|
||||
import Logger from '@ayanaware/logger';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
if (!findFile('config.json', process.cwd())) {
|
||||
Logger.get('FS').error(`No config.json exists in the ${__dirname}, exiting...`)
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const config = JSON.parse(readFileSync(findFile('config.json', process.cwd()), 'utf8'))
|
||||
|
||||
export interface Shortened {
|
||||
url: string;
|
||||
origin: string;
|
||||
protocol: string;
|
||||
key: string;
|
||||
extension: string;
|
||||
mime: string;
|
||||
}
|
||||
|
||||
export class ShortenUtil {
|
||||
static parseURL(url: string): Shortened {
|
||||
const parsed = new URL(url);
|
||||
return {
|
||||
url: parsed.href,
|
||||
origin: parsed.origin,
|
||||
protocol: parsed.protocol.slice(0, -1),
|
||||
key: parsed.pathname.startsWith(config.shorten.route) ? parsed.pathname.slice(3).split('.')[0] : null,
|
||||
extension: parsed.pathname.startsWith(config.shorten.route) ? parsed.pathname.slice(3).split('.')[1] : null,
|
||||
mime: parsed.pathname.startsWith(config.shorten.route) ? getType(parsed.pathname.slice(3).split('.')[1]) : null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import { User } from './entities/User';
|
|||
import { Image } from './entities/Image';
|
||||
import { statSync, readdirSync } from 'fs';
|
||||
import { join, basename } from 'path';
|
||||
import { Shorten } from './entities/Shorten';
|
||||
|
||||
|
||||
export function randomId(length) {
|
||||
|
@ -38,6 +39,12 @@ export async function getImage(orm: ORMHandler, url: string, user: number) {
|
|||
return image;
|
||||
}
|
||||
|
||||
export async function getShorten(orm: ORMHandler, key: string, origin: string, url: string, user: number) {
|
||||
const image = await orm.repos.shorten.findOne({ key });
|
||||
if (!image) return orm.repos.shorten.save(new Shorten().set({ key, origin, url, user }));
|
||||
return image;
|
||||
}
|
||||
|
||||
export function findFile(file, directory) {
|
||||
const result = [];
|
||||
(function read(dir) {
|
||||
|
|
Loading…
Add table
Reference in a new issue