Skip to content

Commit

Permalink
chore(): many changes and use nanoid
Browse files Browse the repository at this point in the history
  • Loading branch information
alexthemaster committed Jul 20, 2020
1 parent 99ea9d4 commit 9db3510
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 120 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# sharex-server (NodeJS)

## The easiest way to run this is to use Docker ([go here](./docker)). If you want to manually run it, continue reading!
## 🗒️ The easiest way to run sharex-server is to use our Docker solution ([which you can find here](https://github.com/authenticname/sharex-server/tree/master/docker)). If you want to manually run it, continue reading!


### Requirements
### ⚙️ Requirements
- [Node.js](https://nodejs.org/en)

### Usage
Expand All @@ -22,8 +22,11 @@ new Server({
- Enjoy

The password is to be set as a header;

The file form name is to be set to `image`;

The image uploading endpoint is /api/upload;

The upload endpoint returns a JSON with a URL link;

### ShareX - Custom uploader settings
Expand Down
2 changes: 1 addition & 1 deletion docker/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Configuration
First of all, `git clone` this repository.

After cloning, navigate to the folder and build the Docker image using: `docker build -t sharex-server .` (you only do this ONCE!)
After cloning, navigate to this folder and build the Docker image using: `docker build -t sharex-server .` (you only do this ONCE!)

After installation, you can simply run the following command to start the server: `docker run -d --env PASSWORD=somePassword --env UPLOADS_PATH=not/my/nudes --env LENGTH=10 -p 80:80 sharex-server`

Expand Down
92 changes: 16 additions & 76 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
"name": "sharex-server",
"version": "1.0.6",
"version": "1.1.0",
"description": "ShareX image hosting done with NodeJS",
"main": "src/index.js",
"files": [
"src"
],
"author": "Kovacs Alex <alex@atm.moe>",
"homepage": "https://github.com/authenticname/sharex-server#readme",
"repository": {
Expand All @@ -12,11 +15,17 @@
"bugs": {
"url": "https://github.com/authenticname/sharex-server/issues"
},
"keywords": ["sharex", "sharex-server", "sharex server", "sharex image hoster"],
"keywords": [
"sharex",
"sharex-server",
"sharex server",
"sharex image hoster"
],
"license": "MIT",
"dependencies": {
"express-fileupload": "^1.1.1-alpha.2",
"express-fileupload": "^1.1.6",
"fs-extra": "^7.0.1",
"nanoid": "^3.1.10",
"polka": "^0.5.2"
}
}
53 changes: 15 additions & 38 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ const polka = require('polka');
const fileUpload = require('express-fileupload');
const fs = require('fs-extra');
const path = require('path');
const nanoid = require('nanoid');

const formatREGEX = /\.(gif|jpg|jpeg|tiff|png)$/i;
const removerREGEX = /([-!$%^&*()_+|~=`{}\[\]:";'<>?,.@#])|^[\/]*|[\/]*$/g;

const middlewares = {
// Easy way to set a status of a response
status: function (req, res, next) {
status: function (_req, res, next) {
res.status = function (code) {
this.setHeader('status', code);
return this;
Expand All @@ -24,10 +26,10 @@ class Server {
/**
* @constructor
* @param {Object} config
* @param {String} config.password The password
* @param {String} config.path The path the uploads will be stored
* @param {Number} config.port The port the server will be running on
* @param {Number} config.fileLength The desired length of the file name
* @param {string} config.password The password
* @param {string} config.path The path the uploads will be stored
* @param {number} config.port The port the server will be running on
* @param {number} config.fileLength The desired length of the file name
*/
constructor(config = { password: "1234", path: "uploads", port: 6060, fileLength: 10 }) {
this._password = config.password;
Expand All @@ -41,13 +43,10 @@ class Server {
this._init()
}

/**
* @private
*/
/** @private */
async _init() {
// Make sure the directory the uploads will go in exists
await fs.ensureDir(this._folder + this._path)


// Server setup
this._server = polka();
Expand All @@ -58,9 +57,7 @@ class Server {
this._routes();
}

/**
* @private
*/
/** @private */
_routes() {

// Serve the image, if it exists
Expand All @@ -71,8 +68,10 @@ class Server {
if (!exists) return res.status(404).end('Image not found');

const [, format] = formatREGEX.exec(req.params.img);

if (format === 'gif') res.writeHead(200, { "Content-Type": "image/gif" });
else res.writeHead(200, { "Content-Type": "image/png" });

return fs.createReadStream(this._folder + this._path + req.params.img).pipe(res);
});

Expand All @@ -84,7 +83,7 @@ class Server {
if (!req.files.image || !formatREGEX.test(req.files.image.name)) return res.status(403).end('Please provide a valid image.');

// Generate a string
const string = await this.string(this._fileLength).catch(error => { throw new Error(error) });
const string = await nanoid(10);

const [, type] = formatREGEX.exec(req.files.image.name);

Expand All @@ -103,36 +102,14 @@ class Server {

/**
* Parse the path to work with the server (remove additional slash characters / symbols)
* @param {String} path
* @returns {String}
* @param {string} path
* @returns {string}
* @example "/uploads/images/"
*/
parsePath(path) {
const removerRegex = /([-!$%^&*()_+|~=`{}\[\]:";'<>?,.@#])|^[\/]*|[\/]*$/g;
path = path.replace(removerRegex, '');
path = path.replace(removerREGEX, '');
return `/${path}${!path.length ? '' : '/'}`;
}

/**
* Generate a random string to use for the file name
* @param {Number} length The desired length of the file
* @returns {Promise<String | Error>}
*/
async string(length = 10, tries = 0) {
if (tries >= 100) throw 'Tried 100 string combinations for a file, but all of them are already taken. I suggest cleaning older images!';

const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split('');
let final = '';

for (let i = 0; i < length; i++) {
final += possible[Math.floor(Math.random() * possible.length)]
}

const exists = await fs.exists(`${this._folder}${this._path}${final}.png`);
if (exists) return this.string(length, ++tries);

return final;
}
}

module.exports = Server;

0 comments on commit 9db3510

Please sign in to comment.