first push

This commit is contained in:
2025-10-13 18:09:01 +02:00
parent aa38e520f0
commit 2e59c1f5e7
19 changed files with 1719 additions and 1 deletions

22
.gitignore vendored Normal file
View File

@@ -0,0 +1,22 @@
# IDE (IntelliJ IDEA)
.idea
HastebinPlus.iml
# IDE (Microsoft Visual Studio)
obj/
Microsoft.NodejsTools.WebRole.dll
.ntvs_analysis.dat
*.njsproj
*.sln
*.suo
# Application
data
node_modules
*.min.css
*.min.js
!jquery.min.js
!highlight.min.js
# NodeJS
npm-debug.log

View File

@@ -1 +1,65 @@
# unknownbin
# Hastebin Plus
Hastebin Plus is an open-source Pastebin software written in node.js, which is easily installable in any network.
It bases upon [haste](https://github.com/seejohnrun/haste-server) and got enhanced in matters of **Design, Speed and Simplicity**.
## Features
* Paste code, logs and ... almost everything!
* Syntax-Highlighting
* Add static documents
* Duplicate & edit pastes
* Raw paste-view
## Installation
[![Deploy to Heroku](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/MarvinMenzerath/HastebinPlus)
1. Install Git and node.js: `sudo apt-get install git nodejs`
2. Clone this repository: `git clone https://github.com/MarvinMenzerath/HastebinPlus.git hastebin-plus`
3. Open `config.json` and change the settings (if you want to)
4. Install dependencies: `npm install`
5. Start the application: `npm start`
## Update
1. Pull changes from this repository: `git pull`
2. Install new dependencies: `npm install`
## Settings
| Key | Description | Default value |
| ---------------------- | ----------------------------------------------- | ------------- |
| `host` | The host the server runs on | `0.0.0.0` |
| `port` | The port the server runs on | `8080` |
| `dataPath` | The directory where all pastes are stored | `./data` |
| `keyLength` | The length of the pastes' key | `10` |
| `maxLength` | Maximum chars in a paste | `500000` |
| `createKey` | Needs to be in front of paste to allow creation | ` ` |
| `documents` | Static documents to serve | See below |
### Default Config
```json
{
"host": "0.0.0.0",
"port": 8080,
"dataPath": "./data",
"keyLength": 10,
"maxLength": 500000,
"createKey": "",
"documents": {
"about": "./README.md",
"javaTest": "./documents/test.java"
}
}
```
## Authors
* [haste](https://github.com/seejohnrun/haste-server): John Crepezzi - MIT License
* [jQuery](https://github.com/jquery/jquery): MIT License
* [highlight.js](https://github.com/isagalaev/highlight.js): Ivan Sagalaev - [License](https://github.com/isagalaev/highlight.js/blob/master/LICENSE)
* [Application Icon](https://www.iconfinder.com/icons/285631/notepad_icon): [Paomedia](https://www.iconfinder.com/paomedia) - [CC BY 3.0 License](http://creativecommons.org/licenses/by/3.0/)
## License
Copyright (c) 2014-2016 Marvin Menzerath
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

15
app.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "unknownBIN",
"description": "unknownBIN is an open-source Pastebin software written in node.js.",
"repository": "https://github.com/MrUnknownDE/unknownbin",
"logo": "https://raw.githubusercontent.com/MarvinMenzerath/HastebinPlus/master/static/favicon.png",
"keywords": [
"node",
"paste",
"pastebin",
"haste",
"hastebin",
"code",
"syntax highlighting"
]
}

12
config.json Normal file
View File

@@ -0,0 +1,12 @@
{
"host": "0.0.0.0",
"port": 8080,
"dataPath": "./data",
"keyLength": 10,
"maxLength": 500000,
"createKey": "",
"documents": {
"about": "./README.md",
"javaTest": "./documents/test.java"
}
}

48
documents/test.java Normal file
View File

@@ -0,0 +1,48 @@
public class Dancer {
private static final String VERSION = "1.2.4.3 Beta 2";
private String name;
private int age;
private int moves;
public static void main(String[] args) {
System.out.println("Welcome to DANCE-MASTER 3000 v" + VERSION + "!");
System.out.println("Creating and testing your Dancers. Please be patient...!");
Dancer hugo = new Dancer("Hugo", 34, 6);
Dancer mike = new Dancer("Mike", 81, 2);
Dancer nori = new Dancer("Nori", 22, 27);
Dancer john = new Dancer("John", 4, 1);
Dancer rony = new Dancer("Rony", 42, 24); // WTF is this name?
System.out.println("Goodbye!");
System.exit(0);
}
public Dancer(String name, int age, int moves) {
// Save the values
this.name = name;
this.age = age;
this.moves = moves;
// Welcome our new Dancer
System.out.println("Welcome, " + name + "!");
boolean goodDancer = dance(); // Let's go!
}
/**
* Here the Dancer has to dance.
* This is not possible for everyone...
*
* @return whether the Dancer is a good Dancer or not
*/
private boolean dance() {
if (age > 6 && age < 70 && moves > 5) {
System.out.println("YEAH! THIS ROCKS!!!");
return true;
} else {
System.out.println("Dude... Move on!");
return false;
}
}
}

118
lib/document_handler.js Normal file
View File

@@ -0,0 +1,118 @@
var logger = require('winston');
var KeyGenerator = require('./key_generator.js');
// handles creating new and requesting existing documents
var DocumentHandler = function(options) {
if (!options) {
options = {};
}
this.store = options.store;
this.maxLength = options.maxLength || 50000;
this.keyLength = options.keyLength || 10;
this.createKey = options.createKey || '';
this.keyGenerator = new KeyGenerator();
if (this.createKey !== '') {
logger.info("Creation-Key:", this.createKey);
}
};
// handles existing documents
DocumentHandler.prototype.handleGet = function(key, res) {
this.store.get(key, function(ret) {
if (ret) {
logger.verbose('Open paste:', key);
res.writeHead(200, {'content-type': 'application/json'});
res.end(JSON.stringify({key: key, data: ret.replace(/\t/g, ' ')}));
} else {
logger.verbose('Paste not found:', key);
res.writeHead(404, {'content-type': 'application/json'});
res.end(JSON.stringify({message: 'Paste not found.'}));
}
});
};
// handles exisiting documents (raw)
DocumentHandler.prototype.handleRawGet = function(key, res) {
this.store.get(key, function(ret) {
if (ret) {
logger.verbose('Open paste:', key);
res.writeHead(200, {'content-type': 'text/plain'});
res.end(ret);
} else {
logger.verbose('Paste not found:', key);
res.writeHead(404, {'content-type': 'application/json'});
res.end(JSON.stringify({message: 'Paste not found.'}));
}
});
};
// handles creating new documents
DocumentHandler.prototype.handlePost = function(req, res) {
var _this = this;
var buffer = '';
var cancelled = false;
req.on('data', function(data) {
if (cancelled) return;
buffer += data.toString();
if (_this.maxLength && buffer.length > _this.maxLength) {
cancelled = true;
logger.warn('Paste exeeds maximum length.');
res.writeHead(400, {'content-type': 'application/json'});
res.end(JSON.stringify({message: 'Paste exceeds maximum length.'}));
}
});
req.on('end', function() {
if (cancelled) return;
if (_this.createKey !== '') {
if (!buffer.startsWith(_this.createKey)) {
logger.warn('Error adding new paste: wrong key');
res.writeHead(400, {'content-type': 'application/json'});
res.end(JSON.stringify({message: 'Error adding new paste: wrong key'}));
return;
}
buffer = buffer.substring(_this.createKey.length);
}
_this.chooseKey(function(key) {
_this.store.set(key, buffer, function(success) {
if (success) {
logger.verbose('New paste:', key);
res.writeHead(200, {'content-type': 'application/json'});
res.end(JSON.stringify({key: key}));
} else {
logger.warn('Error adding new paste.');
res.writeHead(500, {'content-type': 'application/json'});
res.end(JSON.stringify({message: 'Error adding new paste.'}));
}
});
});
});
req.on('error', function(error) {
logger.error('Connection error: ' + error.message);
res.writeHead(500, {'content-type': 'application/json'});
res.end(JSON.stringify({message: 'Connection error.'}));
});
};
// creates new keys until one is not taken
DocumentHandler.prototype.chooseKey = function(callback) {
var key = this.acceptableKey();
var _this = this;
this.store.get(key, function(success) {
if (success) {
_this.chooseKey(callback);
} else {
callback(key);
}
});
};
// creates a new key using the key-generator
DocumentHandler.prototype.acceptableKey = function() {
return this.keyGenerator.createKey(this.keyLength);
};
module.exports = DocumentHandler;

38
lib/file_storage.js Normal file
View File

@@ -0,0 +1,38 @@
var fs = require('fs');
var crypto = require('crypto');
var logger = require('winston');
// handles saving and retrieving all documents
var FileDocumentStore = function(options) {
this.basePath = options.path || './data';
logger.info('Path to data: ' + this.basePath);
};
// saves a new file to the filesystem
FileDocumentStore.prototype.set = function(key, data, callback) {
var _this = this;
fs.mkdir(this.basePath, '700', function(err) {
fs.writeFile(_this.basePath + '/' + key, data, 'utf8', function(err) {
if (err) {
callback(false);
} else {
callback(true);
}
});
});
};
// gets an exisiting file from the filesystem
FileDocumentStore.prototype.get = function(key, callback) {
var _this = this;
fs.readFile(this.basePath + '/' + key, 'utf8', function(err, data) {
if (err) {
callback(false);
} else {
callback(data);
}
});
};
module.exports = FileDocumentStore;

15
lib/key_generator.js Normal file
View File

@@ -0,0 +1,15 @@
var KeyGenerator = function() {
this.keyspace = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
};
KeyGenerator.prototype.createKey = function(keyLength) {
var key = '';
var index;
for (var i = 0; i < keyLength; i++) {
index = Math.floor(Math.random() * this.keyspace.length);
key += this.keyspace.charAt(index);
}
return key;
};
module.exports = KeyGenerator;

757
package-lock.json generated Normal file
View File

@@ -0,0 +1,757 @@
{
"name": "unknownBIN",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "unknownBIN",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"clean-css": "~3.4.19",
"express": "~4.14.0",
"uglify-js": "~2.7.0",
"winston": "~2.2.0"
}
},
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
"license": "MIT",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/align-text": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
"integrity": "sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==",
"license": "MIT",
"dependencies": {
"kind-of": "^3.0.2",
"longest": "^1.0.1",
"repeat-string": "^1.5.2"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==",
"license": "BSD-3-Clause OR MIT",
"engines": {
"node": ">=0.4.2"
}
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT"
},
"node_modules/async": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
},
"node_modules/camelcase": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
"integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/center-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
"integrity": "sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==",
"license": "MIT",
"dependencies": {
"align-text": "^0.1.3",
"lazy-cache": "^1.0.3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/clean-css": {
"version": "3.4.28",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz",
"integrity": "sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw==",
"license": "MIT",
"dependencies": {
"commander": "2.8.x",
"source-map": "0.4.x"
},
"bin": {
"cleancss": "bin/cleancss"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cliui": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
"integrity": "sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA==",
"license": "ISC",
"dependencies": {
"center-align": "^0.1.1",
"right-align": "^0.1.1",
"wordwrap": "0.0.2"
}
},
"node_modules/colors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
"integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
"license": "MIT",
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/commander": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==",
"license": "MIT",
"dependencies": {
"graceful-readlink": ">= 1.0.0"
},
"engines": {
"node": ">= 0.6.x"
}
},
"node_modules/content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
"integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"license": "MIT"
},
"node_modules/cycle": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
"integrity": "sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/debug": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
"integrity": "sha512-X0rGvJcskG1c3TgSCPqHJ0XJgwlcvOC7elJ5Y0hYuKBZoVqWpAMfLOeIh2UI/DCQ5ruodIjvsugZtjUYUw2pUw==",
"license": "MIT",
"dependencies": {
"ms": "0.7.1"
}
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==",
"license": "MIT"
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/etag": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz",
"integrity": "sha512-Mbv5pNpLNPrm1b4rzZlZlfTRpdDr31oiD43N362sIyvSWVNu5Du33EcJGzvEV4YdYLuENB1HzND907cQkFmXNw==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express": {
"version": "4.14.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.14.1.tgz",
"integrity": "sha512-aL+R5JmMN85tiMiWNx3wge9k3hjqezh530Nbc36kJezDZO8hkK+LBaaFvv9wziPiigK6vCubJ+omjQyqt8keYw==",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.3",
"array-flatten": "1.1.1",
"content-disposition": "0.5.2",
"content-type": "~1.0.2",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "~2.2.0",
"depd": "~1.1.0",
"encodeurl": "~1.0.1",
"escape-html": "~1.0.3",
"etag": "~1.7.0",
"finalhandler": "0.5.1",
"fresh": "0.3.0",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.1",
"path-to-regexp": "0.1.7",
"proxy-addr": "~1.1.3",
"qs": "6.2.0",
"range-parser": "~1.2.0",
"send": "0.14.2",
"serve-static": "~1.11.2",
"type-is": "~1.6.14",
"utils-merge": "1.0.0",
"vary": "~1.1.0"
},
"engines": {
"node": ">= 0.10.0"
}
},
"node_modules/eyes": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
"integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==",
"engines": {
"node": "> 0.1.90"
}
},
"node_modules/finalhandler": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.1.tgz",
"integrity": "sha512-PYuh1UzGGCOoRvrbGYCq6memvx41rxMCr+0XT9NtiIWqGG7hbCBcPMBRQoi5sMZDzTOxwiuv7/gwPtrDOz76CQ==",
"license": "MIT",
"dependencies": {
"debug": "~2.2.0",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"statuses": "~1.3.1",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha512-Ua9xNhH0b8pwE3yRbFfXJvfdWF0UHNCdeyb2sbi9Ul/M+r3PTdrz7Cv4SCfZRMjmzEM9PhraqfZFbGTIg3OMyA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz",
"integrity": "sha512-akx5WBKAwMSg36qoHTuMMVncHWctlaDGslJASDYAhoLrzDUDCjZlOngNa/iC6lPm9aA0qk8pN5KnpmbJHSIIQQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==",
"license": "MIT"
},
"node_modules/http-errors": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"integrity": "sha512-ftkc2U5ADKHv8Ny1QJaDn8xnE18G+fP5QYupx9c3Xk6L5Vgo3qK8Bgbpb4a+jRtaF/YQKjIuXA5J0tde4Tojng==",
"license": "MIT",
"dependencies": {
"inherits": "2.0.3",
"setprototypeof": "1.0.2",
"statuses": ">= 1.3.1 < 2"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
"license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz",
"integrity": "sha512-RbrsPoo4IkisyHhS9VDa3ybxnu0wOo0uTAhaELmwxq244p18X7Dk0fQoJvh/QTkIUO296fbjgvMqK3ry84eVVA==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"license": "MIT"
},
"node_modules/isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
"license": "MIT"
},
"node_modules/kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
"license": "MIT",
"dependencies": {
"is-buffer": "^1.1.5"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lazy-cache": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
"integrity": "sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/longest": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
"integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
"license": "MIT"
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
"integrity": "sha512-sAaYXszED5ALBt665F0wMQCUXpGuZsGdopoqcHPdL39ZYdi7uHoZlhrfZfhv8WzivhBzr/oXwaj+yiK5wY8MXQ==",
"bin": {
"mime": "cli.js"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
"integrity": "sha512-lRLiIR9fSNpnP6TC4v8+4OU7oStC01esuNowdQ34L+Gk8e5Puoc88IqJ+XAY/B3Mn2ZKis8l8HX90oU8ivzUHg=="
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
"license": "MIT"
},
"node_modules/pkginfo": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
"integrity": "sha512-yO5feByMzAp96LtP58wvPKSbaKAi/1C4kV9XpTctr6EepnP6F33RBNOiVrdz9BrPA98U2BMFsTNHo44TWcbQ2A==",
"license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/proxy-addr": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
"integrity": "sha512-av1MQ5vwTiMICwU75KSf/vJ6a+AXP0MtP+aYBqm2RFlire7BP6sWlfOLc8+6wIQrywycqSpJWm5zNkYFkRARWA==",
"license": "MIT",
"dependencies": {
"forwarded": "~0.1.0",
"ipaddr.js": "1.4.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/qs": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.2.0.tgz",
"integrity": "sha512-xJlDcRyZKEdvI99YhwNqGKmeiOCcfxk5E09Gof/E8xSpiMcqJ+BCwPZ3ykEYQdwDlmTpK6YlPB/kd8zfy9e7wg==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.6"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
"license": "MIT",
"engines": {
"node": ">=0.10"
}
},
"node_modules/right-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
"integrity": "sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg==",
"license": "MIT",
"dependencies": {
"align-text": "^0.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/send": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.14.2.tgz",
"integrity": "sha512-36O39SV4A6lj4TBALc0tAMmiTwClC2Npp6wiRvzxqyrH3yTiYwAmWVyB2a0a/D3ISCQVHY/l+VO/9JVo6ZubfA==",
"license": "MIT",
"dependencies": {
"debug": "~2.2.0",
"depd": "~1.1.0",
"destroy": "~1.0.4",
"encodeurl": "~1.0.1",
"escape-html": "~1.0.3",
"etag": "~1.7.0",
"fresh": "0.3.0",
"http-errors": "~1.5.1",
"mime": "1.3.4",
"ms": "0.7.2",
"on-finished": "~2.3.0",
"range-parser": "~1.2.0",
"statuses": "~1.3.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/send/node_modules/ms": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"integrity": "sha512-5NnE67nQSQDJHVahPJna1PQ/zCXMnQop3yUCxjKPNzCxuyPSKWTQ/5Gu5CZmjetwGLWRA+PzeF5thlbOdbQldA==",
"license": "MIT"
},
"node_modules/serve-static": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.11.2.tgz",
"integrity": "sha512-nBt9IVflCqc4pEtjttEgnwUJXBdy8xk0yZm16OomALNUKVa0S4X6pupZm/92j7M1AbPrC1WYkjr6HjtLeHnsAg==",
"license": "MIT",
"dependencies": {
"encodeurl": "~1.0.1",
"escape-html": "~1.0.3",
"parseurl": "~1.3.1",
"send": "0.14.2"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/setprototypeof": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"integrity": "sha512-mNRSo7UFE4c4tjxlZ3KxO5r+3oQUD1M/KXbp/XTwTwybL4VR9T8Ltmv5DvZX8iRz6C3hQmQftXEV0EmTKRV6mg==",
"license": "ISC"
},
"node_modules/source-map": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==",
"license": "BSD-3-Clause",
"dependencies": {
"amdefine": ">=0.0.4"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/stack-trace": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
"integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/statuses": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"integrity": "sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"license": "MIT",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/uglify-js": {
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz",
"integrity": "sha512-RvbIYn4DIadCg1MV7YP7OrpxnVrtEieZzbK0KSQvwWGAHojqWJxInkQhmtYGRo9PTwwkJkljIgzMyA1VitEc4Q==",
"license": "BSD-2-Clause",
"dependencies": {
"async": "~0.2.6",
"source-map": "~0.5.1",
"uglify-to-browserify": "~1.0.0",
"yargs": "~3.10.0"
},
"bin": {
"uglifyjs": "bin/uglifyjs"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/uglify-js/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/uglify-to-browserify": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
"integrity": "sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q==",
"license": "MIT"
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/utils-merge": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
"integrity": "sha512-HwU9SLQEtyo+0uoKXd1nkLqigUWLB+QuNQR4OcmB73eWqksM5ovuqcycks2x043W8XVb75rG1HQ0h93TMXkzQQ==",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/window-size": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
"integrity": "sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==",
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/winston": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/winston/-/winston-2.2.0.tgz",
"integrity": "sha512-uWxlDhugkqGPbxxn3aWL0VZe3b3Ht8J0s1TzqYyt6TgC84xgUs2e47u2v6SYZGAaRrTZzuCYkdOEuL9KrfYuJQ==",
"license": "MIT",
"dependencies": {
"async": "~1.0.0",
"colors": "1.0.x",
"cycle": "1.0.x",
"eyes": "0.1.x",
"isstream": "0.1.x",
"pkginfo": "0.3.x",
"stack-trace": "0.0.x"
},
"engines": {
"node": ">= 0.10.0"
}
},
"node_modules/winston/node_modules/async": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
"integrity": "sha512-5mO7DX4CbJzp9zjaFXusQQ4tzKJARjNB1Ih1pVBi8wkbmXy/xzIDgEMXxWePLzt2OdFwaxfneIlT1nCiXubrPQ==",
"license": "MIT"
},
"node_modules/wordwrap": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
"integrity": "sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==",
"license": "MIT/X11",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/yargs": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
"integrity": "sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A==",
"license": "MIT",
"dependencies": {
"camelcase": "^1.0.2",
"cliui": "^2.1.0",
"decamelize": "^1.0.0",
"window-size": "0.1.0"
}
}
}
}

