🍑 ass 0.12.0 🍑

Merge branch 'better-custom-index'
pull/138/head releases/0.12.0
tycrek 2 years ago
commit 46678bd96f
No known key found for this signature in database
GPG Key ID: 25D74F3943625263

19
.github/README.md vendored

@ -295,12 +295,12 @@ If you want to customize the font or colours of the viewer page, create a file i
By default, ass directs the index route `/` to this README. Follow these steps to use a custom index:
1. Run `npm run setup` to re-run the setup script.
- The defaults are set by your existing config, so you can press `Enter` to accept the defaults on most prompts.
- The one setting you want to change is `Filename for your custom index`. Enter a name for your index, including `.js` (custom index's must be `.js` files).
2. Make a new file in the `share/` directory matching the name you entered (this directory can be found in the `ass/` directory. It is created automatically after setup is run).
3. Your index file needs to export a single function taking three arguments: `(req, res, next)`. Some code samples for common use cases are provided below.
4. Restart ass. The startup info logs should say **`Custom index:`**` enabled`.
1. Create a file in the `share/` directory called `index.html` or `index.js`.
- ass will treat `index.html` as an HTML file and will send it to the client.
- ass will treat `index.js` as a Node.js file that exports a function representing [Express middleware](https://expressjs.com/en/guide/using-middleware.html). ass will pass all handling of the index to this function. The function should take three arguments: `(req, res, next)`. Some code samples for common use cases are provided below.
- If both `index.html` and `index.js` are present, the `index.html` file will be served first.
2. Add whatever you want to the file.
3. Restart ass. The startup info logs should mention which file is being used as the index.
### Custom index code samples
@ -310,13 +310,6 @@ By default, ass directs the index route `/` to this README. Follow these steps t
module.exports = (req, res, next) => res.redirect('/register');
```
**Send an HTML file**
```js
const path = require('path');
module.exports = (req, res, next) => res.sendFile(path.join(__dirname, 'index.html'));
```
## File storage
ass supports three methods of file storage: local, S3, or [Skynet].

65
package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "ass",
"version": "0.11.0-rc.1",
"version": "0.12.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ass",
"version": "0.11.0-rc.1",
"version": "0.12.0",
"license": "ISC",
"dependencies": {
"@skynetlabs/skynet-nodejs": "^2.3.0",
@ -25,6 +25,7 @@
"discord-webhook-node": "^1.1.8",
"escape-html": "^1.0.3",
"express": "^4.17.3",
"express-brute": "^1.0.1",
"express-busboy": "^8.0.2",
"ffmpeg-static": "^4.4.0",
"fs-extra": "^10.0.1",
@ -46,6 +47,7 @@
"devDependencies": {
"@types/escape-html": "^1.0.1",
"@types/express": "^4.17.13",
"@types/express-brute": "^1.0.1",
"@types/express-busboy": "^8.0.0",
"@types/ffmpeg-static": "^3.0.0",
"@types/fs-extra": "^9.0.12",
@ -512,6 +514,15 @@
"@types/serve-static": "*"
}
},
"node_modules/@types/express-brute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/express-brute/-/express-brute-1.0.1.tgz",
"integrity": "sha512-rG4YWh+tIDvwupiPwuLaz0fEpFE7ShLOX59ZdejMQ4jYlshmxtN5KjB7VFGsggk4TmeVnoHF7QrwLwan2wj8cg==",
"dev": true,
"dependencies": {
"@types/express": "*"
}
},
"node_modules/@types/express-busboy": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@types/express-busboy/-/express-busboy-8.0.0.tgz",
@ -2131,6 +2142,18 @@
"node": ">= 0.10.0"
}
},
"node_modules/express-brute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/express-brute/-/express-brute-1.0.1.tgz",
"integrity": "sha512-ieZmwox3oIZdQCVjvvnwQvrKQumWdb/JjmC9mWplF42AuHCBXr6Yk/I+nLTRQx+9F+2aapOW9kYLwA6xIlwA9g==",
"dependencies": {
"long-timeout": "~0.1.1",
"underscore": "~1.8.3"
},
"peerDependencies": {
"express": "4.x"
}
},
"node_modules/express-busboy": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/express-busboy/-/express-busboy-8.0.2.tgz",
@ -2968,6 +2991,11 @@
"lodash._baseuniq": "~4.6.0"
}
},
"node_modules/long-timeout": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz",
"integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w=="
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -5204,6 +5232,11 @@
"node": ">=4.2.0"
}
},
"node_modules/underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg=="
},
"node_modules/universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@ -5859,6 +5892,15 @@
"@types/serve-static": "*"
}
},
"@types/express-brute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/express-brute/-/express-brute-1.0.1.tgz",
"integrity": "sha512-rG4YWh+tIDvwupiPwuLaz0fEpFE7ShLOX59ZdejMQ4jYlshmxtN5KjB7VFGsggk4TmeVnoHF7QrwLwan2wj8cg==",
"dev": true,
"requires": {
"@types/express": "*"
}
},
"@types/express-busboy": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@types/express-busboy/-/express-busboy-8.0.0.tgz",
@ -7128,6 +7170,15 @@
"vary": "~1.1.2"
}
},
"express-brute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/express-brute/-/express-brute-1.0.1.tgz",
"integrity": "sha512-ieZmwox3oIZdQCVjvvnwQvrKQumWdb/JjmC9mWplF42AuHCBXr6Yk/I+nLTRQx+9F+2aapOW9kYLwA6xIlwA9g==",
"requires": {
"long-timeout": "~0.1.1",
"underscore": "~1.8.3"
}
},
"express-busboy": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/express-busboy/-/express-busboy-8.0.2.tgz",
@ -7787,6 +7838,11 @@
"lodash._baseuniq": "~4.6.0"
}
},
"long-timeout": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz",
"integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w=="
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -9373,6 +9429,11 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz",
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw=="
},
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg=="
},
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",

@ -1,6 +1,6 @@
{
"name": "ass",
"version": "0.11.0-rc.1",
"version": "0.12.0",
"description": "The superior self-hosted ShareX server",
"main": "ass.js",
"engines": {
@ -54,6 +54,7 @@
"discord-webhook-node": "^1.1.8",
"escape-html": "^1.0.3",
"express": "^4.17.3",
"express-brute": "^1.0.1",
"express-busboy": "^8.0.2",
"ffmpeg-static": "^4.4.0",
"fs-extra": "^10.0.1",
@ -75,6 +76,7 @@
"devDependencies": {
"@types/escape-html": "^1.0.1",
"@types/express": "^4.17.13",
"@types/express-brute": "^1.0.1",
"@types/express-busboy": "^8.0.0",
"@types/ffmpeg-static": "^3.0.0",
"@types/fs-extra": "^9.0.12",

@ -23,7 +23,7 @@ if (!fs.existsSync(configPath) || fs.readFileSync(configPath).toString().length
//#endregion
// Load the JSON
const { host, port, useSsl, isProxied, s3enabled, frontendName, indexFile, useSia, diskFilePath }: Config = fs.readJsonSync(path('config.json'));
const { host, port, useSsl, isProxied, s3enabled, frontendName, useSia, diskFilePath }: Config = fs.readJsonSync(path('config.json'));
const { CODE_INTERNAL_SERVER_ERROR }: MagicNumbers = fs.readJsonSync(path('MagicNumbers.json'));
const { name, version, homepage }: Package = fs.readJsonSync(path('package.json'));
@ -58,6 +58,24 @@ app.disable('x-powered-by');
app.set('trust proxy', isProxied);
app.set('view engine', 'pug');
// Rate limiting using express-brute
// ! Notice !
// The rate limiting used here is very trivial and should be used with caution.
// I plan to improve this in the future somehow (possibly with redis, who knows).
// - tycrek, 2022-08-18
// todo: fix this eventually
import ExpressBrute from 'express-brute';
const bruteforce = new ExpressBrute(new ExpressBrute.MemoryStore(), {
freeRetries: 50,
minWait: 50, // 50ms
maxWait: 500, // 500ms
lifetime: 5, // 5 seconds
failCallback: (_req, res, _next, _nextValidRequestDate) => res.sendStatus(429),
});
// Routes to protect
app.get(['/'], bruteforce.prevent, (_req, _res, next) => next());
// Express logger middleware
app.use(log.middleware());
@ -73,11 +91,12 @@ useSsl && app.use(helmet.hsts({ preload: true })); // skipcq: JS-0093
app.use(nofavicon);
// Use custom index, otherwise render README.md
const ASS_INDEX = indexFile !== '' && fs.existsSync(path('share', indexFile)) && require(`../share/${indexFile}`);
const ASS_INDEX_ENABLED = typeof ASS_INDEX === typeof Function;
app.get('/', (req, res, next) => ASS_INDEX_ENABLED // skipcq: JS-0229
? ASS_INDEX(req, res, next)
: res.redirect(homepage));
type ASS_INDEX_TYPE = 'html' | 'js' | undefined;
const ASS_INDEX: ASS_INDEX_TYPE = fs.existsSync(path('share', 'index.html')) ? 'html' : fs.existsSync(path('share', 'index.js')) ? 'js' : undefined;
app.get('/', (req, res, next) =>
ASS_INDEX === 'html' ? res.sendFile(path('share', 'index.html')) :
ASS_INDEX === 'js' ? require(path('share', 'index.js'))(req, res, next) : // skipcq: JS-0359
res.redirect(homepage))
// Set up custom frontend
const ASS_FRONTEND = fs.existsSync(path(`./${frontendName}/package.json`)) ? (require('submodule'), require(`../${frontendName}`)) : { enabled: false };
@ -111,7 +130,7 @@ app.use((err: ErrWrap, _req: Request, res: Response) => log.error(err.message).e
.info('Files', `${data().size}`)
.info('Data engine', data().name, data().type)
.info('Frontend', ASS_FRONTEND.enabled ? ASS_FRONTEND.brand : 'disabled', `${ASS_FRONTEND.enabled ? `${getTrueHttp()}${getTrueDomain()}${ASS_FRONTEND.endpoint}` : ''}`)
.info('Custom index', ASS_INDEX_ENABLED ? `enabled` : 'disabled')
.info('Custom index', ASS_INDEX ?? 'disabled')
.blank()
.express()!.Host(app, port, host, () => log.success('Ready for uploads', `Storing resources ${s3enabled ? 'in S3' : useSia ? 'on Sia blockchain' : 'on disk'}`));
})();

@ -14,7 +14,6 @@ const config = {
viewDirect: false,
dataEngine: '@tycrek/papito',
frontendName: 'ass-x',
indexFile: '',
useSia: false,
s3enabled: false,
};
@ -173,12 +172,6 @@ function doSetup() {
default: config.frontendName,
required: false
},
indexFile: {
description: 'Filename for your custom index, if using one (must be a JS file)',
type: 'string',
default: config.indexFile,
required: false
},
useSia: {
description: 'Use Sia Skynet for decentralized file storage?',
type: 'boolean',

Loading…
Cancel
Save