Răsfoiți Sursa

Merge pull request #4 from overleaf/msm-decaf

access-token-encryptor decaffeination
Miguel Serrano 6 ani în urmă
părinte
comite
82b18e01b5

+ 0 - 18
libraries/access-token-encryptor/.gitignore

@@ -36,26 +36,8 @@ Icon?
 Thumbs.db
 
 /node_modules/*
-test/IntergrationTests/js/*
 data/*/*
 
-app.js
-app/js/*
-lib/js/*
-test/IntergrationTests/js/*
-test/UnitTests/js/*
-cookies.txt
-uploads/*
-public/js/editor.js
-public/js/home.js
-public/js/forms.js
-public/js/gui.js
-public/js/admin.js
-public/stylesheets/mainStyle.css
-public/minjs/
-test/unit/js/
-test/acceptance/js
-
 **.swp
 
 /log.json

+ 1 - 1
libraries/access-token-encryptor/.nvmrc

@@ -1 +1 @@
-4.2.1
+10.19.0

+ 0 - 56
libraries/access-token-encryptor/Gruntfile.coffee

@@ -1,56 +0,0 @@
-spawn = require("child_process").spawn
-
-module.exports = (grunt) ->
-	grunt.initConfig
-		coffee:
-			# app_src:
-			# 	expand: true,
-			# 	cwd: "app/coffee"
-			# 	src: ['**/*.coffee'],
-			# 	dest: 'app/js/',
-			# 	ext: '.js'
-
-			# app:
-			# 	src: "app.coffee"
-			# 	dest: "app.js"
-
-			unit_tests:
-				expand: true
-				cwd:  "test/unit/coffee"
-				src: ["**/*.coffee"]
-				dest: "test/unit/js/"
-				ext:  ".js"
-
-			# acceptance_tests:
-			# 	expand: true
-			# 	cwd:  "test/acceptance/coffee"
-			# 	src: ["**/*.coffee"]
-			# 	dest: "test/acceptance/js/"
-			# 	ext:  ".js"
-
-		clean:
-			app: ["lib/js/"]
-			unit_tests: ["test/unit/js"]
-
-		mochaTest:
-			unit:
-				options:
-					reporter: grunt.option('reporter') or 'spec'
-					grep: grunt.option("grep")
-				src: ["test/unit/js/**/*.js"]
-
-	grunt.loadNpmTasks 'grunt-contrib-coffee'
-	grunt.loadNpmTasks 'grunt-contrib-clean'
-	grunt.loadNpmTasks 'grunt-mocha-test'
-	grunt.loadNpmTasks 'grunt-execute'
-	grunt.loadNpmTasks 'grunt-bunyan'
-
-	grunt.registerTask 'compile:unit_tests', ['clean:unit_tests', 'coffee:unit_tests']
-	grunt.registerTask 'test:unit',          ['compile:unit_tests', 'mochaTest:unit']
-
-	grunt.registerTask 'compile:acceptance_tests', ['clean:acceptance_tests', 'coffee:acceptance_tests']
-	grunt.registerTask 'test:acceptance',          ['compile:acceptance_tests', 'mochaTest:acceptance']
-
-	grunt.registerTask 'install', 'compile:app'
-
-	grunt.registerTask 'default', ['run']

+ 1 - 2
libraries/access-token-encryptor/index.js

@@ -1,2 +1 @@
-require('coffee-script');
-module.exports = require('./lib/coffee/AccessTokenEncryptor.coffee');
+module.exports = require('./lib/js/AccessTokenEncryptor');

+ 0 - 77
libraries/access-token-encryptor/lib/coffee/AccessTokenEncryptor.coffee