29
package.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "unknownBIN",
"version": "1.0.0",
"private": true,
"description": "unknownBIN is an open-source Pastebin software written in node.js.",
"keywords": [
"paste",
"pastebin",
"haste",
"hastebin",
"code",
"syntax highlighting"
],
"author": {
"name": "MrUnknownDE",
"email": "me@mrunk.de",
"url": "https://mrunk.de/"
},
"license": "MIT",
"dependencies": {
"clean-css": "~3.4.19",
"express": "~4.14.0",
"uglify-js": "~2.7.0",
"winston": "~2.2.0"
},
"scripts": {
"start": "node ./server.js"
}
}

81
server.js Normal file
View File

@@ -0,0 +1,81 @@
var http = require('http');
var url = require('url');
var fs = require('fs');
var express = require('express');
var logger = require('winston');
var DocumentHandler = require('./lib/document_handler.js');
var FileStorage = require('./lib/file_storage.js');
// load configuration
var config = JSON.parse(fs.readFileSync(__dirname + '/config.json', 'utf8'));
config.port = process.env.PORT || config.port || 8080;
config.host = process.env.HOST || config.host || 'localhost';
// logger-setup
logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, {colorize: true, level: 'verbose'});
logger.info('Welcome to Hastebin Plus!');
// init file-storage
var fileStorage = new FileStorage(config.dataPath);
// load static documents into file-storage
for (var name in config.documents) {
var path = config.documents[name];
var data = fs.readFileSync(path, 'utf8');
if (data) {
fileStorage.set(name, data, function(success) {});
logger.verbose('Created document: ' + name + " ==> " + path);
} else {
logger.warn('Unable to find document: ' + name + " ==> " + path);
}
}
// configure the document handler
var documentHandler = new DocumentHandler({
store: fileStorage,
maxLength: config.maxLength,
keyLength: config.keyLength,
createKey: config.createKey
});
// compress static assets
var cssCompressor = require('clean-css');
var jsCompressor = require('uglify-js');
var files = fs.readdirSync(__dirname + '/static');
for (var i = 0; i < files.length; i++) {
var item = files[i];
var dest = "";
if ((item.indexOf('.css') === item.length - 4) && (item.indexOf('.min.css') === -1)) {
dest = item.substring(0, item.length - 4) + '.min.css';
fs.writeFileSync(__dirname + '/static/' + dest, new cssCompressor().minify(fs.readFileSync(__dirname + '/static/' + item, 'utf8')).styles, 'utf8');
logger.verbose('Compressed: ' + item + ' ==> ' + dest);
} else if ((item.indexOf('.js') === item.length - 3) && (item.indexOf('.min.js') === -1)) {
dest = item.substring(0, item.length - 3) + '.min.js';
fs.writeFileSync(__dirname + '/static/' + dest, jsCompressor.minify(__dirname + '/static/' + item).code, 'utf8');
logger.verbose('Compressed: ' + item + ' ==> ' + dest);
}
}
// setup routes and request-handling
var app = express();
app.get('/raw/:id', function(req, res) {
return documentHandler.handleRawGet(req.params.id, res);
});
app.post('/documents', function(req, res) {
return documentHandler.handlePost(req, res);
});
app.get('/documents/:id', function(req, res) {
return documentHandler.handleGet(req.params.id, res);
});
app.use(express.static('static'));
app.get('/:id', function(req, res, next) {
res.sendFile(__dirname + '/static/index.html');
});
app.listen(config.port, config.host);
logger.info('Listening on ' + config.host + ':' + config.port);

