@sockethub/server 5.0.0-alpha.3

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.
Files changed (118) hide show
  1. package/LICENSE +165 -0
  2. package/README.md +136 -0
  3. package/bin/sockethub +3 -0
  4. package/coverage/tmp/coverage-93126-1649152190997-0.json +1 -0
  5. package/dist/bootstrap/init.d.ts +18 -0
  6. package/dist/bootstrap/init.js +63 -0
  7. package/dist/bootstrap/init.js.map +1 -0
  8. package/dist/bootstrap/platforms.js +75 -0
  9. package/dist/common.d.ts +3 -0
  10. package/dist/common.js +20 -0
  11. package/dist/common.js.map +1 -0
  12. package/dist/config.d.ts +6 -0
  13. package/dist/config.js +102 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/crypto.d.ts +10 -0
  16. package/dist/crypto.js +38 -0
  17. package/dist/crypto.js.map +1 -0
  18. package/dist/defaults.json +28 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +25 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/janitor.d.ts +15 -0
  23. package/dist/janitor.js +89 -0
  24. package/dist/janitor.js.map +1 -0
  25. package/dist/listener.d.ts +28 -0
  26. package/dist/listener.js +91 -0
  27. package/dist/listener.js.map +1 -0
  28. package/dist/middleware/create-activity-object.d.ts +6 -0
  29. package/dist/middleware/create-activity-object.js +19 -0
  30. package/dist/middleware/create-activity-object.js.map +1 -0
  31. package/dist/middleware/expand-activity-stream.d.ts +2 -0
  32. package/dist/middleware/expand-activity-stream.js +33 -0
  33. package/dist/middleware/expand-activity-stream.js.map +1 -0
  34. package/dist/middleware/expand-activity-stream.test.data.d.ts +480 -0
  35. package/dist/middleware/expand-activity-stream.test.data.js +360 -0
  36. package/dist/middleware/expand-activity-stream.test.data.js.map +1 -0
  37. package/dist/middleware/store-credentials.d.ts +3 -0
  38. package/dist/middleware/store-credentials.js +19 -0
  39. package/dist/middleware/store-credentials.js.map +1 -0
  40. package/dist/middleware/validate.d.ts +2 -0
  41. package/dist/middleware/validate.js +58 -0
  42. package/dist/middleware/validate.js.map +1 -0
  43. package/dist/middleware/validate.test.data.d.ts +532 -0
  44. package/dist/middleware/validate.test.data.js +263 -0
  45. package/dist/middleware/validate.test.data.js.map +1 -0
  46. package/dist/middleware.d.ts +10 -0
  47. package/dist/middleware.js +54 -0
  48. package/dist/middleware.js.map +1 -0
  49. package/dist/platform-instance.d.ts +77 -0
  50. package/dist/platform-instance.js +211 -0
  51. package/dist/platform-instance.js.map +1 -0
  52. package/dist/platform.d.ts +6 -0
  53. package/dist/platform.js +187 -0
  54. package/dist/platform.js.map +1 -0
  55. package/dist/process-manager.d.ts +11 -0
  56. package/dist/process-manager.js +78 -0
  57. package/dist/process-manager.js.map +1 -0
  58. package/dist/routes.d.ts +13 -0
  59. package/dist/routes.js +83 -0
  60. package/dist/routes.js.map +1 -0
  61. package/dist/sockethub.d.ts +39 -0
  62. package/dist/sockethub.js +119 -0
  63. package/dist/sockethub.js.map +1 -0
  64. package/dist/store.d.ts +5 -0
  65. package/dist/store.js +17 -0
  66. package/dist/store.js.map +1 -0
  67. package/package.json +103 -0
  68. package/sockethub.config.example.json +33 -0
  69. package/src/bootstrap/init.d.ts +8 -0
  70. package/src/bootstrap/init.ts +83 -0
  71. package/src/bootstrap/platforms.js +75 -0
  72. package/src/common.test.ts +54 -0
  73. package/src/common.ts +14 -0
  74. package/src/config.d.ts +2 -0
  75. package/src/config.test.ts +28 -0
  76. package/src/config.ts +94 -0
  77. package/src/crypto.d.ts +5 -0
  78. package/src/crypto.test.ts +41 -0
  79. package/src/crypto.ts +41 -0
  80. package/src/defaults.json +28 -0
  81. package/src/index.ts +28 -0
  82. package/src/janitor.d.ts +8 -0
  83. package/src/janitor.ts +89 -0
  84. package/src/listener.ts +79 -0
  85. package/src/middleware/create-activity-object.test.ts +10 -0
  86. package/src/middleware/create-activity-object.ts +13 -0
  87. package/src/middleware/expand-activity-stream.test.data.ts +365 -0
  88. package/src/middleware/expand-activity-stream.test.ts +78 -0
  89. package/src/middleware/expand-activity-stream.ts +27 -0
  90. package/src/middleware/store-credentials.test.ts +73 -0
  91. package/src/middleware/store-credentials.ts +16 -0
  92. package/src/middleware/validate.d.ts +1 -0
  93. package/src/middleware/validate.test.data.ts +261 -0
  94. package/src/middleware/validate.test.ts +83 -0
  95. package/src/middleware/validate.ts +49 -0
  96. package/src/middleware.d.ts +21 -0
  97. package/src/middleware.test.ts +154 -0
  98. package/src/middleware.ts +52 -0
  99. package/src/platform-instance.test.ts +237 -0
  100. package/src/platform-instance.ts +242 -0
  101. package/src/platform.ts +191 -0
  102. package/src/process-manager.ts +64 -0
  103. package/src/routes.test.ts +100 -0
  104. package/src/routes.ts +98 -0
  105. package/src/sockethub.d.ts +1 -0
  106. package/src/sockethub.ts +165 -0
  107. package/src/store.test.ts +28 -0
  108. package/src/store.ts +17 -0
  109. package/test/init-suite.js +41 -0
  110. package/test/queue.functional.test.js +0 -0
  111. package/test/sockethub-suite.js +25 -0
  112. package/tsconfig.json +18 -0
  113. package/views/examples/dummy.ejs +93 -0
  114. package/views/examples/feeds.ejs +90 -0
  115. package/views/examples/irc.ejs +239 -0
  116. package/views/examples/shared.js +72 -0
  117. package/views/examples/xmpp.ejs +191 -0
  118. package/views/index.ejs +17 -0
