Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
NotAShelf committed Jun 28, 2023
2 parents 0571d06 + 80c6191 commit 80f3858
Show file tree
Hide file tree
Showing 17 changed files with 1,714 additions and 1,466 deletions.
13 changes: 9 additions & 4 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ ass was designed with developers in mind. If you are a developer & want somethin

| Type | What is it? |
| ---- | ----------- |
| **[Zero-width spaces][ZWS]** | When pasted elsewhere, the URL appears to be *just* your domain name. Some browsers or sites may not recognize these URLs (Discord **does** support these)<br>![ZWS sample] |
| **[Zero-width spaces][ZWS]** | When pasted elsewhere, the URL appears to be *just* your domain name. Some browsers or sites may not recognize these URLs (Discord sadly no longer supports these as of April 2023)<br>![ZWS sample] |
| **Mixed-case alphanumeric** | The "safe" mode. URL's are browser safe as the character set is just letters & numbers. |
| **Gfycat** | Gfycat-style ID's (for example: `https://example.com/unsung-discrete-grub`). Thanks to [Gfycat] for the wordlists |
| **Original** | The "basic" mode. URL matches the same filename as when the file was uploaded. This may be prone to conflicts with files of the same name. |
Expand Down Expand Up @@ -191,14 +191,19 @@ The first time you run ass, the setup process will automatically be called & you

## Using HTTPS

For HTTPS support, you must configure a reverse proxy. I recommend Caddy but any reverse proxy should work (such as Apache or Nginx). I also have a [tutorial on easily setting up Caddy][my tutorial] as a reverse proxy server.
For HTTPS support, you must configure a reverse proxy. I recommend [Caddy] but any reverse proxy works fine (such as Apache or Nginx). A sample config for Caddy is provided below:

```
ass.example.com {
reverse_proxy localhost:40115
}
```

[Caddy]: https://caddyserver.com/
[my tutorial]: https://old.jmoore.dev/tutorials/2021/03/caddy-express-reverse-proxy/

## Cloudflare users

In your Cloudflare DNS dashboard, set your domain/subdomain to **DNS Only** if you experience issues with **Proxied**.
In your Cloudflare DNS dashboard, set your domain/subdomain to **DNS Only** if you experience issues with **Proxied**. This may not be necessary for all users.

> <img src="https://user-images.githubusercontent.com/29926144/114085791-0f467680-986f-11eb-8cdb-34a9dfae3a23.png" height="140px">
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# - Zusier <[email protected]> (https://github.com/Zusier)

# Node 16 image
FROM node:16.14.0
FROM node:16.19.1

# Set working directory
WORKDIR /opt/ass/
Expand Down
3,035 changes: 1,648 additions & 1,387 deletions package-lock.json

Large diffs are not rendered by default.