136
static/application.css Normal file
View File

@@ -0,0 +1,136 @@
html {
height: 100%;
}
body {
background: #002B36;
height: 90%;
margin: 0;
padding: 1em;
}
#content {
height: 100%;
padding: 0;
}
textarea {
background: transparent;
border: 0;
color: #fff;
font-family: monospace;
font-size: 1em;
height: 100%;
outline: none;
padding: 0;
resize: none;
width: 100%;
}
#code {
border: 0;
font-size: 1em;
margin: 0;
outline: none;
padding: 0 0 4em 0;
white-space: pre-wrap;
}
#code code {
background: transparent !important;
padding: 0;
}
pre {
counter-reset: line-numbering;
}
pre .line::before {
color: #4c6a71;
content: counter(line-numbering);
counter-increment: line-numbering;
display: inline-block;
margin-right: 1em;
text-align: right;
width: 1.5em !important;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#tools {
background: #08323c;
bottom: 0;
font-size: 0;
left: 0;
position: fixed;
width: 100%;
}
#tools .function {
background: url(function-icons.png);
display: inline-block;
height: 37px;
position: relative;
width: 32px;
}
#tools .link embed {
vertical-align: bottom;
}
#tools .function.enabled:hover {
cursor: pointer;
}
#tools .function.save {
background-position: -5px top;
}
#tools .function.enabled.save {
background-position: -5px center;
}
#tools .function.enabled.save:hover {
background-position: -5px bottom;
}
#tools .function.new {
background-position: -42px top;
}
#tools .function.enabled.new {
background-position: -42px center;
}
#tools .function.enabled.new:hover {
background-position: -42px bottom;
}
#tools .function.duplicate {
background-position: -79px top;
}
#tools .function.enabled.duplicate {
background-position: -79px center;
}
#tools .function.enabled.duplicate:hover {
background-position: -79px bottom;
}
#tools .function.raw {
background-position: -116px top;
}
#tools .function.enabled.raw {
background-position: -116px center;
}
#tools .function.enabled.raw:hover {
background-position: -116px bottom;
}