package/package.json ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "name": "@sockethub/server",
3
+ "description": "A polyglot messaging service, server libraries",
4
+ "version": "5.0.0-alpha.3",
5
+ "private": false,
6
+ "author": "Nick Jennings <nick@silverbucket.net>",
7
+ "license": "LGPL-3.0+",
8
+ "main": "dist/index.js",
9
+ "bin": "bin/sockethub",
10
+ "preferGlobal": true,
11
+ "keywords": [
12
+ "sockethub",
13
+ "messaging",
14
+ "polyglot",
15
+ "unhosted",
16
+ "apis",
17
+ "api",
18
+ "protocols",
19
+ "protocol",
20
+ "irc",
21
+ "xmpp",
22
+ "facebook",
23
+ "rss",
24
+ "atom",
25
+ "twitter",
26
+ "smtp",
27
+ "imap",
28
+ "email"
29
+ ],
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/sockethub/sockethub.git",
33
+ "directory": "packages/server"
34
+ },
35
+ "homepage": "https://sockethub.org",
36
+ "dependencies": {
37
+ "@sockethub/activity-streams": "^4.4.0-alpha.3",
38
+ "@sockethub/client": "^5.0.0-alpha.3",
39
+ "@sockethub/schemas": "^3.0.0-alpha.3",
40
+ "body-parser": "^1.19.0",
41
+ "bull": "^4.0.0",
42
+ "debug": "^4.3.1",
43
+ "ejs": "^3.0.1",
44
+ "express": "^4.17.1",
45
+ "findup-sync": "^5.0.0",
46
+ "jquery": "^3.4.1",
47
+ "nconf": "^0.11.2",
48
+ "npm": "8.5.4",
49
+ "object-hash": "^3.0.0",
50
+ "secure-store-redis": "^1.4.7",
51
+ "socket.io": "^4.0.1",
52
+ "urijs": "^1.19.2"
53
+ },
54
+ "scripts": {
55
+ "clean": "npx rimraf dist coverage",
56
+ "clean:deps": "npx rimraf node_modules",
57
+ "compliance": "yarn run lint && yarn run test && yarn run coverage",
58
+ "test": "c8 -x src/bootstrap -x \"src/**/*.test.*\" mocha -r ts-node/register src/*.test.ts src/**/*.test.ts",
59
+ "coverage": "c8 check-coverage --statements 90 --branches 80 --functions 90 --lines 90",
60
+ "start": "DEBUG=sockethub* ./bin/sockethub",
61
+ "dev": "yarn run build && DEBUG=sockethub* ./bin/sockethub --examples",
62
+ "lint": "eslint \"**/*.ts\" ./bin/sockethub",
63
+ "lint:fix": "eslint --fix \"**/*.ts\" ./bin/sockethub",
64
+ "build": "npx rimraf dist && tsc && cp ./src/defaults.json ./dist/defaults.json && cp src/bootstrap/platforms.js dist/bootstrap/"
65
+ },
66
+ "engines": {
67
+ "node": ">= 12.4.0"
68
+ },
69
+ "devDependencies": {
70
+ "@types/body-parser": "1.19.2",
71
+ "@types/chai": "4.3.0",
72
+ "@types/debug": "4.1.7",
73
+ "@types/ejs": "3.1.0",
74
+ "@types/eslint": "8.4.1",
75
+ "@types/express": "4.17.13",
76
+ "@types/jquery": "3.5.13",
77
+ "@types/mocha": "9.1.0",
78
+ "@types/nconf": "0.10.1",
79
+ "@types/node": "17.0.13",
80
+ "@types/object-hash": "2.2.1",
81
+ "@types/proxyquire": "1.3.28",
82
+ "@types/sinon": "10.0.11",
83
+ "@types/urijs": "1.19.18",
84
+ "@typescript-eslint/parser": "5.12.1",
85
+ "c8": "7.11.0",
86
+ "chai": "4.3.6",
87
+ "eslint": "8.9.0",
88
+ "eslint-cli": "1.1.1",
89
+ "jaribu": "2.2.3",
90
+ "mocha": "9.2.1",
91
+ "proxyquire": "2.1.3",
92
+ "sinon": "13.0.1",
93
+ "ts-node": "10.5.0",
94
+ "typescript": "4.5.5"
95
+ },
96
+ "optionalDependencies": {
97
+ "@sockethub/platform-dummy": "^3.0.0-alpha.3",
98
+ "@sockethub/platform-feeds": "^3.0.0-alpha.3",
99
+ "@sockethub/platform-irc": "^4.0.0-alpha.3",
100
+ "@sockethub/platform-xmpp": "^5.0.0-alpha.3"
101
+ },
102
+ "gitHead": "f02238a478b7ffd3f31d8deea292eb67e630a86b"
103
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "activity-streams": {
3
+ "opts": {
4
+ "specialObjs": [ "credentials" ]
5
+ }
6
+ },
7
+ "examples": {
8
+ "enabled": false,
9
+ "secret": 1234567890
10
+ },
11
+ "sockethub": {
12
+ "port": 10550,
13
+ "host": "localhost",
14
+ "path": "/sockethub"
15
+ },
16
+ "log_file": "",
17
+ "platforms": [
18
+ "@sockethub/platform-dummy",
19
+ "@sockethub/platform-feeds",
20
+ "@sockethub/platform-irc",
21
+ "@sockethub/platform-xmpp"
22
+ ],
23
+ "public": {
24
+ "protocol": "http",
25
+ "host": "localhost",
26
+ "port": 10550,
27
+ "path": "/"
28
+ },
29
+ "redis": {
30
+ "host": "127.0.0.1",
31
+ "port": 6379
32
+ }
33
+ }
@@ -0,0 +1,8 @@
1
+ declare const init: {
2
+ version: any;
3
+ platforms: Map<any, any>;
4
+ host: any;
5
+ port: any;
6
+ path: any;
7
+ };
8
+ export default init;
@@ -0,0 +1,83 @@
1
+ import debug from 'debug';
2
+
3
+ import config from '../config';
4
+ import platformLoad from './platforms';
5
+
6
+ const log = debug('sockethub:server:bootstrap:init');
7
+ log('running init routines');
8
+
9
+ const packageJSON = require('./../../package.json');
10
+ const platforms = platformLoad(config.get('platforms'));
11
+
12
+ if (config.get('info')) {
13
+ // eslint-disable-next-line security-node/detect-crlf
14
+ console.log('sockethub ' + packageJSON.version);
15
+ console.log();
16
+
17
+ // eslint-disable-next-line security-node/detect-crlf
18
+ console.log('websocket: ws://' + config.get('sockethub:host') + ':'
19
+ + config.get('sockethub:port')
20
+ + config.get('sockethub:path'));
21
+
22
+ console.log();
23
+ // eslint-disable-next-line security-node/detect-crlf
24
+ console.log('examples: ' + (config.get('examples:enabled') ?
25
+ 'http://' +
26
+ config.get('public:host') + ':' + config.get('public:port') + config.get('public:path')
27
+ : 'disabled'));
28
+
29
+ console.log();
30
+ if (config.get('redis:url')) {
31
+ // eslint-disable-next-line security-node/detect-crlf
32
+ console.log('redis URL: ' + config.get('redis:url'));
33
+ } else {
34
+ // eslint-disable-next-line security-node/detect-crlf
35
+ console.log('redis: ' + config.get('redis:host') + ':' + config.get('redis:port'));
36
+ }
37
+
38
+ console.log();
39
+ // eslint-disable-next-line security-node/detect-crlf
40
+ console.log('platforms: ' + Array.from(platforms.keys()).join(', '));
41
+
42
+ if (platforms.size > 0) {
43
+ for (let platform of platforms.values()) {
44
+ console.log();
45
+ // eslint-disable-next-line security-node/detect-crlf
46
+ console.log(platform.moduleName);
47
+ // eslint-disable-next-line security-node/detect-crlf
48
+ console.log(' name: ' + platform.id + ' version: ' + platform.version);
49
+ // eslint-disable-next-line security-node/detect-crlf
50
+ console.log(' AS types: ' + platform.types.join(', '));
51
+ }
52
+ console.log();
53
+ process.exit();
54
+ } else {
55
+ console.log();
56
+ process.exit();
57
+ }
58
+ }
59
+
60
+ log('finished init routines');
61
+
62
+ export interface IInitObject {
63
+ version: string,
64
+ platforms: Map<string, {
65
+ id: string,
66
+ moduleName: string,
67
+ config: {
68
+ persist?: boolean
69
+ },
70
+ schemas: {
71
+ credentials?: object,
72
+ messages?: object
73
+ },
74
+ version: string,
75
+ types: Array<string>
76
+ }>,
77
+ }
78
+
79
+ const init: IInitObject = {
80
+ version: packageJSON.version,
81
+ platforms: platforms
82
+ };
83
+ export default init;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * bootstrap/platforms.js
3
+ *
4
+ * A Singleton responsible for finding and loading all valid Sockethub
5
+ * platforms, and whitelisting or blacklisting (or neither) based on the
6
+ * config.
7
+ */
8
+ const debug = require('debug'),
9
+ schemas = require('@sockethub/schemas').default;
10
+
11
+ const log = debug('sockethub:server:bootstrap:platforms');
12
+
13
+ log('loading platforms');
14
+
15
+ // if the platform schema lists valid types it implements (essentially methods/verbs for
16
+ // Sockethub to call) then add it to the supported types list.
17
+ function platformListsSupportedTypes(p) {
18
+ return ((p.schema.messages.properties) && (p.schema.messages.properties.type) &&
19
+ (p.schema.messages.properties.type.enum) &&
20
+ (p.schema.messages.properties.type.enum.length > 0));
21
+ }
22
+
23
+ module.exports = function platformLoad(platformsList, requireModule) {
24
+ if (!requireModule) {
25
+ requireModule = require;
26
+ }
27
+ // load platforms from config.platforms
28
+ const platforms = new Map();
29
+
30
+ if (platformsList.length <= 0) {
31
+ throw new Error('No platforms defined. Please check your sockethub.config.json');
32
+ }
33
+
34
+ for (let moduleName of platformsList) {
35
+ log(`loading ${moduleName}`);
36
+ // try to load platform
37
+ // eslint-disable-next-line security-node/detect-non-literal-require-calls
38
+ const P = requireModule(moduleName);
39
+ const p = new P();
40
+ let types = [];
41
+
42
+ const err = schemas.validatePlatformSchema(p.schema);
43
+ if (err) {
44
+ throw new Error(`${moduleName} ${err}`);
45
+ } else if (typeof p.config !== 'object') {
46
+ throw new Error(
47
+ `${moduleName} platform must have a config property that is an object.`);
48
+ } else {
49
+ if (p.schema.credentials) {
50
+ // register the platforms credentials schema
51
+ types.push('credentials');
52
+ } else {
53
+ p.config.noCredentials = true;
54
+ }
55
+ }
56
+
57
+ if (platformListsSupportedTypes(p)) {
58
+ types = [...types, ...p.schema.messages.properties.type.enum];
59
+ }
60
+
61
+ const platformName = p.schema.name;
62
+ platforms.set(platformName, {
63
+ id: platformName,
64
+ moduleName: moduleName,
65
+ config: p.config,
66
+ schemas: {
67
+ credentials: p.schema.credentials || {},
68
+ messages: p.schema.messages || {}
69
+ },
70
+ version: p.schema.version,
71
+ types: types
72
+ });
73
+ }
74
+ return platforms;
75
+ };
@@ -0,0 +1,54 @@
1
+ import proxyquire from 'proxyquire';
2
+ import { expect } from 'chai';
3
+ import * as sinon from 'sinon';
4
+
5
+ import { decryptJobData, getPlatformId } from './common';
6
+ import crypto from './crypto';
7
+
8
+ proxyquire.noPreserveCache();
9
+ proxyquire.noCallThru();
10
+
11
+ describe("getPlatformId", () => {
12
+ let cryptoHashStub: any;
13
+
14
+ beforeEach(() => {
15
+ cryptoHashStub = sinon.stub(crypto, 'hash');
16
+ cryptoHashStub.returnsArg(0);
17
+ proxyquire('./common', { crypto: { hash: cryptoHashStub }});
18
+ });
19
+
20
+ afterEach(() => {
21
+ cryptoHashStub.restore();
22
+ });
23
+
24
+ it('generates platform hash', () => {
25
+ expect(getPlatformId('foo')).to.be.equal('foo');
26
+ sinon.assert.calledOnce(cryptoHashStub);
27
+ sinon.assert.calledWith(cryptoHashStub, 'foo');
28
+ });
29
+ it('generates platform + actor hash', () => {
30
+ expect(getPlatformId('foo', 'bar')).to.be.equal('foobar');
31
+ sinon.assert.calledOnce(cryptoHashStub);
32
+ sinon.assert.calledWith(cryptoHashStub, 'foobar');
33
+ });
34
+ });
35
+
36
+ describe("decryptJobData", () => {
37
+ let cryptoDecryptStub: any;
38
+
39
+ beforeEach(() => {
40
+ cryptoDecryptStub = sinon.stub(crypto, 'decrypt');
41
+ cryptoDecryptStub.returnsArg(0);
42
+ proxyquire('./common', { crypto: { hash: cryptoDecryptStub }});
43
+ });
44
+
45
+ afterEach(() => {
46
+ cryptoDecryptStub.restore();
47
+ });
48
+
49
+ it("decrypts and returns expected object", () => {
50
+ const jobData = {data:{title:"foo", msg:'encryptedjobdata', sessionId:'foobar'}};
51
+ const secret = 'secretstring';
52
+ expect(decryptJobData(jobData, secret)).to.be.eql(jobData.data);
53
+ });
54
+ });
package/src/common.ts ADDED
@@ -0,0 +1,14 @@
1
+ import crypto from "./crypto";
2
+ import { JobDataDecrypted, JobEncrypted } from "./sockethub";
3
+
4
+ export function getPlatformId(platform: string, actor?: string): string {
5
+ return actor ? crypto.hash(platform + actor) : crypto.hash(platform);
6
+ }
7
+
8
+ export function decryptJobData(job: JobEncrypted, secret: string): JobDataDecrypted {
9
+ return {
10
+ title: job.data.title,
11
+ msg: crypto.decrypt(job.data.msg, secret),
12
+ sessionId: job.data.sessionId
13
+ };
14
+ }
@@ -0,0 +1,2 @@
1
+ declare let config: any;
2
+ export default config;
@@ -0,0 +1,28 @@
1
+ import { expect } from 'chai';
2
+
3
+ import { Config } from './config';
4
+
5
+ describe('config', () => {
6
+
7
+ it('loads default values', () => {
8
+ const config = new Config();
9
+ expect(config).to.have.property('get');
10
+ expect(config.get('sockethub:host')).to.eql('localhost');
11
+ });
12
+
13
+ it('overrides from env', () => {
14
+ const hostname = 'a host string';
15
+ process.env = { HOST: hostname };
16
+ const config = new Config();
17
+ expect(config).to.have.property('get');
18
+ expect(config.get('sockethub:host')).to.eql(hostname);
19
+ });
20
+
21
+ it('defaults to redis config', () => {
22
+ process.env = { REDIS_URL: '' };
23
+ const config = new Config();
24
+ expect(config).to.have.property('get');
25
+ expect(config.get('redis')).to.eql(
26
+ {"host": "127.0.0.1", "port": 6379});
27
+ });
28
+ });
package/src/config.ts ADDED
@@ -0,0 +1,94 @@
1
+ import nconf from 'nconf';
2
+ import { debug } from 'debug';
3
+ import * as fs from "fs";
4
+
5
+ const log = debug('sockethub:server:bootstrap:config');
6
+
7
+ export class Config {
8
+ constructor() {
9
+ log('initializing config');
10
+ // assign config loading priorities (command-line, environment, cfg, defaults)
11
+ nconf.argv({
12
+ 'info': {
13
+ type: 'boolean',
14
+ describe: 'Display Sockethub runtime information'
15
+ },
16
+ 'examples': {
17
+ type: 'boolean',
18
+ describe: 'Enable the examples pages served at [host]:[port]/examples'
19
+ },
20
+ 'config': {
21
+ alias: 'c',
22
+ default: '',
23
+ describe: 'Path to sockethub.config.json'
24
+ },
25
+ 'port': {
26
+ alias: 'sockethub.port'
27
+ },
28
+ 'host': {
29
+ alias: 'sockethub.host'
30
+ },
31
+ 'redis_host': {
32
+ alias: 'redis.host'
33
+ },
34
+ 'redis_port': {
35
+ alias: 'redis.port'
36
+ },
37
+ 'redis_url': {
38
+ alias: 'redis.url'
39
+ }
40
+ });
41
+ nconf.env();
42
+
43
+ // get value of flags defined by any command-line params
44
+ const examples = nconf.get('examples');
45
+
46
+ // Load the main config
47
+ let configFile = nconf.get('config');
48
+ if (configFile) {
49
+ if (! fs.existsSync(configFile)) {
50
+ throw new Error(`Config file not found: ${configFile}`);
51
+ }
52
+ } else {
53
+ configFile = __dirname + '/../sockethub.config.json';
54
+ }
55
+ nconf.file(configFile);
56
+
57
+ // only override config file if explicitly mentioned in command-line params
58
+ nconf.set('examples:enabled', (examples ? true : nconf.get('examples:enabled')));
59
+
60
+ // load defaults
61
+ const defaults: object = require(__dirname + '/defaults.json');
62
+ nconf.defaults(defaults);
63
+
64
+ nconf.required(['platforms']);
65
+
66
+ function defaultEnvParams(host: string, port: string | number, prop: string) {
67
+ nconf.set(prop + ':host', host);
68
+ nconf.set(prop + ':port', port);
69
+ }
70
+
71
+ defaultEnvParams(
72
+ process.env.HOST || nconf.get('sockethub:host'),
73
+ process.env.PORT || nconf.get('sockethub:port'),
74
+ 'sockethub'
75
+ );
76
+
77
+ defaultEnvParams(
78
+ process.env.REDIS_HOST || nconf.get('redis:host'),
79
+ process.env.REDIS_PORT || nconf.get('redis:port'),
80
+ 'redis'
81
+ );
82
+
83
+ // allow a redis://user:host:port url, takes precedence
84
+ if (process.env.REDIS_URL) {
85
+ nconf.set('redis:url', process.env.REDIS_URL);
86
+ nconf.clear('redis:host');
87
+ nconf.clear('redis:port');
88
+ }
89
+ }
90
+ get = (key: string): any => nconf.get(key);
91
+ }
92
+
93
+ const config = new Config();
94
+ export default config;
@@ -0,0 +1,5 @@
1
+ declare const crypto: {
2
+ encrypt: (json: any, secret: any) => string;
3
+ decrypt: (string: any, secret: any) => any;
4
+ };
5
+ export default crypto;
@@ -0,0 +1,41 @@
1
+ import { expect } from 'chai';
2
+ import proxyquire from 'proxyquire';
3
+
4
+ const crypto = proxyquire('./crypto', {
5
+ 'crypto': {
6
+ randomBytes: () => Buffer.alloc(16)
7
+ }
8
+ }).default;
9
+
10
+ const secret = 'a test secret.. that is 16 x 2..';
11
+ const data = {'foo': 'bar'};
12
+ const encryptedData = "00000000000000000000000000000000:0543ec94d863fbf4b7a19b48e69d9317";
13
+
14
+ describe('crypto', () => {
15
+ it('encrypts', () => {
16
+ expect(crypto.encrypt(data, secret)).to.be.equal(encryptedData);
17
+ });
18
+ it('decrypts', () => {
19
+ expect(crypto.decrypt(encryptedData, secret)).to.eql(data);
20
+ });
21
+ it('hashes', () => {
22
+ expect(crypto.hash('foobar')).to.be.equal('8843d7f');
23
+ });
24
+ it('randTokens 8', () => {
25
+ const token = crypto.randToken(8);
26
+ expect(token.length).to.be.equal(8);
27
+ });
28
+ it('randTokens 16', () => {
29
+ const token = crypto.randToken(16);
30
+ expect(token.length).to.be.equal(16);
31
+ });
32
+ it('randTokens 32', () => {
33
+ const token = crypto.randToken(32);
34
+ expect(token.length).to.be.equal(32);
35
+ });
36
+ it('randTokens 33+ will fail', () => {
37
+ expect(() => {
38
+ crypto.randToken(33);
39
+ }).to.throw();
40
+ });
41
+ });
package/src/crypto.ts ADDED
@@ -0,0 +1,41 @@
1
+ import { randomBytes, createCipheriv, createDecipheriv, createHash } from 'crypto';
2
+ import { IActivityStream } from "@sockethub/schemas";
3
+
4
+ const ALGORITHM = 'aes-256-cbc',
5
+ IV_LENGTH = 16; // For AES, this is always 16
6
+
7
+ class Crypto {
8
+ constructor() {}
9
+ encrypt(json: IActivityStream, secret: string): string {
10
+ const iv = randomBytes(IV_LENGTH);
11
+ const cipher = createCipheriv(ALGORITHM, Buffer.from(secret), iv);
12
+ let encrypted = cipher.update(JSON.stringify(json));
13
+
14
+ encrypted = Buffer.concat([encrypted, cipher.final()]);
15
+ return iv.toString('hex') + ':' + encrypted.toString('hex');
16
+ }
17
+ decrypt(text: string, secret: string): IActivityStream {
18
+ let parts = text.split(':');
19
+ const iv = Buffer.from(parts.shift(), 'hex');
20
+ const encryptedText = Buffer.from(parts.join(':'), 'hex');
21
+ const decipher = createDecipheriv(ALGORITHM, Buffer.from(secret), iv);
22
+ let decrypted = decipher.update(encryptedText);
23
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
24
+ return JSON.parse(decrypted.toString());
25
+ }
26
+ hash(text: string): string {
27
+ const shasum = createHash('sha1');
28
+ shasum.update(text);
29
+ return shasum.digest('hex').substring(0, 7);
30
+ }
31
+ randToken(len: number): string {
32
+ if (len > 32) {
33
+ throw new Error(`crypto.randToken supports a length param of up to 32, ${len} given`);
34
+ }
35
+ const buf = randomBytes(len);
36
+ return buf.toString('hex').substring(0, len);
37
+ }
38
+ }
39
+
40
+ const crypto = new Crypto();
41
+ export default crypto;
@@ -0,0 +1,28 @@
1
+ {
2
+ "activity-streams": {
3
+ "opts": {
4
+ "specialObjs": [ "credentials" ]
5
+ }
6
+ },
7
+ "examples": {
8
+ "enabled": false,
9
+ "secret": 1234567890
10
+ },
11
+ "sockethub": {
12
+ "port": 10550,
13
+ "host": "localhost",
14
+ "path": "/sockethub"
15
+ },
16
+ "log_file": "",
17
+ "platforms": [],
18
+ "public": {
19
+ "protocol": "http",
20
+ "host": "localhost",
21
+ "port": 10550,
22
+ "path": "/"
23
+ },
24
+ "redis": {
25
+ "host": "127.0.0.1",
26
+ "port": 6379
27
+ }
28
+ }
package/src/index.ts ADDED
@@ -0,0 +1,28 @@
1
+ const Sockethub = require('./sockethub').default;
2
+ const sockethub = new Sockethub();
3
+
4
+ module.exports = async () => {
5
+ process.once('uncaughtException', function (err) {
6
+ console.log('UNCAUGHT EXCEPTION');
7
+ // eslint-disable-next-line security-node/detect-crlf
8
+ console.log(err.stack);
9
+ process.exit(1);
10
+ });
11
+
12
+ process.once('SIGTERM', function () {
13
+ console.log('Received TERM signal. Exiting.');
14
+ process.exit(0);
15
+ });
16
+
17
+ process.once('SIGINT', function () {
18
+ console.log('Received INT signal. Exiting.');
19
+ process.exit(0);
20
+ });
21
+
22
+ process.once('exit', async function () {
23
+ console.log('destroying all platform instances');
24
+ await sockethub.removeAllPlatformInstances();
25
+ });
26
+
27
+ sockethub.boot();
28
+ };
@@ -0,0 +1,8 @@
1
+ declare function janitorCycle(): void;
2
+ declare const janitor: {
3
+ start: typeof janitorCycle;
4
+ alreadyCalled: boolean;
5
+ cycleCount: number;
6
+ reportCount: number;
7
+ };
8
+ export default janitor;