| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- const chai = require('chai')
- chai.should()
- const { expect } = chai
- const modulePath = '../../../index.js'
- const SandboxedModule = require('sandboxed-module')
- 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.encrypted2023 =
- '2023.1-v3:a6dd3781dd6ce93a4134874b505a209c:9TdIDAc8V9SeR0ffSn63Jj4=:d8b2de0b733c81b949993dce229abb4c'
- this.badLabel = 'xxxxxx:c7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q='
- this.badKey = '2015.1:d7a39310056b694c:jQf+Uh5Den3JREtvc82GW5Q='
- this.badCipherText = '2015.1:c7a39310056b694c:xQf+Uh5Den3JREtvc82GW5Q='
- this.settings = {
- cipherLabel: '2023.1-v3',
- cipherPasswords: {
- '2023.1-v3': '44444444444444444444444444444444444444',
- },
- }
- this.AccessTokenEncryptor = SandboxedModule.require(modulePath, {
- globals: {
- Buffer,
- },
- })
- this.encryptor = new this.AccessTokenEncryptor(this.settings)
- })
- describe('invalid settings', function () {
- it('should flag missing label', function () {
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '',
- cipherPasswords: { '': '' },
- })
- ).to.throw(/cipherLabel cannot be empty/)
- })
- it('should flag invalid label with colon', function () {
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '2023:1-v2',
- cipherPasswords: { '2023:1-v2': '' },
- })
- ).to.throw(/colon/)
- })
- it('should flag missing password', function () {
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherPasswords: { '2023.1-v3': '' },
- cipherVersions: { '2023.1-v3': 'v3' },
- })
- ).to.throw(/cipherPasswords.+ missing/)
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '2023.1-v3',
- cipherPasswords: { '2023.1-v3': undefined },
- })
- ).to.throw(/cipherPasswords.+ missing/)
- })
- it('should flag short password', function () {
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '2023.1-v3',
- cipherPasswords: { '2023.1-v3': 'foo' },
- })
- ).to.throw(/cipherPasswords.+ too short/)
- })
- it('should flag missing version', function () {
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '2023.1',
- cipherPasswords: { 2023.1: '11111111111111111111111111111111' },
- })
- ).to.throw(/must contain version suffix/)
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '2023.1-',
- cipherPasswords: { '2023.1-': '11111111111111111111111111111111' },
- })
- ).to.throw(/must contain version suffix/)
- })
- it('should flag invalid version', function () {
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '2023.1-v0',
- cipherPasswords: {
- '2023.1-v0': '11111111111111111111111111111111',
- },
- })
- ).to.throw(/unknown version/)
- })
- it('should flag unknown default scheme', function () {
- expect(
- () =>
- new this.AccessTokenEncryptor({
- cipherLabel: '2000.1-v3',
- cipherPasswords: {
- '2023.1-v3': '11111111111111111111111111111111',
- },
- })
- ).to.throw(/unknown default cipherLabel/)
- })
- })
- describe('sync', function () {
- describe('encrypt', function () {
- it('should encrypt the object', function (done) {
- this.encryptor.encryptJson(this.testObject, (err, encrypted) => {
- expect(err).to.be.null
- encrypted.should.match(
- /^2023.1-v3:[0-9a-f]{32}:[a-zA-Z0-9=+/]+:[0-9a-f]{32}$/
- )
- done()
- })
- })
- it('should encrypt the object differently the next time', function (done) {
- this.encryptor.encryptJson(this.testObject, (err, encrypted1) => {
- expect(err).to.be.null
- this.encryptor.encryptJson(this.testObject, (err, encrypted2) => {
- expect(err).to.be.null
- encrypted1.should.not.equal(encrypted2)
- done()
- })
- })
- })
- })
- describe('decrypt', function () {
- it('should decrypt the string to get the same object', function (done) {
- this.encryptor.encryptJson(this.testObject, (err, encrypted) => {
- expect(err).to.be.null
- this.encryptor.decryptToJson(encrypted, (err, decrypted) => {
- expect(err).to.be.null
- expect(decrypted).to.deep.equal(this.testObject)
- done()
- })
- })
- })
- it('should not be able to decrypt 2015 string', function (done) {
- this.encryptor.decryptToJson(this.encrypted2015, (err, decrypted) => {
- expect(err).to.exist
- expect(err.message).to.equal(
- 'unknown access-token-encryptor label 2015.1'
- )
- expect(decrypted).to.not.exist
- done()
- })
- })
- it('should not be able to decrypt a 2016 string', function (done) {
- this.encryptor.decryptToJson(this.encrypted2016, (err, decrypted) => {
- expect(err).to.exist
- expect(err.message).to.equal(
- 'unknown access-token-encryptor label 2016.1'
- )
- expect(decrypted).to.not.exist
- done()
- })
- })
- it('should not be able to decrypt a 2019 string', function (done) {
- this.encryptor.decryptToJson(this.encrypted2019, (err, decrypted) => {
- expect(err).to.exist
- expect(err.message).to.equal(
- 'unknown access-token-encryptor label 2019.1'
- )
- expect(decrypted).to.not.exist
- done()
- })
- })
- it('should decrypt an 2023 string to get the same object', function (done) {
- this.encryptor.decryptToJson(this.encrypted2023, (err, decrypted) => {
- expect(err).to.be.null
- expect(decrypted).to.deep.equal(this.testObject)
- done()
- })
- })
- it('should return an error when decrypting an invalid label', function (done) {
- this.encryptor.decryptToJson(this.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', function (done) {
- this.encryptor.decryptToJson(this.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', function (done) {
- this.encryptor.decryptToJson(this.badCipherText, (err, decrypted) => {
- expect(err).to.be.instanceof(Error)
- expect(decrypted).to.be.undefined
- done()
- })
- })
- })
- })
- describe('async', function () {
- describe('encrypt', function () {
- it('should encrypt the object', async function () {
- const encrypted = await this.encryptor.promises.encryptJson(
- this.testObject
- )
- encrypted.should.match(
- /^2023.1-v3:[0-9a-f]{32}:[a-zA-Z0-9=+/]+:[0-9a-f]{32}$/
- )
- })
- it('should encrypt the object differently the next time', async function () {
- const encrypted1 = await this.encryptor.promises.encryptJson(
- this.testObject
- )
- const encrypted2 = await this.encryptor.promises.encryptJson(
- this.testObject
- )
- encrypted1.should.not.equal(encrypted2)
- })
- })
- describe('decrypt', function () {
- it('should decrypt the string to get the same object', async function () {
- const encrypted = await this.encryptor.promises.encryptJson(
- this.testObject
- )
- const decrypted = await this.encryptor.promises.decryptToJson(encrypted)
- expect(decrypted).to.deep.equal(this.testObject)
- })
- it('should not be able to decrypt 2015 string', async function () {
- await expect(
- this.encryptor.promises.decryptToJson(this.encrypted2015)
- ).to.eventually.be.rejectedWith(
- 'unknown access-token-encryptor label 2015.1'
- )
- })
- it('should not be able to decrypt a 2016 string', async function () {
- await expect(
- this.encryptor.promises.decryptToJson(this.encrypted2016)
- ).to.be.rejectedWith('unknown access-token-encryptor label 2016.1')
- })
- it('should not be able to decrypt a 2019 string', async function () {
- await expect(
- this.encryptor.promises.decryptToJson(this.encrypted2019)
- ).to.be.rejectedWith('unknown access-token-encryptor label 2019.1')
- })
- it('should decrypt an 2023 string to get the same object', async function () {
- const decrypted = await this.encryptor.promises.decryptToJson(
- this.encrypted2023
- )
- expect(decrypted).to.deep.equal(this.testObject)
- })
- it('should return an error when decrypting an invalid label', async function () {
- await expect(
- this.encryptor.promises.decryptToJson(this.badLabel)
- ).to.be.rejectedWith('unknown access-token-encryptor label xxxxxx')
- })
- it('should return an error when decrypting an invalid key', async function () {
- await expect(
- this.encryptor.promises.decryptToJson(this.badKey)
- ).to.be.rejectedWith('unknown access-token-encryptor label 2015.1')
- })
- it('should return an error when decrypting an invalid ciphertext', async function () {
- await expect(
- this.encryptor.promises.decryptToJson(this.badCipherText)
- ).to.be.rejectedWith('unknown access-token-encryptor label 2015.1')
- })
- })
- })
- })
|