mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	v2.1.0 (#293)
* Fix wrapping when too many hosts are shown (#207) * Update npm packages, fixes CVE-2019-10757 * Revert some breaking packages * Major overhaul - Docker buildx support in CI - Cypress API Testing in CI - Restructured folder layout (insert clean face meme) - Added Swagger documentation and validate API against that (to be completed) - Use common base image for all supported archs, which includes updated nginx with ipv6 support - Updated certbot and changes required for it - Large amount of Hosts names will wrap in UI - Updated packages for frontend - Version bump 2.1.0 * Updated documentation * Fix JWT expire time going crazy. Now set to 1day * Backend JS formatting rules * Remove v1 importer, I doubt anyone is using v1 anymore * Added backend formatting rules and enforce them in Jenkins builds * Fix CI, doesn't need a tty * Thanks bcrypt. Why can't you just be normal. * Cleanup after syntax check Co-authored-by: Marcelo Castagna <margaale@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										136
									
								
								backend/models/token.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								backend/models/token.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| /** | ||||
|  NOTE: This is not a database table, this is a model of a Token object that can be created/loaded | ||||
|  and then has abilities after that. | ||||
|  */ | ||||
|  | ||||
| const _      = require('lodash'); | ||||
| const config = require('config'); | ||||
| const jwt    = require('jsonwebtoken'); | ||||
| const crypto = require('crypto'); | ||||
| const error  = require('../lib/error'); | ||||
| const ALGO   = 'RS256'; | ||||
|  | ||||
| module.exports = function () { | ||||
| 	const public_key  = config.get('jwt.pub'); | ||||
| 	const private_key = config.get('jwt.key'); | ||||
|  | ||||
| 	let token_data = {}; | ||||
|  | ||||
| 	let self = { | ||||
| 		/** | ||||
| 		 * @param {Object}  payload | ||||
| 		 * @returns {Promise} | ||||
| 		 */ | ||||
| 		create: (payload) => { | ||||
| 			// sign with RSA SHA256 | ||||
| 			let options = { | ||||
| 				algorithm: ALGO, | ||||
| 				expiresIn: payload.expiresIn || '1d' | ||||
| 			}; | ||||
|  | ||||
| 			payload.jti = crypto.randomBytes(12) | ||||
| 				.toString('base64') | ||||
| 				.substr(-8); | ||||
|  | ||||
| 			return new Promise((resolve, reject) => { | ||||
| 				jwt.sign(payload, private_key, options, (err, token) => { | ||||
| 					if (err) { | ||||
| 						reject(err); | ||||
| 					} else { | ||||
| 						token_data = payload; | ||||
| 						resolve({ | ||||
| 							token:   token, | ||||
| 							payload: payload | ||||
| 						}); | ||||
| 					} | ||||
| 				}); | ||||
| 			}); | ||||
| 		}, | ||||
|  | ||||
| 		/** | ||||
| 		 * @param {String} token | ||||
| 		 * @returns {Promise} | ||||
| 		 */ | ||||
| 		load: function (token) { | ||||
| 			return new Promise((resolve, reject) => { | ||||
| 				try { | ||||
| 					if (!token || token === null || token === 'null') { | ||||
| 						reject(new error.AuthError('Empty token')); | ||||
| 					} else { | ||||
| 						jwt.verify(token, public_key, {ignoreExpiration: false, algorithms: [ALGO]}, (err, result) => { | ||||
| 							if (err) { | ||||
|  | ||||
| 								if (err.name === 'TokenExpiredError') { | ||||
| 									reject(new error.AuthError('Token has expired', err)); | ||||
| 								} else { | ||||
| 									reject(err); | ||||
| 								} | ||||
|  | ||||
| 							} else { | ||||
| 								token_data = result; | ||||
|  | ||||
| 								// Hack: some tokens out in the wild have a scope of 'all' instead of 'user'. | ||||
| 								// For 30 days at least, we need to replace 'all' with user. | ||||
| 								if ((typeof token_data.scope !== 'undefined' && _.indexOf(token_data.scope, 'all') !== -1)) { | ||||
| 									//console.log('Warning! Replacing "all" scope with "user"'); | ||||
|  | ||||
| 									token_data.scope = ['user']; | ||||
| 								} | ||||
|  | ||||
| 								resolve(token_data); | ||||
| 							} | ||||
| 						}); | ||||
| 					} | ||||
| 				} catch (err) { | ||||
| 					reject(err); | ||||
| 				} | ||||
| 			}); | ||||
|  | ||||
| 		}, | ||||
|  | ||||
| 		/** | ||||
| 		 * Does the token have the specified scope? | ||||
| 		 * | ||||
| 		 * @param   {String}  scope | ||||
| 		 * @returns {Boolean} | ||||
| 		 */ | ||||
| 		hasScope: function (scope) { | ||||
| 			return typeof token_data.scope !== 'undefined' && _.indexOf(token_data.scope, scope) !== -1; | ||||
| 		}, | ||||
|  | ||||
| 		/** | ||||
| 		 * @param  {String}  key | ||||
| 		 * @return {*} | ||||
| 		 */ | ||||
| 		get: function (key) { | ||||
| 			if (typeof token_data[key] !== 'undefined') { | ||||
| 				return token_data[key]; | ||||
| 			} | ||||
|  | ||||
| 			return null; | ||||
| 		}, | ||||
|  | ||||
| 		/** | ||||
| 		 * @param  {String}  key | ||||
| 		 * @param  {*}       value | ||||
| 		 */ | ||||
| 		set: function (key, value) { | ||||
| 			token_data[key] = value; | ||||
| 		}, | ||||
|  | ||||
| 		/** | ||||
| 		 * @param   [default_value] | ||||
| 		 * @returns {Integer} | ||||
| 		 */ | ||||
| 		getUserId: (default_value) => { | ||||
| 			let attrs = self.get('attrs'); | ||||
| 			if (attrs && typeof attrs.id !== 'undefined' && attrs.id) { | ||||
| 				return attrs.id; | ||||
| 			} | ||||
|  | ||||
| 			return default_value || 0; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	return self; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user