42 changes: 21 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ass",
"version": "0.14.2",
"description": "The superior self-hosted ShareX server",
"version": "0.14.4",
"description": "The simple self-hosted ShareX server",
"main": "ass.js",
"engines": {
"node": ">=16.14.x",
Expand Down Expand Up @@ -42,42 +42,42 @@
"url": "https://patreon.com/tycrek"
},
"dependencies": {
"@tinycreek/postcss-font-magician": "^4.1.0",
"@tsconfig/node16": "^1.0.1",
"@tycrek/discord-hookr": "^0.1.0",
"@tycrek/express-nofavicon": "^1.0.3",
"@tycrek/express-postcss": "^0.2.4",
"@tycrek/isprod": "^2.0.2",
"@tycrek/log": "^0.6.0-7",
"@tycrek/express-postcss": "^0.4.0",
"@tycrek/joint": "^1.0.0-1",
"@tycrek/log": "^0.7.1",
"@tycrek/papito": "^0.3.4",
"@xoi/gps-metadata-remover": "^1.1.1",
"any-shell-escape": "^0.1.1",
"autoprefixer": "^10.4.4",
"aws-sdk": "^2.1115.0",
"axios": "^1.2.1",
"autoprefixer": "^10.4.13",
"aws-sdk": "^2.1318.0",
"axios": "^1.3.3",
"bcrypt": "^5.1.0",
"chalk": "^4.1.2",
"check-node-version": "^4.2.1",
"crypto-random-string": "3.3.1",
"cssnano": "^5.1.7",
"cssnano": "^5.1.15",
"escape-html": "^1.0.3",
"express": "^4.17.3",
"express": "^4.18.2",
"express-brute": "^1.0.1",
"express-busboy": "^8.0.2",
"ffmpeg-static": "^4.4.0",
"fs-extra": "^10.0.1",
"helmet": "^4.6.0",
"luxon": "^2.3.1",
"express-busboy": "^9.0.0",
"ffmpeg-static": "^5.1.0",
"fs-extra": "^11.1.0",
"helmet": "^6.0.1",
"luxon": "^3.3.0",
"nanoid": "^3.3.4",
"node-fetch": "^2.6.7",
"node-vibrant": "^3.1.6",
"postcss-font-magician": "^3.0.0",
"prompt": "^1.3.0",
"pug": "^3.0.2",
"sanitize-filename": "^1.6.3",
"sharp": "^0.30.3",
"sharp": "^0.31.3",
"stream-to-array": "^2.3.0",
"submodule": "^1.2.1",
"tailwindcss": "^3.0.24",
"typescript": "^4.6.3",
"tailwindcss": "^3.2.7",
"typescript": "^4.9.5",
"uuid": "^8.3.2"
},
"devDependencies": {
Expand All @@ -88,7 +88,7 @@
"@types/express-busboy": "^8.0.0",
"@types/ffmpeg-static": "^3.0.0",
"@types/fs-extra": "^9.0.12",
"@types/luxon": "^2.0.3",
"@types/luxon": "^3.3.0",
"@types/marked": "^3.0.0",
"@types/node": "^16.9.0",
"@types/node-fetch": "^2.5.12",
Expand Down
17 changes: 11 additions & 6 deletions src/ass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Config, MagicNumbers, Package } from 'ass-json';
//#region Imports
import fs from 'fs-extra';
import express, { Request, Response, json as BodyParserJson } from 'express';
import nofavicon from '@tycrek/express-nofavicon';
import { nofavicon } from '@tycrek/joint';
import { epcss } from '@tycrek/express-postcss';
import tailwindcss from 'tailwindcss';
import helmet from 'helmet';
Expand Down Expand Up @@ -78,7 +78,7 @@ const bruteforce = new ExpressBrute(new ExpressBrute.MemoryStore(), {
app.get(['/'], bruteforce.prevent, (_req, _res, next) => next());

// Express logger middleware
app.use(log.middleware());
// app.use(log.middleware());

// Body parser for API POST requests
// (I really don't like this being top level but it does not work inside the API Router as of 2022-12-24)
Expand All @@ -93,7 +93,8 @@ app.use(helmet.dnsPrefetchControl());
useSsl && app.use(helmet.hsts({ preload: true })); // skipcq: JS-0093

// Don't process favicon requests
app.use(nofavicon);
// todo: this doesn't actually return a 204 properly, it returns a 404
app.use(nofavicon.none());

// Use custom index, otherwise render README.md
type ASS_INDEX_TYPE = 'html' | 'js' | undefined;
Expand All @@ -120,7 +121,7 @@ app.use('/css', epcss({
tailwindcss,
require('autoprefixer')(),
require('cssnano')(),
require('postcss-font-magician')(),
require('@tinycreek/postcss-font-magician')(),
],
warn: (warning: Error) => log.warn('PostCSS', warning.toString())
}));
Expand All @@ -129,7 +130,11 @@ app.use('/css', epcss({
app.use('/:resourceId', (req, _res, next) => (req.resourceId = req.params.resourceId, next()), ROUTERS.resource); // skipcq: JS-0086, JS-0090

// Error handler
app.use((err: ErrWrap, _req: Request, res: Response) => log.error(err.message).err(err).callback(() => res.sendStatus(CODE_INTERNAL_SERVER_ERROR))); // skipcq: JS-0128
app.use((err: ErrWrap, _req: Request, res: Response) => {
log.error(err.message);
console.error(err);
res.sendStatus(CODE_INTERNAL_SERVER_ERROR);
});

(async function start() {
await AuthOnStart();
Expand All @@ -143,5 +148,5 @@ app.use((err: ErrWrap, _req: Request, res: Response) => log.error(err.message).e
.info('Frontend', ASS_FRONTEND.enabled ? ASS_FRONTEND.brand : 'disabled', `${ASS_FRONTEND.enabled ? `${getTrueHttp()}${getTrueDomain()}${ASS_FRONTEND.endpoint}` : ''}`)
.info('Custom index', ASS_INDEX ?? 'disabled')
.blank()
.express()!.Host(app, port, host, () => log.success('Ready for uploads', `Storing resources ${s3enabled ? 'in S3' : 'on disk'}`));
.callback(() => app.listen(port, host, () => log.success('Ready for uploads', `Storing resources ${s3enabled ? 'in S3' : 'on disk'}`)));
})();
4 changes: 2 additions & 2 deletions src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ export const onStart = (authFile = 'auth.json') => new Promise((resolve, reject)
log.debug('File does not exist', authFile, 'will be created automatically');
return fs.writeJson(file, { migrated: true });
})
.catch((errWriteJson) => log.error('Failed to create auth.json').callback(reject, errWriteJson))
.catch((errWriteJson) => log.error('Failed to create auth.json').callback(() => reject(errWriteJson)))

// File exists or was created
.then(() => fs.readJson(file))
Expand All @@ -393,7 +393,7 @@ export const onStart = (authFile = 'auth.json') => new Promise((resolve, reject)
// Add users to the map
return json.users.forEach((user) => users.push(user));
})
.catch((errReadJson) => log.error('Failed to read auth.json').callback(reject, errReadJson))
.catch((errReadJson) => log.error('Failed to read auth.json').callback(() => reject(errReadJson)))
.then(resolve);
});

Expand Down
2 changes: 1 addition & 1 deletion src/checkEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ function doCheck() {

if (require.main !== module) module.exports = doCheck;
else doCheck()
.then((result) => logger.comment(`Wanted: ${ENGINES.node} (npm ${ENGINES.npm})`).node().success(result))
.then((result) => logger.comment(`Wanted: ${ENGINES.node} (npm ${ENGINES.npm})`)/* .node() */.success(result))
.catch((err) => logger.error(err) && process.exit(1));
2 changes: 1 addition & 1 deletion src/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export default (file: FileData): Promise<string> =>
toArray((fs.createReadStream(file.path)))
.then((parts: any[]) => Buffer.concat(parts.map((part: any) => (Buffer.isBuffer(part) ? part : Buffer.from(part)))))
.then((buf: Buffer) => crypto.createHash('sha1').update(buf).digest('hex')) // skipcq: JS-D003
.then((hash: string) => log.debug(`Hash for ${file.originalname}`, hash, 'SHA1, hex').callback(resolve, hash))
.then((hash: string) => log.debug(`Hash for ${file.originalname}`, hash, 'SHA1, hex').callback(() => resolve(hash)))
.catch(reject));
36 changes: 6 additions & 30 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,10 @@
import { TLog, DateTimePreset } from '@tycrek/log';
import { TLog } from '@tycrek/log';
import { DateTime } from 'luxon';

// Set up logging
const logger = new TLog({
// @ts-ignore
level: process.env.LOG_LEVEL || (process.env.NODE_ENV === 'production' ? 'info' : 'debug'),
timestamp: {
enabled: true,
colour: 'grey',
preset: DateTimePreset.DATETIME_MED
}
});
const logger = new TLog(process.env.NODE_ENV === 'production' ? 'info' : 'debug')
.setTimestamp({ preset: DateTime.DATETIME_MED });

// Enable the Express logger
logger.enable.express({
middleware: {
excludePaths: ['favicon.ico'],
},
trim: {
enabled: true,
maxLength: 80,
delim: ': ',
},
handle404: true,
handle500: false
}).debug('Plugin enabled', 'Express');
// todo: re-enable the Express logger

/**
* @type {TLog}
*/
// yeet


export default logger;
export default logger;
2 changes: 1 addition & 1 deletion src/routers/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ router.post('/', (req: Request, res: Response, next: Function) => {
log.debug(`Sending${admin ? ' admin' : ''} embed to webhook`);
hook.addEmbed(embed).send()
.then(() => log.debug(`Webhook${admin ? ' admin' : ''} sent`))
.catch((err) => log.error('Webhook error').err(err));
.catch((err) => (log.error('Webhook error'), console.error(err)));
}

// Send the response
Expand Down
13 changes: 7 additions & 6 deletions src/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ function getConfirmSchema(description) {
// If directly called on the command line, run setup script
function doSetup() {
const path = (...paths) => require('path').join(process.cwd(), ...paths);
const { TLog, getChalk } = require('@tycrek/log');
const { TLog } = require('@tycrek/log');
const fs = require('fs-extra');
const prompt = require('prompt');
const chalk = require('chalk');
const token = require('./generators/token');

const log = new TLog({ level: 'debug', timestamp: { enabled: false } });
const log = new TLog('debug').setTimestamp({ enabled: false });

// Override default configs with existing configs to allow migrating configs
// Now that's a lot of configs!
Expand All @@ -85,7 +86,7 @@ function doSetup() {
Object.prototype.hasOwnProperty.call(oldConfig, key) && (oldConfig[key] = value); // skipcq: JS-0093
});
} catch (ex) {
if (ex.code !== 'MODULE_NOT_FOUND' && !ex.toString().includes('Unexpected end')) log.error(ex);
if (ex.code !== 'MODULE_NOT_FOUND' && !ex.toString().includes('Unexpected end')) log.error(`${ex}`);
}

// Disabled the annoying "prompt: " prefix and removes colours
Expand Down Expand Up @@ -294,15 +295,15 @@ function doSetup() {
// Verify information is correct
.then(() => log
.blank()
.info('Please verify your information', '\n'.concat(Object.entries(results).map(([setting, value]) => `${' '}${getChalk().dim.gray('-->')} ${getChalk().bold.white(`${setting}:`)} ${getChalk().white(value)}`).join('\n')))
.info('Please verify your information', '\n'.concat(Object.entries(results).map(([setting, value]) => `${' '}${chalk.dim.gray('-->')} ${chalk.bold.white(`${setting}:`)} ${chalk.white(value)}`).join('\n')))
.blank())

// Apply old configs
.then(() => Object.entries(oldConfig).forEach(([setting, value]) => (typeof results[setting] === 'undefined') && (results[setting] = value)))

// Confirm
.then(() => prompt.get(confirmSchema))
.then(({ confirm }) => (confirm ? fs.writeJson(path('config.json'), results, { spaces: 4 }) : log.error('Setup aborted').callback(process.exit, 1)))
.then(({ confirm }) => (confirm ? fs.writeJson(path('config.json'), results, { spaces: 4 }) : log.error('Setup aborted').callback(() => process.exit(1))))

// Other setup tasks
.then(() => {
Expand Down Expand Up @@ -334,7 +335,7 @@ function doSetup() {

// Complete & exit
.then(() => log.blank().success('Setup complete').callback(() => process.exit(0)))
.catch((err) => log.blank().error(err).callback(() => process.exit(1)));
.catch((err) => log.blank().callback(() => console.error(err)).callback(() => process.exit(1)));
}

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export function processUploaded(req: Request, res: Response, next: Function) { /
.callback(() => res.sendStatus(CODE_UNSUPPORTED_MEDIA_TYPE)))
.catch((err) => log
.error('Temp file could not be deleted', err)
.callback(next, err)));
.callback(() => next(err))));

// Remove unwanted fields
delete req.file.uuid;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/script.adduser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ if (process.argv.length < 4) {
const admin = process.argv[4] ? process.argv[4].toLowerCase() === 'true' : false;
const meta = process.argv[5] ? JSON.parse(process.argv[5]) : {};

axios.post(`http://localhost:${port}/api/user/new`, { username, password, admin, meta }, { headers: { 'Authorization': cliKey } })
axios.post(`http://localhost:${port}/api/user`, { username, password, admin, meta }, { headers: { 'Authorization': cliKey } })
.then((response) => {
const user = response.data as User;
logger.info('User created', username, user.unid).callback(() => process.exit(0))
Expand Down
1 change: 0 additions & 1 deletion src/types/tycrek.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
declare module './setup' {
export function doSetup(): void;
}
declare module '@tycrek/express-nofavicon';
declare module '@tycrek/papito';
declare module '@skynetlabs/skynet-nodejs';
3 changes: 2 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import gfyGen from './generators/gfycat';
import tsGen from './generators/timestamp';
import logger from './logger';
import { Request } from 'express';
import { isProd as ip } from '@tycrek/joint';
const { HTTP, HTTPS, KILOBYTES } = require('../MagicNumbers.json');

// Catch config.json not existing when running setup script
Expand Down Expand Up @@ -90,7 +91,7 @@ export function generateId(mode: string, length: number, gfyLength: number, orig
// Set up pathing
export const path = (...paths: string[]) => Path.join(process.cwd(), ...paths);

export const isProd = require('@tycrek/isprod')();
export const isProd = ip();
module.exports = {
path,
getTrueHttp,
Expand Down
2 changes: 1 addition & 1 deletion views/opengraph.pug
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
meta(property='og:title' content='ass - The superior self-hosted ShareX server')
meta(property='og:title' content='ass - The simple self-hosted ShareX server')
meta(property='og:type' content='website')
meta(property='og:url' content='https://github.com/tycrek/ass')
meta(property='og:description' content='ass is a self-hosted ShareX upload server written in Node.js')
Expand Down
2 changes: 1 addition & 1 deletion views/view.pug
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ html
br
span: a.link(href='#' onclick=`window.location = '${resourceAttr.src}?download=yes'; return false;` download=title) Download
if showAd
.mx-4.mb-8.text-footer.text-secondary: p Image hosted by #[a.link(href='https://github.com/tycrek/ass' target='_blank'): strong ass], the superior self-hosted ShareX server
.mx-4.mb-8.text-footer.text-secondary: p Image hosted by #[a.link(href='https://github.com/tycrek/ass' target='_blank'): strong ass], the simple self-hosted ShareX server

0 comments on commit 80f3858

Please sign in to comment.