@sockethub/crypto 1.0.0-alpha.4 → 1.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,16 +1,15 @@
1
1
  {
2
2
  "name": "@sockethub/crypto",
3
3
  "description": "Crypto functions and helpers for Sockethub",
4
- "version": "1.0.0-alpha.4",
4
+ "version": "1.0.0-alpha.5",
5
+ "type": "module",
5
6
  "private": false,
6
7
  "author": "Nick Jennings <nick@silverbucket.net>",
7
8
  "license": "MIT",
8
- "main": "dist/index.js",
9
- "types": "dist/index.d.ts",
10
- "files": [
11
- "dist/",
12
- "src/"
13
- ],
9
+ "main": "src/index.ts",
10
+ "engines": {
11
+ "bun": ">=1.2"
12
+ },
14
13
  "keywords": [
15
14
  "sockethub",
16
15
  "messaging",
@@ -26,41 +25,15 @@
26
25
  },
27
26
  "homepage": "https://github.com/sockethub/sockethub/tree/master/packages/data-layer",
28
27
  "dependencies": {
29
- "@sockethub/schemas": "^3.0.0-alpha.4",
30
- "object-hash": "^3.0.0"
31
- },
32
- "scripts": {
33
- "clean": "npx rimraf dist coverage",
34
- "clean:deps": "npx rimraf node_modules",
35
- "compliance": "yarn run lint && yarn run test && yarn run coverage",
36
- "test": "c8 -x \"src/**/*.test.*\" mocha -r ts-node/register src/*.test.ts",
37
- "coverage": "c8 check-coverage --statements 100 --branches 90 --functions 85 --lines 100",
38
- "lint": "eslint \"**/*.ts\"",
39
- "lint:fix": "eslint --fix \"**/*.ts\"",
40
- "build": "tsc"
41
- },
42
- "engines": {
43
- "node": ">= 14"
28
+ "@sockethub/schemas": "3.0.0-alpha.5",
29
+ "object-hash": "3.0.0"
44
30
  },
45
31
  "devDependencies": {
46
- "@types/chai": "4.3.3",
47
- "@types/debug": "4.1.7",
48
- "@types/eslint": "8.4.6",
49
- "@types/mocha": "9.1.1",
50
- "@types/node": "17.0.13",
51
- "@types/object-hash": "2.2.1",
52
- "@types/proxyquire": "1.3.28",
53
- "@types/sinon": "10.0.13",
54
- "@typescript-eslint/parser": "5.37.0",
55
- "c8": "7.12.0",
56
- "chai": "4.3.6",
57
- "eslint": "8.23.1",
58
- "eslint-cli": "1.1.1",
59
- "mocha": "10.0.0",
60
- "proxyquire": "2.1.3",
61
- "sinon": "14.0.0",
62
- "ts-node": "10.9.1",
63
- "typescript": "4.8.3"
32
+ "@types/bun": "latest",
33
+ "@types/debug": "4.1.12",
34
+ "@types/object-hash": "3.0.6",
35
+ "@types/sinon": "17.0.2",
36
+ "sinon": "17.0.1"
64
37
  },
65
- "gitHead": "c6d34ff44d2be479e4ea42c46da649612342a680"
38
+ "gitHead": "341ea9eeca6afd1442fe6e01457bc21d112b91a4"
66
39
  }
package/src/index.test.ts CHANGED
@@ -1,78 +1,86 @@
1
- import { expect } from 'chai';
2
- import proxyquire from 'proxyquire';
1
+ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
3
2
  import * as sinon from "sinon";
4
3
 
5
- import crypto, {getPlatformId} from "./index";
4
+ import { Crypto, getPlatformId } from "./index";
6
5
 
7
- const secret = 'a test secret.. that is 16 x 2..';
8
- const data = {'foo': 'bar'};
9
- const encryptedData = "00000000000000000000000000000000:0543ec94d863fbf4b7a19b48e69d9317";
6
+ const secret = "a test secret.. that is 16 x 2..";
7
+ const data = { foo: "bar" };
8
+ const encryptedData =
9
+ "00000000000000000000000000000000:0543ec94d863fbf4b7a19b48e69d9317";
10
10
 