@@ -1,77 +0,0 @@
-crypto = require('crypto')
-
-ALGORITHM = 'aes-256-ctr'
-
-keyFn = (password, salt, callback)->
-	return crypto.pbkdf2(password, salt, 10000, 64, 'sha1', callback)
-
-keyFn32 = (password, salt, keyLength, callback)->
-	return crypto.pbkdf2(password, salt, 10000, 32, 'sha1', callback)
-
-class AccessTokenEncryptor
-
-	constructor: (settings) ->
-
-		@settings = settings
-		@cipherLabel = @settings.cipherLabel
-		throw Error("cipherLabel must not contain a colon (:)") if @cipherLabel?.match(/:/)
-
-		@cipherPassword = @settings.cipherPasswords[@cipherLabel]
-		throw Error("cipherPassword not set") if not @cipherPassword?
-		throw Error("cipherPassword too short") if @cipherPassword.length < 16
-
-	encryptJson: (json, callback) ->
-		string = JSON.stringify(json)
-		crypto.randomBytes 32, (err, bytes) =>
-			return callback(err) if err
-			salt = bytes.slice(0, 16)
-			iv = bytes.slice(16, 32)
-
-			keyFn32 @cipherPassword, salt, 32, (err, key) =>
-				if err?
-					logger.err err:err, "error getting Fn key"
-					return callback(err)
-
-				cipher = crypto.createCipheriv(ALGORITHM, key, iv)
-				crypted = cipher.update(string, 'utf8', 'base64') + cipher.final('base64')
-
-				callback(null, "#{@cipherLabel}:#{salt.toString('hex')}:#{crypted}:#{iv.toString('hex')}")
-
-	decryptToJson: (encryptedJson, callback) ->
-		[label, salt, cipherText, iv] = encryptedJson.split(':', 4)
-		password = @settings.cipherPasswords[label]
-		return callback(new Error("invalid password")) if not password? or password.length < 16
-
-		if iv
-			@decryptToJsonV2(password, salt, cipherText, iv, callback)
-		else
-			@decryptToJsonV1(password, salt, cipherText, callback)
-
-	decryptToJsonV1: (password, salt, cipherText, callback) ->
-		keyFn password, Buffer.from(salt, 'hex'), (err, key) =>
-			if err?
-				logger.err err:err, "error getting Fn key"
-				return callback(err)
-			decipher = crypto.createDecipher(ALGORITHM, key)
-			dec = decipher.update(cipherText, 'base64', 'utf8') + decipher.final('utf8')
-			try
-				json = JSON.parse(dec)
-			catch e
-				return callback(new Error("error decrypting token"))
-			callback(null, json, true)
-
-	decryptToJsonV2: (password, salt, cipherText, iv, callback) ->
-		keyFn32 password, Buffer.from(salt, 'hex'), 32, (err, key) =>
-			if err?
-				logger.err err:err, "error getting Fn key"
-				return callback(err)
-
-			decipher = crypto.createDecipheriv(ALGORITHM, key, Buffer.from(iv, 'hex'))
-			dec = decipher.update(cipherText, 'base64', 'utf8') + decipher.final('utf8')
-			try
-				json = JSON.parse(dec)
-			catch e
-				return callback(new Error("error decrypting token"))
-			callback(null, json)
-
-module.exports = AccessTokenEncryptor

+ 104 - 0
libraries/access-token-encryptor/lib/js/AccessTokenEncryptor.js

