Browse Source

Changed from ip whitelist to token based auth

kanadeko 7 years ago
parent
commit
b81cf72ac4
9 changed files with 45 additions and 44 deletions
  1. 2 1
      .gitignore
  2. 9 4
      README.md
  3. 12 20
      config.sample.js
  4. 6 4
      controllers/galleryController.js
  5. 5 4
      controllers/uploadController.js
  6. 4 1
      lolisafe.js
  7. 1 2
      package.json
  8. 1 4
      public/js/upload.js
  9. 5 4
      routes/routes.js

+ 2 - 1
.gitignore

@@ -1,5 +1,6 @@
 node_modules/
 uploads/
 logs/
+database/db
 config.js
-db
+start.json

+ 9 - 4
README.md

@@ -5,9 +5,14 @@ Pomf-like image uploading service, written in NodeJS
 ---
 1. Clone
 2. Rename `config.sample.js` to `config.js`
-3. Modify port and privacy options if desired
-4. run `npm install` to install all dependencies
-5. run `node lolisafe.js` to start the service
+4. Modify port and token options if desired
+3. run `npm install` to install all dependencies
+5. run `pm2 start lolisafe.js` or `node lolisafe.js` to start the service
+
+### Token
+This service supports running both as public and private. The only difference is that one needs a token and the other one doesn't. If you want it to be public so anyone can upload files either from the website or API, just leave the token empty on the config file.
+
+But if you want to run it privately, you need to specify a random string, which you'll need to provide in every API call as a header called `auth`.
 
 ---
 ## Using it
@@ -18,4 +23,4 @@ A chrome extension to be able to right click images -> send to safe is in the wo
 
 If you are using nginx, you should set inside your location block the following directive, replacing the number with the one you want set up `client_max_body_size 512M;`
 
-If using apache, you should change the following directives on your config `memory_limit = 512M`
+If using apache, you should change the following directives on your config `RLimitMEM 512M`

+ 12 - 20
config.sample.js