268
static/application.js Normal file
View File

@@ -0,0 +1,268 @@
// represents the haste-application
var haste = function() {
this.appName = "Hastebin Plus";
this.$textarea = $('textarea');
this.$box = $('#code');
this.$code = $('#code code');
this.configureShortcuts();
this.configureButtons();
};
// set title (browser window)
haste.prototype.setTitle = function(ext) {
var title = ext ? this.appName + ' - ' + ext : this.appName;
document.title = title;
};
// show the light key
haste.prototype.lightKey = function() {
this.configureKey(['new', 'save']);
};
// show the full key
haste.prototype.fullKey = function() {
this.configureKey(['new', 'duplicate', 'raw']);
};
// enable certain keys
haste.prototype.configureKey = function(enable) {
$('#tools .function').each(function() {
var $this = $(this);
for (var i = 0; i < enable.length; i++) {
if ($this.hasClass(enable[i])) {
$this.addClass('enabled');
return true;
}
}
$this.removeClass('enabled');
});
};
// setup a new, blank document
haste.prototype.newDocument = function(hideHistory) {
this.$box.hide();
this.doc = new haste_document();
if (!hideHistory) {
window.history.pushState(null, this.appName, '/');
}
this.setTitle();
this.lightKey();
this.$textarea.val('').show('fast', function() {
this.focus();
});
};
// load an existing document
haste.prototype.loadDocument = function(key) {
var _this = this;
_this.doc = new haste_document();
_this.doc.load(key, function(ret) {
if (ret) {
_this.$code.html(ret.value);
_this.setTitle(ret.key);
window.history.pushState(null, _this.appName + '-' + ret.key, '/' + ret.key);
_this.fullKey();
_this.$textarea.val('').hide();
_this.$box.show();
} else {
_this.newDocument();
}
});
};
// duplicate the current document
haste.prototype.duplicateDocument = function() {
if (this.doc.locked) {
var currentData = this.doc.data;
this.newDocument();
this.$textarea.val(currentData);
}
};
// lock the current document
haste.prototype.lockDocument = function() {
var _this = this;
this.doc.save(this.$textarea.val(), function(err, ret) {
if (!err && ret) {
_this.$code.html(ret.value.trim().replace(/.+/g, "<span class=\"line\">$&</span>").replace(/^\s*[\r\n]/gm, "<span class=\"line\"></span>\n"));
_this.setTitle(ret.key);
window.history.pushState(null, _this.appName + '-' + ret.key, '/' + ret.key);
_this.fullKey();
_this.$textarea.val('').hide();
_this.$box.show();
}
});
};
// configure buttons and their shortcuts
haste.prototype.configureButtons = function() {
var _this = this;
this.buttons = [
{
$where: $('#tools .save'),
shortcut: function(evt) {
return evt.ctrlKey && evt.keyCode === 83;
},
action: function() {
if (_this.$textarea.val().replace(/^\s+|\s+$/g, '') !== '') {
_this.lockDocument();
}
}
},
{
$where: $('#tools .new'),
shortcut: function(evt) {
return evt.ctrlKey && evt.keyCode === 32;
},
action: function() {
_this.newDocument(!_this.doc.key);
}
},
{
$where: $('#tools .duplicate'),
shortcut: function(evt) {
return _this.doc.locked && evt.ctrlKey && evt.keyCode === 68;
},
action: function() {
_this.duplicateDocument();
}
},
{
$where: $('#tools .raw'),
shortcut: function(evt) {
return evt.ctrlKey && evt.shiftKey && evt.keyCode === 82;
},
action: function() {
window.location.href = '/raw/' + _this.doc.key;
}
}
];
for (var i = 0; i < this.buttons.length; i++) {
this.configureButton(this.buttons[i]);
}
};
// handles the button-click
haste.prototype.configureButton = function(options) {
options.$where.click(function(evt) {
evt.preventDefault();
if (!options.clickDisabled && $(this).hasClass('enabled')) {
options.action();
}
});
};
// enables the configured shortcuts
haste.prototype.configureShortcuts = function() {
var _this = this;
$(document.body).keydown(function(evt) {
var button;
for (var i = 0; i < _this.buttons.length; i++) {
button = _this.buttons[i];
if (button.shortcut && button.shortcut(evt)) {
evt.preventDefault();
button.action();
return;
}
}
});
};
// represents a single document
var haste_document = function() {
this.locked = false;
};
// escape HTML-characters
haste_document.prototype.htmlEscape = function(s) {
return s
.replace(/&/g, '&amp;')
.replace(/>/g, '&gt;')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;');
};
// load a document from the server
haste_document.prototype.load = function(key, callback) {
var _this = this;
$.ajax('/documents/' + key, {
type: 'get',
dataType: 'json',
success: function(res) {
_this.locked = true;
_this.key = key;
_this.data = res.data;
high = hljs.highlightAuto(res.data).value;
callback({
value: high.replace(/.+/g, "<span class=\"line\">$&</span>").replace(/^\s*[\r\n]/gm, "<span class=\"line\"></span>\n"),
key: key,
});
},
error: function(err) {
callback(false);
}
});
};
// sends the document to the server
haste_document.prototype.save = function(data, callback) {
if (this.locked) return false;
this.data = data;
var _this = this;
$.ajax('/documents', {
type: 'post',
data: data.trim(),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function(res) {
new haste().loadDocument(res.key);
},
error: function(res) {
try {
callback($.parseJSON(res.responseText));
} catch (e) {
callback({message: 'Something went wrong!'});
}
}
});
};
// after page is loaded
$(function() {
$('textarea').keydown(function(evt) {
// allow usage of tabs
if (evt.keyCode === 9) {
evt.preventDefault();
var myValue = ' ';
if (document.selection) {
this.focus();
sel = document.selection.createRange();
sel.text = myValue;
this.focus();
} else if (this.selectionStart || this.selectionStart == '0') {
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
var scrollTop = this.scrollTop;
this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos, this.value.length);
this.focus();
this.selectionStart = startPos + myValue.length;
this.selectionEnd = startPos + myValue.length;
this.scrollTop = scrollTop;
} else {
this.value += myValue;
this.focus();
}
}
});
var app = new haste();
var path = window.location.pathname;
if (path === '/') {
app.newDocument(true);
} else {
app.loadDocument(path.substring(1, path.length));
}
});
hljs.initHighlightingOnLoad();

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
static/function-icons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