11
- describe('crypto', () => {
12
- let crypto;
13
- beforeEach(() => {
14
- crypto = proxyquire('./index', {
15
- crypto: {
16
- randomBytes: () => Buffer.alloc(16)
17
- }
18
- }).default;
19
- });
11
+ describe("crypto", () => {
12
+ let crypto;
13
+ beforeEach(() => {
14
+ class TestCrypto extends Crypto {
15
+ createRandomBytes() {
16
+ this.randomBytes = () => Buffer.alloc(16);
17
+ }
18
+ }
19
+ crypto = new TestCrypto();
20
+ });
20
21
 
21
- it('encrypts', () => {
22
- expect(crypto.encrypt(data, secret)).to.be.equal(encryptedData);
23
- });
22
+ it("encrypts", () => {
23
+ expect(crypto.encrypt(data, secret)).toEqual(encryptedData);
24
+ });
24
25
 
25
- it('decrypts', () => {
26
- expect(crypto.decrypt(encryptedData, secret)).to.eql(data);
27
- });
26
+ it("decrypts", () => {
27
+ expect(crypto.decrypt(encryptedData, secret)).toEqual(data);
28
+ });
28
29
 
29
- it('hashes', () => {
30
- expect(crypto.hash('foobar')).to.be.equal('8843d7f');
31
- });
30
+ it("hashes", () => {
31
+ expect(crypto.hash("foobar")).toEqual("8843d7f");
32
+ });
32
33
 
33
- it('randTokens 8', () => {
34
- const token = crypto.randToken(8);
35
- expect(token.length).to.be.equal(8);
36
- });
34
+ it("randTokens 8", () => {
35
+ const token = crypto.randToken(8);
36
+ expect(token.length).toEqual(8);
37
+ });
37
38
 
38
- it('randTokens 16', () => {
39
- const token = crypto.randToken(16);
40
- expect(token.length).to.be.equal(16);
41
- });
39
+ it("randTokens 16", () => {
40
+ const token = crypto.randToken(16);
41
+ expect(token.length).toEqual(16);
42
+ });
42
43
 
43
- it('randTokens 32', () => {
44
- const token = crypto.randToken(32);
45
- expect(token.length).to.be.equal(32);
46
- });
44
+ it("randTokens 32", () => {
45
+ const token = crypto.randToken(32);
46
+ expect(token.length).toEqual(32);
47
+ });
47
48
 
48
- it('randTokens 33+ will fail', () => {
49
- expect(() => {
50
- crypto.randToken(33);
51
- }).to.throw();
52
- });
49
+ it("randTokens 33+ will fail", () => {
50
+ expect(() => {
51
+ crypto.randToken(33);
52
+ }).toThrow();
53
+ });
53
54
  });
54
55
 
55
56
  describe("getPlatformId", () => {
56
- let cryptoHashStub: any;
57
+ let cryptoHashStub: any;
58
+ let crypto;
57
59
 
58
- beforeEach(() => {
59
- cryptoHashStub = sinon.stub(crypto, 'hash');
60
- cryptoHashStub.returnsArg(0);
61
- proxyquire('./index', { crypto: { hash: cryptoHashStub }});
62
- });
60
+ beforeEach(() => {
61
+ cryptoHashStub = sinon.mock();
62
+ class TestCrypto extends Crypto {
63
+ createRandomBytes() {
64
+ this.randomBytes = () => Buffer.alloc(16);
65
+ }
66
+ }
67
+ crypto = new TestCrypto();
68
+ cryptoHashStub = sinon.stub(crypto, "hash");
69
+ cryptoHashStub.returnsArg(0);
70
+ });
63
71
 
64
- afterEach(() => {
65
- cryptoHashStub.restore();
66
- });
72
+ afterEach(() => {
73
+ cryptoHashStub.restore();
74
+ });
67
75
 
68
- it('generates platform hash', () => {
69
- expect(getPlatformId('foo')).to.be.equal('foo');
70
- sinon.assert.calledOnce(cryptoHashStub);
71
- sinon.assert.calledWith(cryptoHashStub, 'foo');
72
- });
73
- it('generates platform + actor hash', () => {
74
- expect(getPlatformId('foo', 'bar')).to.be.equal('foobar');
75
- sinon.assert.calledOnce(cryptoHashStub);
76
- sinon.assert.calledWith(cryptoHashStub, 'foobar');
77
- });
78
- });
76
+ it("generates platform hash", () => {
77
+ expect(getPlatformId("foo", undefined, crypto)).toEqual("foo");
78
+ sinon.assert.calledOnce(cryptoHashStub);
79
+ sinon.assert.calledWith(cryptoHashStub, "foo");
80
+ });
81
+ it("generates platform + actor hash", () => {
82
+ expect(getPlatformId("foo", "bar", crypto)).toEqual("foobar");
83
+ sinon.assert.calledOnce(cryptoHashStub);
84
+ sinon.assert.calledWith(cryptoHashStub, "foobar");
85
+ });
86
+ });
package/src/index.ts CHANGED
@@ -1,53 +1,82 @@
1
- import { randomBytes, createCipheriv, createDecipheriv, createHash } from 'crypto';
2
- import {IActivityStream} from "@sockethub/schemas";
3
- import hash from 'object-hash';
1
+ import {
2
+ createCipheriv,
3
+ createDecipheriv,
4
+ createHash,
5
+ randomBytes,
6
+ } from "node:crypto";
7
+ import type { ActivityStream } from "@sockethub/schemas";
8
+ import hash from "object-hash";
4
9
 