@@ -2,31 +2,27 @@ module.exports = {
 
 	/* 
 	NOTES:
-	
 		All folders specified on this file will be created automagically.
-		Most options shouldn't be touched, and the service should run straight up.
-
+		Ideally the only options you should change are port and basedomain.
 	*/
 
+	// Token to use on the api. Leave blank for public
+	TOKEN: 'YOURSUPERSECRETTOKEN',
+
 	// Port on which to run the server
 	port: 9999,
 
-	// Upload restrictions
-	privacy: {
-
-		// Is the service public? If so, anyone with the URL can upload files
-		public: false,
-
-		// If not, which IP's should be able to access?
-		IPs: [
-			'::1',
-			'127.0.0.1'
-		]
-	},
-
 	// Uploads config
 	uploads: {
 
+		// Where to serve the uploaded files.
+		basedomain: 'https://i.kanacchi.moe/',
+
+		// If prefix is set, it will be appended at the end of basedomain.
+		// Ex: https://i.kanacchi.moe/prefix/k4n4.png
+		// Leave blank to use the basedomain
+		prefix: '',
+
 		// Folder where images should be stored
 		folder: 'uploads',
 
@@ -35,10 +31,6 @@ module.exports = {
 
 		// The length of the random generated name for the uploaded files
 		fileLength: 4,
-
-		// Prefix before linking an uploaded file. Ex: your-domain.com/prefix/k4n4.png
-		// Leave blank for no prefix
-		prefix: ''
 	},
 
 	// Folder where to store logs

+ 6 - 4
controllers/galleryController.js

@@ -5,8 +5,9 @@ let galleryController = {}
 
 galleryController.list = function(req, res, next){
 	
-	if(!config.privacy.public)
-		if(!config.privacy.IPs.includes(req.ip)) return res.status(401).send('not-authorized')
+	if(config.TOKEN !== '')
+		if(req.headers.auth !== config.TOKEN)
+			return res.status(401).send('not-authorized')
 
 	db.table('gallery').select('id', 'name').then((data) => {
 		res.json({ data })
@@ -15,8 +16,9 @@ galleryController.list = function(req, res, next){
 
 galleryController.test = function(req, res, next){
 	
-	if(!config.privacy.public)
-		if(!config.privacy.IPs.includes(req.ip)) return res.status(401).send('not-authorized')
+	if(config.TOKEN !== '')
+		if(req.headers.auth !== config.TOKEN)
+			return res.status(401).send('not-authorized')
 
 	let testdata = [
 		{name: 'Test 1'},

+ 5 - 4
controllers/uploadController.js

@@ -22,10 +22,11 @@ const upload = multer({
 
 uploadsController.upload = function(req, res, next){
 
-	let gallery = req.headers.gallery
+	if(config.TOKEN !== '')
+		if(req.headers.auth !== config.TOKEN)
+			return res.status(401).send('not-authorized')
 
-	if(!config.privacy.public)
-		if(!config.privacy.IPs.includes(req.ip)) return res.status(401).send('not-authorized')
+	let gallery = req.headers.gallery
 	
 	upload(req, res, function (err) {
 		if (err) {
@@ -38,7 +39,7 @@ uploadsController.upload = function(req, res, next){
 			galleryid: gallery
 		}).then(() => {
 			return res.json({
-				'filename': req.file.filename
+				'url': config.uploads.basedomain + req.file.filename
 			})
 		})
 		

+ 4 - 1
lolisafe.js

@@ -30,4 +30,7 @@ safe.use(function (err, req, res, next) {
 	res.status(500).end()
 })
 
-safe.listen(config.port, () => console.log(`loli-safe started on port ${config.port}`))
+safe.listen(config.port, () => console.log(`loli-safe started on port ${config.port}`))
+
+if(config.TOKEN !== '') console.log('Use the following token as the \'auth\' header in your requests to the API: ' + config.TOKEN)
+else console.log('Running lolisafe in public mode. No token required.')

+ 1 - 2
package.json

@@ -1,9 +1,8 @@
 {
   "name": "loli-safe",
   "version": "1.0.0",
-  "description": "Pomf-like uploading service, written in NodeJS",
+  "description": "Pomf-like uploading service, written in node",
   "author": "kanadeko",
-  "main": "lolibank.js",
   "repository": {
     "type": "git",
     "url": "https://github.com/kanadeko/loli-safe"

+ 1 - 4
public/js/upload.js

@@ -1,5 +1,4 @@
 var maxSize = '512';
-var urlPrefix = '';
 
 var xhr = new XMLHttpRequest();
 xhr.onreadystatechange = function() {
@@ -10,8 +9,6 @@ xhr.onreadystatechange = function() {
 		}
 		if(xhr.responseText.maxFileSize)
 			maxSize = xhr.responseText.maxFileSize;
-		if(xhr.responseText.urlPrefix)
-			urlPrefix = xhr.responseText.urlPrefix + '/';
 	}
 }
 xhr.open('GET', '/api/info', true);
@@ -45,7 +42,7 @@ window.onload = function () {
 	dropzone.on("success", function(file, response) {
 		// Handle the responseText here. For example, add the text to the preview element:
 		a = document.createElement('a');
-		a.href = window.location.origin + '/' + urlPrefix + response.filename;
+		a.href = response.url;
 		a.target = '_blank';
 		a.innerHTML = response.filename;
 

+ 5 - 4
routes/routes.js

@@ -4,12 +4,13 @@ const uploadController = require('../controllers/uploadController')
 const galleryController = require('../controllers/galleryController')
 
 routes.get  ('/info', (req, res, next) => {
-	if(!config.privacy.public)
-		if(!config.privacy.IPs.includes(req.ip)) return res.status(401).send('not-authorized')
 
+	if(config.TOKEN !== '')
+		if(req.headers.auth !== config.TOKEN)
+			return res.status(401).send('not-authorized')
+		
 	return res.json({
-		maxFileSize: config.uploads.maxsize.slice(0, -2),
-		urlPrefix: config.uploads.prefix
+		maxFileSize: config.uploads.maxsize.slice(0, -2)
 	})
 })