84
static/highlight.css Normal file
View File

@@ -0,0 +1,84 @@
/*
Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #002b36;
color: #839496;
}
.hljs-comment,
.hljs-quote {
color: #586e75;
}
/* Solarized Green */
.hljs-keyword,
.hljs-selector-tag,
.hljs-addition {
color: #859900;
}
/* Solarized Cyan */
.hljs-number,
.hljs-string,
.hljs-meta .hljs-meta-string,
.hljs-literal,
.hljs-doctag,
.hljs-regexp {
color: #2aa198;
}
/* Solarized Blue */
.hljs-title,
.hljs-section,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #268bd2;
}
/* Solarized Yellow */
.hljs-attribute,
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-class .hljs-title,
.hljs-type {
color: #b58900;
}
/* Solarized Orange */
.hljs-symbol,
.hljs-bullet,
.hljs-subst,
.hljs-meta,
.hljs-meta .hljs-keyword,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-link {
color: #cb4b16;
}
/* Solarized Red */
.hljs-built_in,
.hljs-deletion {
color: #dc322f;
}
.hljs-formula {
background: #073642;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

2
static/highlight.min.js vendored Normal file

File diff suppressed because one or more lines are too long

25
static/index.html Normal file
View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<title>Hastebin Plus</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" type="text/css" href="application.min.css"/>
<link rel="stylesheet" type="text/css" href="highlight.min.css"/>
<link rel="shortcut icon" href="favicon.png">
<script src="jquery.min.js"></script>
<script src="highlight.min.js"></script>
<script src="application.min.js"></script>
</head>
<body>
<div id="content">
<pre id="code" style="display:none;" tabindex="0"><code></code></pre>
<textarea spellcheck="false" style="display:none;"></textarea>
</div>
<div id="tools">
<div class="save function" title="Save [Ctrl + S]"></div>
<div class="new function" title="New [Ctrl + Space]"></div>
<div class="duplicate function" title="Duplicate [Ctrl + D]"></div>
<div class="raw function" title="Raw [Ctrl + Shift + R]"></div>
</div>
</body>
</html>

4
static/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long