5
- const ALGORITHM = 'aes-256-cbc',
6
- IV_LENGTH = 16; // For AES, this is always 16
10
+ const ALGORITHM = "aes-256-cbc";
11
+ const IV_LENGTH = 16; // For AES, this is always 16
7
12
 
8
- export function getPlatformId(platform: string, actor?: string): string {
9
- return actor ? crypto.hash(platform + actor) : crypto.hash(platform);
13
+ export function getPlatformId(
14
+ platform: string,
15
+ actor?: string,
16
+ _crypto = crypto,
17
+ ): string {
18
+ return actor ? _crypto.hash(platform + actor) : _crypto.hash(platform);
10
19
  }
11
20
 
12
- class Crypto {
13
-
14
- encrypt(json: IActivityStream, secret: string): string {
15
- const iv = randomBytes(IV_LENGTH);
16
- const cipher = createCipheriv(ALGORITHM, Buffer.from(secret), iv);
17
- let encrypted = cipher.update(JSON.stringify(json));
18
-
19
- encrypted = Buffer.concat([encrypted, cipher.final()]);
20
- return iv.toString('hex') + ':' + encrypted.toString('hex');
21
- }
22
-
23
- decrypt(text: string, secret: string): IActivityStream {
24
- const parts = text.split(':');
25
- const iv = Buffer.from(parts.shift(), 'hex');
26
- const encryptedText = Buffer.from(parts.join(':'), 'hex');
27
- const decipher = createDecipheriv(ALGORITHM, Buffer.from(secret), iv);
28
- let decrypted = decipher.update(encryptedText);
29
- decrypted = Buffer.concat([decrypted, decipher.final()]);
30
- return JSON.parse(decrypted.toString());
31
- }
32
-
33
- hash(text: string): string {
34
- const SHASum = createHash('sha1');
35
- SHASum.update(text);
36
- return SHASum.digest('hex').substring(0, 7);
37
- }
38
-
39
- objectHash(object: any): string {
40
- return hash(object);
41
- }
42
-
43
- randToken(len: number): string {
44
- if (len > 32) {
45
- throw new Error(`crypto.randToken supports a length param of up to 32, ${len} given`);
46
- }
47
- const buf = randomBytes(len);
48
- return buf.toString('hex').substring(0, len);
49
- }
21
+ export class Crypto {
22
+ randomBytes: typeof randomBytes;
23
+
24
+ constructor() {
25
+ this.createRandomBytes();
26
+ }
27
+
28
+ createRandomBytes() {
29
+ this.randomBytes = randomBytes;
30
+ }
31
+
32
+ encrypt(json: ActivityStream, secret: string): string {
33
+ Crypto.ensureSecret(secret);
34
+ const iv = this.randomBytes(IV_LENGTH);
35
+ const cipher = createCipheriv(ALGORITHM, Buffer.from(secret), iv);
36
+ let encrypted = cipher.update(JSON.stringify(json));
37
+
38
+ encrypted = Buffer.concat([encrypted, cipher.final()]);
39
+ return `${iv.toString("hex")}:${encrypted.toString("hex")}`;
40
+ }
41
+
42
+ decrypt(text: string, secret: string): ActivityStream {
43
+ Crypto.ensureSecret(secret);
44
+ const parts = text.split(":");
45
+ const iv = Buffer.from(parts.shift(), "hex");
46
+ const encryptedText = Buffer.from(parts.join(":"), "hex");
47
+ const decipher = createDecipheriv(ALGORITHM, Buffer.from(secret), iv);
48
+ let decrypted = decipher.update(encryptedText);
49
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
50
+ return JSON.parse(decrypted.toString());
51
+ }
52
+
53
+ hash(text: string): string {
54
+ const SHASum = createHash("sha1");
55
+ SHASum.update(text);
56
+ return SHASum.digest("hex").substring(0, 7);
57
+ }
58
+
59
+ objectHash(object: object): string {
60
+ return hash(object);
61
+ }
62
+
63
+ randToken(len: number): string {
64
+ if (len > 32) {
65
+ throw new Error(
66
+ `crypto.randToken supports a length param of up to 32, ${len} given`,
67
+ );
68
+ }
69
+ const buf = this.randomBytes(len);
70
+ return buf.toString("hex").substring(0, len);
71
+ }
72
+
73
+ private static ensureSecret(secret: string) {
74
+ if (secret.length !== 32) {
75
+ throw new Error(
76
+ `secret must be a 32 char string, length: ${secret.length}`,
77
+ );
78
+ }
79
+ }
50
80
  }
51
81
 
52
- const crypto = new Crypto();
53
- export default crypto;
82
+ export const crypto = new Crypto();
package/dist/index.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import { IActivityStream } from "@sockethub/schemas";
2
- export declare function getPlatformId(platform: string, actor?: string): string;
3
- declare class Crypto {
4
- encrypt(json: IActivityStream, secret: string): string;
5
- decrypt(text: string, secret: string): IActivityStream;
6
- hash(text: string): string;
7
- objectHash(object: any): string;
8
- randToken(len: number): string;
9
- }
10
- declare const crypto: Crypto;
11
- export default crypto;
package/dist/index.js DELETED
@@ -1,49 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getPlatformId = void 0;
7
- const crypto_1 = require("crypto");
8
- const object_hash_1 = __importDefault(require("object-hash"));
9
- const ALGORITHM = 'aes-256-cbc', IV_LENGTH = 16; // For AES, this is always 16
10
- function getPlatformId(platform, actor) {
11
- return actor ? crypto.hash(platform + actor) : crypto.hash(platform);
12
- }
13
- exports.getPlatformId = getPlatformId;
14
- class Crypto {
15
- encrypt(json, secret) {
16
- const iv = (0, crypto_1.randomBytes)(IV_LENGTH);
17
- const cipher = (0, crypto_1.createCipheriv)(ALGORITHM, Buffer.from(secret), iv);
18
- let encrypted = cipher.update(JSON.stringify(json));
19
- encrypted = Buffer.concat([encrypted, cipher.final()]);
20
- return iv.toString('hex') + ':' + encrypted.toString('hex');
21
- }
22
- decrypt(text, secret) {
23
- const parts = text.split(':');
24
- const iv = Buffer.from(parts.shift(), 'hex');
25
- const encryptedText = Buffer.from(parts.join(':'), 'hex');
26
- const decipher = (0, crypto_1.createDecipheriv)(ALGORITHM, Buffer.from(secret), iv);
27
- let decrypted = decipher.update(encryptedText);
28
- decrypted = Buffer.concat([decrypted, decipher.final()]);
29
- return JSON.parse(decrypted.toString());
30
- }
31
- hash(text) {
32
- const SHASum = (0, crypto_1.createHash)('sha1');
33
- SHASum.update(text);
34
- return SHASum.digest('hex').substring(0, 7);
35
- }
36
- objectHash(object) {
37
- return (0, object_hash_1.default)(object);
38
- }
39
- randToken(len) {
40
- if (len > 32) {
41
- throw new Error(`crypto.randToken supports a length param of up to 32, ${len} given`);
42
- }
43
- const buf = (0, crypto_1.randomBytes)(len);
44
- return buf.toString('hex').substring(0, len);
45
- }
46
- }
47
- const crypto = new Crypto();
48
- exports.default = crypto;
49
- //# sourceMappingURL=/index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":";;;;;;AAAA,mCAAmF;AAEnF,8DAA+B;AAE/B,MAAM,SAAS,GAAG,aAAa,EACzB,SAAS,GAAG,EAAE,CAAC,CAAC,6BAA6B;AAEnD,SAAgB,aAAa,CAAC,QAAgB,EAAE,KAAc;IAC5D,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACvE,CAAC;AAFD,sCAEC;AAED,MAAM,MAAM;IAEV,OAAO,CAAC,IAAqB,EAAE,MAAc;QAC3C,MAAM,EAAE,GAAG,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,IAAA,uBAAc,EAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAClE,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAEpD,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACvD,OAAO,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,CAAC,IAAY,EAAE,MAAc;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,IAAA,yBAAgB,EAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACtE,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC/C,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC,IAAY;QACf,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,UAAU,CAAC,MAAW;QACpB,OAAO,IAAA,qBAAI,EAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,IAAI,GAAG,GAAG,EAAE,EAAE;YACZ,MAAM,IAAI,KAAK,CAAC,yDAAyD,GAAG,QAAQ,CAAC,CAAC;SACvF;QACD,MAAM,GAAG,GAAG,IAAA,oBAAW,EAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;AAC5B,kBAAe,MAAM,CAAC"}