mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-24 03:23:10 +00:00
init (copied from thirdpartydatastore-sharelatex)
This commit is contained in:
commit
fc3c0d1384
6 changed files with 262 additions and 0 deletions
62
libraries/access-token-encryptor/.gitignore
vendored
Normal file
62
libraries/access-token-encryptor/.gitignore
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
compileFolder
|
||||
|
||||
Compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
# Packages #
|
||||
############
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store?
|
||||
ehthumbs.db
|
||||
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
|
||||
hash_folder
|
56
libraries/access-token-encryptor/Gruntfile.coffee
Normal file
56
libraries/access-token-encryptor/Gruntfile.coffee
Normal file
|
@ -0,0 +1,56 @@
|
|||
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']
|
2
libraries/access-token-encryptor/index.js
Normal file
2
libraries/access-token-encryptor/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
require('coffee-script');
|
||||
module.exports = require('./lib/coffee/AccessTokenEncryptor.coffee');
|
|
@ -0,0 +1,44 @@
|
|||
crypto = require('crypto')
|
||||
|
||||
settings = require('settings-sharelatex')
|
||||
|
||||
cipherLabel = settings.cipherLabel
|
||||
throw Error("cipherLabel must not contain a colon (:)") if cipherLabel?.match(/:/)
|
||||
|
||||
cipherPassword = settings.cipherPasswords[settings.cipherLabel]
|
||||
throw Error("cipherPassword not set") if not cipherPassword?
|
||||
throw Error("cipherPassword too short") if cipherPassword.length < 16
|
||||
|
||||
ALGORITHM = 'aes-256-ctr'
|
||||
|
||||
keyFn = (password, salt, callback)->
|
||||
return crypto.pbkdf2(password, salt, 10000, 64, callback)
|
||||
|
||||
module.exports =
|
||||
|
||||
encryptJson: (json, callback)->
|
||||
string = JSON.stringify(json)
|
||||
salt = crypto.randomBytes(16)
|
||||
keyFn cipherPassword, salt, (err, key)->
|
||||
if err?
|
||||
logger.err err:err, "error getting Fn key"
|
||||
return callback(err)
|
||||
cipher = crypto.createCipher(ALGORITHM, key)
|
||||
crypted = cipher.update(string, 'utf8', 'base64') + cipher.final('base64')
|
||||
callback(null, cipherLabel + ":" + salt.toString('hex') + ":" + crypted)
|
||||
|
||||
decryptToJson: (encryptedJson, callback)->
|
||||
[label, salt, cipherText] = encryptedJson.split(':', 3)
|
||||
password = settings.cipherPasswords[label]
|
||||
return callback(new Error("invalid password")) if not password? or password.length < 16
|
||||
keyFn password, new Buffer(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)
|
28
libraries/access-token-encryptor/package.json
Normal file
28
libraries/access-token-encryptor/package.json
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "access-token-encryptor-sharelatex",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "Proprietary",
|
||||
"dependencies": {
|
||||
"coffee-script": "^1.10.0",
|
||||
"settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nock": "0.15.2",
|
||||
"sandboxed-module": "",
|
||||
"sinon": "",
|
||||
"chai": "",
|
||||
"grunt-contrib-clean": "~0.5.0",
|
||||
"grunt-mocha-test": "~0.10.2",
|
||||
"grunt-contrib-coffee": "~0.10.1",
|
||||
"grunt": "~0.4.5",
|
||||
"grunt-execute": "~0.2.1",
|
||||
"bunyan": "~0.22.3",
|
||||
"grunt-bunyan": "~0.5.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
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"}
|
||||
@Encrypted = "2016.1:6e7ac79ab13a18b5749eace965ec7962:sAAYt1yQZqpvOnu6l8iUD/Y="
|
||||
@oldEncrypted = "2015.1:473a66fb5d816bc716f278ab819d88a5:+mTg7O9sgUND8pNQFG6h2GE="
|
||||
@badLabel = "xxxxxx:c7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q="
|
||||
@badKey = "2015.1:d7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q="
|
||||
@badCipherText = "2015.1:c7a39310056b694c:xQf+Uh5Den3JREtvc82GW5Q="
|
||||
@requires = requires:
|
||||
"settings-sharelatex":
|
||||
cipherLabel: "2016.1"
|
||||
cipherPasswords:
|
||||
"2016.1": "11111111111111111111111111111111111111"
|
||||
"2015.1": "22222222222222222222222222222222222222"
|
||||
@AccessTokenEncryptor = SandboxedModule.require modulePath, @requires
|
||||
|
||||
describe "encrypt", ->
|
||||
it 'should encrypt the object', (done)->
|
||||
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted)->
|
||||
expect(err).to.be.null
|
||||
encrypted.should.match(/^2016.1:[0-9a-f]+:[a-zA-Z0-9=+\/]+$/)
|
||||
done()
|
||||
|
||||
it 'should encrypt the object differently the next time', (done)->
|
||||
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted1)=>
|
||||
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted2)=>
|
||||
encrypted1.should.not.equal(encrypted2)
|
||||
done()
|
||||
|
||||
describe "decrypt", ->
|
||||
it 'should decrypt the string to get the same object', (done)->
|
||||
@AccessTokenEncryptor.encryptJson @testObject, (err, encrypted) =>
|
||||
expect(err).to.be.null
|
||||
@AccessTokenEncryptor.decryptToJson encrypted, (err, decrypted) =>
|
||||
expect(err).to.be.null
|
||||
expect(decrypted).to.deep.equal @testObject
|
||||
done()
|
||||
|
||||
it 'should decrypt an old string to get the same object', (done)->
|
||||
@AccessTokenEncryptor.decryptToJson @oldEncrypted, (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)->
|
||||
@AccessTokenEncryptor.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)->
|
||||
@AccessTokenEncryptor.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)->
|
||||
@AccessTokenEncryptor.decryptToJson @badCipherText, (err, decrypted)->
|
||||
expect(err).to.be.instanceof(Error)
|
||||
expect(decrypted).to.be.undefined
|
||||
done()
|
Loading…
Reference in a new issue