@@ -0,0 +1,104 @@
+// TODO: This file was created by bulk-decaffeinate.
+// Sanity-check the conversion and remove this comment.
+/*
+ * decaffeinate suggestions:
+ * DS101: Remove unnecessary use of Array.from
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const crypto = require('crypto');
+
+const Buffer = require('buffer').Buffer;
+
+const ALGORITHM = 'aes-256-ctr';
+
+const keyFn = (password, salt, callback)=> crypto.pbkdf2(password, salt, 10000, 64, 'sha1', callback);
+
+const keyFn32 = (password, salt, keyLength, callback)=> crypto.pbkdf2(password, salt, 10000, 32, 'sha1', callback);
+
+class AccessTokenEncryptor {
+
+	constructor(settings) {
+
+		this.settings = settings;
+		this.cipherLabel = this.settings.cipherLabel;
+		if (this.cipherLabel != null ? this.cipherLabel.match(/:/) : undefined) { throw Error("cipherLabel must not contain a colon (:)"); }
+
+		this.cipherPassword = this.settings.cipherPasswords[this.cipherLabel];
+		if ((this.cipherPassword == null)) { throw Error("cipherPassword not set"); }
+		if (this.cipherPassword.length < 16) { throw Error("cipherPassword too short"); }
+	}
+
+	encryptJson(json, callback) {
+		const string = JSON.stringify(json);
+		return crypto.randomBytes(32, (err, bytes) => {
+			if (err) { return callback(err); }
+			const salt = bytes.slice(0, 16);
+			const iv = bytes.slice(16, 32);
+
+			return keyFn32(this.cipherPassword, salt, 32, (err, key) => {
+				if (err != null) {
+					logger.err({err}, "error getting Fn key");
+					return callback(err);
+				}
+
+				const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
+				const crypted = cipher.update(string, 'utf8', 'base64') + cipher.final('base64');
+
+				return callback(null, `${this.cipherLabel}:${salt.toString('hex')}:${crypted}:${iv.toString('hex')}`);
+			});
+		});
+	}
+
+	decryptToJson(encryptedJson, callback) {
+		const [label, salt, cipherText, iv] = Array.from(encryptedJson.split(':', 4));
+		const password = this.settings.cipherPasswords[label];
+		if ((password == null) || (password.length < 16)) { return callback(new Error("invalid password")); }
+
+		if (iv) {
+			return this.decryptToJsonV2(password, salt, cipherText, iv, callback);
+		} else {
+			return this.decryptToJsonV1(password, salt, cipherText, callback);
+		}
+	}
+
+	decryptToJsonV1(password, salt, cipherText, callback) {
+		return keyFn(password, Buffer.from(salt, 'hex'), (err, key) => {
+			let json;
+			if (err != null) {
+				logger.err({err}, "error getting Fn key");
+				return callback(err);
+			}
+			const decipher = crypto.createDecipher(ALGORITHM, key);
+			const dec = decipher.update(cipherText, 'base64', 'utf8') + decipher.final('utf8');
+			try {
+				json = JSON.parse(dec);
+			} catch (e) {
+				return callback(new Error("error decrypting token"));
+			}
+			return callback(null, json, true);
+		});
+	}
+
+	decryptToJsonV2(password, salt, cipherText, iv, callback) {
+		return keyFn32(password, Buffer.from(salt, 'hex'), 32, (err, key) => {
+			let json;
+			if (err != null) {
+				logger.err({err}, "error getting Fn key");
+				return callback(err);
+			}
+
+			const decipher = crypto.createDecipheriv(ALGORITHM, key, Buffer.from(iv, 'hex'));
+			const dec = decipher.update(cipherText, 'base64', 'utf8') + decipher.final('utf8');
+			try {
+				json = JSON.parse(dec);
+			} catch (e) {
+				return callback(new Error("error decrypting token"));
+			}
+			return callback(null, json);
+		});
+	}
+}
+
+module.exports = AccessTokenEncryptor;

Fișier diff suprimat deoarece este prea mare
+ 0 - 888
libraries/access-token-encryptor/package-lock.json


+ 2 - 11
libraries/access-token-encryptor/package.json

@@ -5,23 +5,14 @@
   "private": true,
   "main": "index.js",
   "scripts": {
-    "test": "grunt coffee && grunt mochaTest"
+    "test": "mocha test/**/*.js"
   },
   "author": "",
   "license": "Proprietary",
