Skip to content

Commit

Permalink
Merge pull request #1 from localnerve/rc-0.1.0
Browse files Browse the repository at this point in the history
Rc 0.1.0
  • Loading branch information
localnerve committed Sep 7, 2023
2 parents 098baef + 48aefb9 commit 45bb205
Show file tree
Hide file tree
Showing 24 changed files with 14,735 additions and 1 deletion.
15 changes: 15 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"env": {
"node": true
},
"extends": [
"eslint:recommended"
],
"rules": {
"no-console": 0
}
}
32 changes: 32 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Verify
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
verify:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- name: Run Lint and Test
run: npm run lint && npm test
- name: Coverage Upload
if: ${{ success() }}
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coverage/lcov.info
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

*.tgz

tmp
cjs
dist

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

coverage
6 changes: 6 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__tests__
test-package
.github
coverage
tmp
*.tgz
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# hmac-symmetric
A library for symmetric encryption with hmac digests

> A library for simple symmetric encryption with HMAC digests
## Detailed readme coming soon...
28 changes: 28 additions & 0 deletions __tests__/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* test lib/utils.js
*
* Relies on the following environment:
* process.env.HS_ENCRYPTION_KEY
* process.env.HS_HMAC_SECRET
*
* Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
* Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
*/
/* eslint-env jest */
import { encryptAndDigest, decryptAndTest } from '../lib/helpers.js';

const input = 'hello world';

describe('full basic test', () => {
test('basic functionality', () => {
const enc = encryptAndDigest(input);
expect(enc).toHaveProperty('digest');
expect(enc).toHaveProperty('payload');

const result = decryptAndTest(enc.digest, enc.payload);
expect(result).toHaveProperty('ok');
expect(result).toHaveProperty('decrypted');
expect(result.ok).toStrictEqual(true);
expect(result.decrypted).toEqual(input);
});
});
97 changes: 97 additions & 0 deletions __tests__/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* test lib/utils.js
*
* Relies on the following environment:
* process.env.HS_ENCRYPTION_KEY
* process.env.HS_HMAC_SECRET
*
* Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
* Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
*/
/* eslint-env jest */
import { HSError } from '../lib/errors.js';
import { generateHmac, symmetricEncrypt, symmetricDecrypt } from '../lib/utils.js';

const input = 'hello world';

describe('generateHmac', () => {
test('basic equality', () => {
const first = generateHmac(input);
const second = generateHmac(input);
expect(first).toEqual(second);
});

test('bad secret, environment override, HSError instance', () => {
expect(() => {
generateHmac(input, {
hmacSecret: {}
});
}).toThrow(HSError)
});

test('bad algo, error type', () => {
try {
generateHmac(input, {
hmacAlgo: 'notAlgo'
});
throw new Error('This should not have run');
} catch (e) {
expect(e.hseType).toEqual(HSError.HSE_HMAC);
}
});
});

describe('symmetricEncrypt', () => {
test('basic encyption', () => {
const encrypted = symmetricEncrypt(input);
const decrypted = symmetricDecrypt(encrypted);
expect(decrypted).toEqual(input);
});

test('bad key, environment override, HSError instance', () => {
expect(() => {
symmetricEncrypt(input, {
encryptionKey: {}
});
}).toThrow(HSError);
});

test('bad algo, error type', () => {
try {
symmetricEncrypt(input, {
encryptionAlgo: 'notAlgo'
});
throw new Error('this should not have run');
} catch (e) {
expect(e.hseType).toEqual(HSError.HSE_ENCRYPT);
}
});
});

describe('symmetricDecrypt', () => {
test('decrypt to buffer', () => {
const encrypted = symmetricEncrypt(input);
const decrypted = symmetricDecrypt(encrypted, { outputBuffer: true });
expect(decrypted).toBeInstanceOf(Buffer);
expect(decrypted.toString()).toEqual(input);
});

test('bad key, environment override, HSError instance', () => {
expect(() => {
symmetricDecrypt('one:two', {
encryptionKey: {}
});
}).toThrow(HSError);
});

test('bad algo, error type', () => {
try {
symmetricDecrypt('one:two', {
encryptionKey: {}
});
throw new Error('this should not have run');
} catch (e) {
expect(e.hseType).toEqual(HSError.HSE_DECRYPT);
}
});
});
11 changes: 11 additions & 0 deletions babel.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"presets": [
[
"@babel/preset-env", {
"targets": {
"node": "16"
}
}
]
]
}
10 changes: 10 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
collectCoverage: true,
coverageDirectory: 'coverage',
verbose: true,
testEnvironment: 'node',
testPathIgnorePatterns: [
'/node_modules/',
'/tmp/'
]
};
23 changes: 23 additions & 0 deletions lib/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Error type for hmac symmetric.
*
* Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
* Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
*/

export class HSError extends Error {
static HSE_HMAC = 'HSE_HMAC';
static HSE_ENCRYPT = 'HSE_ENCRYPT';
static HSE_DECRYPT = 'HSE_DECRYPT';

#hseType;
get hseType () {
return this.#hseType;
}

constructor (hsErrorType, originalError) {
super(originalError.message, { cause: originalError });
this.#hseType = hsErrorType;
this.name = 'HSError';
}
}
38 changes: 38 additions & 0 deletions lib/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Convenience methods for hmac symmetric.
*
* Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
* Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
*/
import { generateHmac, symmetricEncrypt, symmetricDecrypt } from './utils.js';

/**
* Generate hmac and symmetrically encrypted payload.
*
* @param {String|Buffer|TypedArray|DataView} input - The data to encrypt.
* @param {Object} [options] - Optional options, @see utils.js
* @returns {Object} - { digest, payload } on success, throws HSError on error.
*/
export function encryptAndDigest (input, options) {
return {
digest: generateHmac(input, options),
payload: symmetricEncrypt(input, options)
};
}

/**
* Decrypt encrypted input and check hmac digest with original.
*
* @param {String} originalDigest - The original hmac digest to test against.
* @param {String} encryptedInput - The encrypted input data string.
* @param {Object} [options] - Optional options, @see utils.js
* @returns {Object} - { ok, decrypted } on success, throws HSError on error.
*/
export function decryptAndTest (originalDigest, encryptedInput, options) {
const decrypted = symmetricDecrypt(encryptedInput, options);
const digest = generateHmac(decrypted);
return {
ok: digest === originalDigest,
decrypted
};
}
8 changes: 8 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* hmac-symmetric exports
*
* Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
* Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
*/
export { generateHmac, symmetricEncrypt, symmetricDecrypt } from './utils.js';
export { encryptAndDigest, decryptAndTest } from './helpers.js';
Loading

0 comments on commit 45bb205

Please sign in to comment.