-  "dependencies": {
-    "coffee-script": "^1.10.0"
-  },
+  "dependencies": {},
   "devDependencies": {
     "bunyan": "~0.22.3",
     "chai": "",
-    "grunt": "~0.4.5",
-    "grunt-bunyan": "~0.5.0",
-    "grunt-cli": "^1.3.2",
-    "grunt-contrib-clean": "~0.5.0",
-    "grunt-contrib-coffee": "~0.10.1",
-    "grunt-execute": "~0.2.1",
-    "grunt-mocha-test": "^0.13.3",
     "mocha": "^6.2.2",
     "nock": "0.15.2",
     "sandboxed-module": "^2.0.3",

+ 0 - 84
libraries/access-token-encryptor/test/unit/coffee/AccessTokenEncryptorTests.coffee

@@ -1,84 +0,0 @@
-sinon = require('sinon')
-chai = require('chai')
-should = chai.should()
-expect = chai.expect
-modulePath = "../../../index.js"
-SandboxedModule = require('sandboxed-module')
-path = require('path')
-
-describe 'AccessTokenEncryptor', ->
-
-	beforeEach ->
-		@testObject = {"hello":"world"}
-		@encrypted2015 = "2015.1:473a66fb5d816bc716f278ab819d88a5:+mTg7O9sgUND8pNQFG6h2GE="
-		@encrypted2016 = "2016.1:76a7d64a444ccee1a515b49c44844a69:m5YSkexUsLjcF4gLncm72+k="
-		@encrypted2019 = "2019.1:627143b2ab185a020c8720253a4c984e:7gnY6Ez3/Y3UWgLHLfBtJsE=:bf75cecb6aeea55b3c060e1122d2a82d"
-		@badLabel = "xxxxxx:c7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q="
-		@badKey = "2015.1:d7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q="
-		@badCipherText = "2015.1:c7a39310056b694c:xQf+Uh5Den3JREtvc82GW5Q="
-		@settings =
-			cipherLabel: "2019.1"
-			cipherPasswords:
-				"2016.1": "11111111111111111111111111111111111111"
-				"2015.1": "22222222222222222222222222222222222222"
-				"2019.1": "33333333333333333333333333333333333333"
-		@AccessTokenEncryptor = SandboxedModule.require modulePath
-		@encryptor = new @AccessTokenEncryptor(@settings)
-
-	describe "encrypt", ->
-		it 'should encrypt the object', (done)->
-			@encryptor.encryptJson @testObject, (err, encrypted)->
-				expect(err).to.be.null
-				encrypted.should.match(/^2019.1:[0-9a-f]{32}:[a-zA-Z0-9=+\/]+:[0-9a-f]{32}$/)
-				done()
-
-		it 'should encrypt the object differently the next time', (done)->
-			@encryptor.encryptJson @testObject, (err, encrypted1)=>
-				@encryptor.encryptJson @testObject, (err, encrypted2)=>
-					encrypted1.should.not.equal(encrypted2)
-					done()
-
-	describe "decrypt", ->
-		it 'should decrypt the string to get the same object', (done)->
-			@encryptor.encryptJson @testObject, (err, encrypted) =>
-				expect(err).to.be.null
-				@encryptor.decryptToJson encrypted, (err, decrypted) =>
-					expect(err).to.be.null
-					expect(decrypted).to.deep.equal @testObject
-					done()
-
-		it 'should decrypt an 2015 string to get the same object', (done)->
-			@encryptor.decryptToJson @encrypted2015, (err, decrypted)=>
-				expect(err).to.be.null
-				expect(decrypted).to.deep.equal @testObject
-				done()
-
-		it 'should decrypt an 2016 string to get the same object', (done)->
-			@encryptor.decryptToJson @encrypted2016, (err, decrypted)=>
-				expect(err).to.be.null
-				expect(decrypted).to.deep.equal @testObject
-				done()
-
-		it 'should decrypt an 2019 string to get the same object', (done)->
-			@encryptor.decryptToJson @encrypted2019, (err, decrypted)=>
-				expect(err).to.be.null
-				expect(decrypted).to.deep.equal @testObject
-				done()
-
-		it 'should return an error when decrypting an invalid label', (done)->
-			@encryptor.decryptToJson @badLabel, (err, decrypted)->
-				expect(err).to.be.instanceof(Error)
-				expect(decrypted).to.be.undefined
-				done()
-
-		it 'should return an error when decrypting an invalid key', (done)->
-			@encryptor.decryptToJson @badKey, (err, decrypted)->
-				expect(err).to.be.instanceof(Error)
-				expect(decrypted).to.be.undefined
-				done()
-
-		it 'should return an error when decrypting an invalid ciphertext',(done)->
-			@encryptor.decryptToJson	@badCipherText, (err, decrypted)->
-				expect(err).to.be.instanceof(Error)
-				expect(decrypted).to.be.undefined
-				done()

+ 117 - 0
libraries/access-token-encryptor/test/unit/js/AccessTokenEncryptorTests.js

@@ -0,0 +1,117 @@
+// TODO: This file was created by bulk-decaffeinate.
+// Sanity-check the conversion and remove this comment.
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const sinon = require('sinon');
+const chai = require('chai');
+const should = chai.should();
+const { expect } = chai;
+const modulePath = "../../../index.js";
+const SandboxedModule = require('sandboxed-module');
+const path = require('path');
+
+describe('AccessTokenEncryptor', function() {
+
+	beforeEach(function() {
+		this.testObject = {"hello":"world"};
+		this.encrypted2015 = "2015.1:473a66fb5d816bc716f278ab819d88a5:+mTg7O9sgUND8pNQFG6h2GE=";
+		this.encrypted2016 = "2016.1:76a7d64a444ccee1a515b49c44844a69:m5YSkexUsLjcF4gLncm72+k=";
+		this.encrypted2019 = "2019.1:627143b2ab185a020c8720253a4c984e:7gnY6Ez3/Y3UWgLHLfBtJsE=:bf75cecb6aeea55b3c060e1122d2a82d";
+		this.badLabel = "xxxxxx:c7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q=";
+		this.badKey = "2015.1:d7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q=";
+		this.badCipherText = "2015.1:c7a39310056b694c:xQf+Uh5Den3JREtvc82GW5Q=";
+		this.settings = {
+			cipherLabel: "2019.1",
+			cipherPasswords: {
+				"2016.1": "11111111111111111111111111111111111111",
+				"2015.1": "22222222222222222222222222222222222222",
+				"2019.1": "33333333333333333333333333333333333333"
+			}
+		};
+		this.AccessTokenEncryptor = SandboxedModule.require(modulePath);
+		return this.encryptor = new this.AccessTokenEncryptor(this.settings);
+	});
+
+	describe("encrypt", function() {
+		it('should encrypt the object', function(done){
+			return this.encryptor.encryptJson(this.testObject, function(err, encrypted){
+				expect(err).to.be.null;
+				encrypted.should.match(/^2019.1:[0-9a-f]{32}:[a-zA-Z0-9=+\/]+:[0-9a-f]{32}$/);
+				return done();
+			});
+		});
+
+		return it('should encrypt the object differently the next time', function(done){
+			return this.encryptor.encryptJson(this.testObject, (err, encrypted1)=> {
+				return this.encryptor.encryptJson(this.testObject, (err, encrypted2)=> {
+					encrypted1.should.not.equal(encrypted2);
+					return done();
+				});
+			});
+		});
+	});
+
+	return describe("decrypt", function() {
+		it('should decrypt the string to get the same object', function(done){
+			return this.encryptor.encryptJson(this.testObject, (err, encrypted) => {
+				expect(err).to.be.null;
+				return this.encryptor.decryptToJson(encrypted, (err, decrypted) => {
+					expect(err).to.be.null;
+					expect(decrypted).to.deep.equal(this.testObject);
+					return done();
+				});
+			});
+		});
+
+		it('should decrypt an 2015 string to get the same object', function(done){
+			return this.encryptor.decryptToJson(this.encrypted2015, (err, decrypted)=> {
+				expect(err).to.be.null;
+				expect(decrypted).to.deep.equal(this.testObject);
+				return done();
+			});
+		});
+
+		it('should decrypt an 2016 string to get the same object', function(done){
+			return this.encryptor.decryptToJson(this.encrypted2016, (err, decrypted)=> {
+				expect(err).to.be.null;
+				expect(decrypted).to.deep.equal(this.testObject);
+				return done();
+			});
+		});
+
+		it('should decrypt an 2019 string to get the same object', function(done){
+			return this.encryptor.decryptToJson(this.encrypted2019, (err, decrypted)=> {
+				expect(err).to.be.null;
+				expect(decrypted).to.deep.equal(this.testObject);
+				return done();
+			});
+		});
+
+		it('should return an error when decrypting an invalid label', function(done){
+			return this.encryptor.decryptToJson(this.badLabel, function(err, decrypted){
+				expect(err).to.be.instanceof(Error);
+				expect(decrypted).to.be.undefined;
+				return done();
+			});
+		});
+
+		it('should return an error when decrypting an invalid key', function(done){
+			return this.encryptor.decryptToJson(this.badKey, function(err, decrypted){
+				expect(err).to.be.instanceof(Error);
+				expect(decrypted).to.be.undefined;
+				return done();
+			});
+		});
+
+		return it('should return an error when decrypting an invalid ciphertext',function(done){
+			return this.encryptor.decryptToJson(this.badCipherText, function(err, decrypted){
+				expect(err).to.be.instanceof(Error);
+				expect(decrypted).to.be.undefined;
+				return done();
+			});
+		});
+	});
+});

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff