@sockethub/server 5.0.0-alpha.4 → 5.0.0-alpha.6

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 (105) hide show
  1. package/README.md +54 -60
  2. package/bin/sockethub +4 -3
  3. package/package.json +42 -54
  4. package/res/socket.io.js +4908 -0
  5. package/res/sockethub-client.js +602 -0
  6. package/res/sockethub-client.min.js +19 -0
  7. package/sockethub.config.example.json +2 -3
  8. package/src/bootstrap/init.d.ts +16 -13
  9. package/src/bootstrap/init.test.ts +211 -0
  10. package/src/bootstrap/init.ts +152 -76
  11. package/src/bootstrap/load-platforms.ts +151 -0
  12. package/src/config.test.ts +27 -22
  13. package/src/config.ts +82 -86
  14. package/src/defaults.json +24 -16
  15. package/src/index.ts +61 -22
  16. package/src/janitor.test.ts +191 -169
  17. package/src/janitor.ts +141 -118
  18. package/src/listener.ts +148 -58
  19. package/src/middleware/create-activity-object.test.ts +28 -8
  20. package/src/middleware/create-activity-object.ts +16 -10
  21. package/src/middleware/expand-activity-stream.test.data.ts +331 -345
  22. package/src/middleware/expand-activity-stream.test.ts +65 -66
  23. package/src/middleware/expand-activity-stream.ts +26 -21
  24. package/src/middleware/store-credentials.test.ts +74 -60
  25. package/src/middleware/store-credentials.ts +14 -8
  26. package/src/middleware/validate.test.data.ts +240 -242
  27. package/src/middleware/validate.test.ts +39 -78
  28. package/src/middleware/validate.ts +62 -36
  29. package/src/middleware.test.ts +168 -138
  30. package/src/middleware.ts +57 -55
  31. package/src/platform-instance.test.ts +508 -214
  32. package/src/platform-instance.ts +324 -231
  33. package/src/platform.test.ts +375 -0
  34. package/src/platform.ts +306 -117
  35. package/src/process-manager.ts +75 -51
  36. package/src/routes.test.ts +43 -89
  37. package/src/routes.ts +40 -78
  38. package/src/sentry.test.ts +106 -0
  39. package/src/sentry.ts +19 -0
  40. package/src/sockethub.ts +190 -129
  41. package/src/util.ts +5 -0
  42. package/coverage/tmp/coverage-39338-1663949520416-0.json +0 -1
  43. package/dist/bootstrap/init.d.ts +0 -18
  44. package/dist/bootstrap/init.js +0 -64
  45. package/dist/bootstrap/init.js.map +0 -1
  46. package/dist/bootstrap/platforms.js +0 -75
  47. package/dist/config.d.ts +0 -12
  48. package/dist/config.js +0 -107
  49. package/dist/config.js.map +0 -1
  50. package/dist/defaults.json +0 -28
  51. package/dist/index.d.ts +0 -1
  52. package/dist/index.js +0 -29
  53. package/dist/index.js.map +0 -1
  54. package/dist/janitor.d.ts +0 -30
  55. package/dist/janitor.js +0 -120
  56. package/dist/janitor.js.map +0 -1
  57. package/dist/listener.d.ts +0 -31
  58. package/dist/listener.js +0 -94
  59. package/dist/listener.js.map +0 -1
  60. package/dist/middleware/create-activity-object.d.ts +0 -8
  61. package/dist/middleware/create-activity-object.js +0 -19
  62. package/dist/middleware/create-activity-object.js.map +0 -1
  63. package/dist/middleware/expand-activity-stream.d.ts +0 -3
  64. package/dist/middleware/expand-activity-stream.js +0 -36
  65. package/dist/middleware/expand-activity-stream.js.map +0 -1
  66. package/dist/middleware/expand-activity-stream.test.data.d.ts +0 -480
  67. package/dist/middleware/expand-activity-stream.test.data.js +0 -360
  68. package/dist/middleware/expand-activity-stream.test.data.js.map +0 -1
  69. package/dist/middleware/store-credentials.d.ts +0 -3
  70. package/dist/middleware/store-credentials.js +0 -9
  71. package/dist/middleware/store-credentials.js.map +0 -1
  72. package/dist/middleware/validate.d.ts +0 -2
  73. package/dist/middleware/validate.js +0 -56
  74. package/dist/middleware/validate.js.map +0 -1
  75. package/dist/middleware/validate.test.data.d.ts +0 -532
  76. package/dist/middleware/validate.test.data.js +0 -263
  77. package/dist/middleware/validate.test.data.js.map +0 -1
  78. package/dist/middleware.d.ts +0 -21
  79. package/dist/middleware.js +0 -56
  80. package/dist/middleware.js.map +0 -1
  81. package/dist/platform-instance.d.ts +0 -78
  82. package/dist/platform-instance.js +0 -226
  83. package/dist/platform-instance.js.map +0 -1
  84. package/dist/platform.d.ts +0 -6
  85. package/dist/platform.js +0 -176
  86. package/dist/platform.js.map +0 -1
  87. package/dist/process-manager.d.ts +0 -11
  88. package/dist/process-manager.js +0 -82
  89. package/dist/process-manager.js.map +0 -1
  90. package/dist/routes.d.ts +0 -13
  91. package/dist/routes.js +0 -83
  92. package/dist/routes.js.map +0 -1
  93. package/dist/sockethub.d.ts +0 -18
  94. package/dist/sockethub.js +0 -112
  95. package/dist/sockethub.js.map +0 -1
  96. package/src/bootstrap/platforms.js +0 -75
  97. package/test/init-suite.js +0 -41
  98. package/test/sockethub-suite.js +0 -25
  99. package/tsconfig.json +0 -18
  100. package/views/examples/dummy.ejs +0 -95
  101. package/views/examples/feeds.ejs +0 -90
  102. package/views/examples/irc.ejs +0 -239
  103. package/views/examples/shared.js +0 -72
  104. package/views/examples/xmpp.ejs +0 -217
  105. package/views/index.ejs +0 -17
package/src/sockethub.ts CHANGED
@@ -1,137 +1,198 @@
1
- import debug from 'debug';
2
- import {Socket} from "socket.io";
3
- import crypto from "@sockethub/crypto";
4
- import {CredentialsStore} from "@sockethub/data-layer";
5
-
6
- import init from './bootstrap/init';
7
- import middleware, {MiddlewareChainInterface} from './middleware';
8
- import createActivityObject from "./middleware/create-activity-object";
9
- import expandActivityStream from "./middleware/expand-activity-stream";
10
- import storeCredentials from "./middleware/store-credentials";
11
- import validate from "./middleware/validate";
12
- import janitor from './janitor';
13
- import listener from './listener';
14
- import ProcessManager from "./process-manager";
15
- import nconf from "nconf";
16
- import {IActivityStream} from "@sockethub/schemas";
17
-
18
- const log = debug('sockethub:server:core');
19
-
20
- function attachError(err, msg) {
21
- if (typeof msg !== 'object') {
22
- msg = { context: 'error' };
23
- }
24
- msg.error = err.toString();
25
- delete msg.sessionSecret;
26
- return msg;
1
+ import debug from "debug";
2
+ import type { Socket } from "socket.io";
3
+
4
+ import { crypto } from "@sockethub/crypto";
5
+ import { CredentialsStore } from "@sockethub/data-layer";
6
+ import type { CredentialsStoreInterface } from "@sockethub/data-layer";
7
+ import type {
8
+ ActivityStream,
9
+ InternalActivityStream,
10
+ } from "@sockethub/schemas";
11
+
12
+ import getInitObject from "./bootstrap/init.js";
13
+ import config from "./config";
14
+ import janitor from "./janitor.js";
15
+ import listener from "./listener.js";
16
+ import middleware from "./middleware.js";
17
+ import createActivityObject from "./middleware/create-activity-object.js";
18
+ import expandActivityStream from "./middleware/expand-activity-stream.js";
19
+ import storeCredentials from "./middleware/store-credentials.js";
20
+ import validate from "./middleware/validate.js";
21
+ import ProcessManager from "./process-manager.js";
22
+
23
+ const log = debug("sockethub:server:core");
24
+
25
+ type ErrMsg = {
26
+ context: string;
27
+ error: string;
28
+ content: object;
29
+ };
30
+
31
+ function attachError(err: unknown, msg: InternalActivityStream | undefined) {
32
+ const finalError: ErrMsg = {
33
+ context: "error",
34
+ error: err.toString(),
35
+ content: {},
36
+ };
37
+
38
+ // biome-ignore lint/performance/noDelete: <explanation>
39
+ delete msg.sessionSecret;
40
+
41
+ if (msg) {
42
+ finalError.content = msg;
43
+ }
44
+ return finalError;
27
45
  }
28
46
 
29
47
  class Sockethub {
30
- private readonly parentId: string;
31
- private readonly parentSecret1: string;
32
- private readonly parentSecret2: string;
33
- counter: number;
34
- platforms: Map<string, object>;
35
- status: boolean;
36
- processManager: ProcessManager;
37
-
38
- constructor() {
39
- this.platforms = init.platforms;
40
- this.status = false;
41
- this.parentId = crypto.randToken(16);
42
- this.parentSecret1 = crypto.randToken(16);
43
- this.parentSecret2 = crypto.randToken(16);
44
- this.processManager = new ProcessManager(
45
- this.parentId, this.parentSecret1, this.parentSecret2);
46
- log('session id: ' + this.parentId);
47
- }
48
-
49
- /**
50
- * initialization of Sockethub starts here
51
- */
52
- boot() {
53
- if (this.status) {
54
- return log('Sockethub.boot() called more than once');
55
- } else {
56
- this.status = true;
48
+ private readonly parentId: string;
49
+ private readonly parentSecret1: string;
50
+ private readonly parentSecret2: string;
51
+ counter: number;
52
+ platforms: Map<string, object>;
53
+ status: boolean;
54
+ processManager: ProcessManager;
55
+
56
+ constructor() {
57
+ this.status = false;
58
+ this.parentId = crypto.randToken(16);
59
+ this.parentSecret1 = crypto.randToken(16);
60
+ this.parentSecret2 = crypto.randToken(16);
61
+ log(`session id: ${this.parentId}`);
57
62
  }
58
63
 
59
- log('active platforms: ', [...init.platforms.keys()]);
60
- listener.start(); // start external services
61
- janitor.start(); // start cleanup cycle
62
- log('registering handlers');
63
- listener.io.on('connection', this.handleIncomingConnection.bind(this));
64
- }
65
-
66
- async shutdown() {
67
- await janitor.stop();
68
- }
69
-
70
- private handleIncomingConnection(socket: Socket) {
71
- // session-specific debug messages
72
- const sessionLog = debug('sockethub:server:core:' + socket.id),
73
- sessionSecret = crypto.randToken(16),
74
- // store instance is session-specific
75
- // store = getSessionStore(this.parentId, this.parentSecret1, socket.id, sessionSecret);
76
- credentialsStore = new CredentialsStore(
77
- this.parentId, socket.id,
78
- this.parentSecret1 + sessionSecret,
79
- nconf.get('redis')
80
- );
81
-
82
- sessionLog(`socket.io connection`);
83
-
84
- socket.on('disconnect', () => {
85
- sessionLog('disconnect received from client');
86
- });
87
-
88
- socket.on('credentials',
89
- middleware('credentials')
90
- .use(expandActivityStream)
91
- .use(validate('credentials', socket.id))
92
- .use(storeCredentials(credentialsStore) as MiddlewareChainInterface)
93
- .use((err, data, next) => {
94
- // error handler
95
- next(attachError(err, data));
96
- }).use((data, next) => { next(); })
97
- .done());
98
-
99
- // when new activity objects are created on the client side, an event is
100
- // fired and we receive a copy on the server side.
101
- socket.on('activity-object',
102
- middleware('activity-object')
103
- .use(validate('activity-object', socket.id))
104
- .use(createActivityObject)
105
- .use((err, data, next) => {
106
- next(attachError(err, data));
107
- }).use((data, next) => { next(); })
108
- .done());
109
-
110
- socket.on('message',
111
- middleware('message')
112
- .use(expandActivityStream)
113
- .use(validate('message', socket.id))
114
- .use((msg, next) => {
115
- // The platform thread must find the credentials on their own using the given
116
- // sessionSecret, which indicates that this specific session (socket
117
- // connection) has provided credentials.
118
- msg.sessionSecret = sessionSecret;
119
- next(msg);
120
- }).use((err, data, next) => {
121
- next(attachError(err, data));
122
- }).use(async (msg: IActivityStream, next) => {
123
- const platformInstance = this.processManager.get(msg.context, msg.actor.id, socket.id);
124
- // job validated and queued, store socket.io callback for when job is completed
125
- const job = await platformInstance.jobQueue.add(socket.id, msg);
126
- if (job) {
127
- platformInstance.completedJobHandlers.set(job.title, next);
128
- } else {
129
- // failed to add job to queue, reject handler immediately
130
- msg.error = 'failed to add job to queue';
131
- next(msg);
132
- }
133
- }).done());
134
- }
64
+ /**
65
+ * initialization of Sockethub starts here
66
+ */
67
+ async boot() {
68
+ if (this.status) {
69
+ return log("Sockethub.boot() called more than once");
70
+ }
71
+ this.status = true;
72
+
73
+ const init = await getInitObject().catch((err) => {
74
+ log(err);
75
+ process.exit(1);
76
+ });
77
+
78
+ this.processManager = new ProcessManager(
79
+ this.parentId,
80
+ this.parentSecret1,
81
+ this.parentSecret2,
82
+ init,
83
+ );
84
+
85
+ this.platforms = init.platforms;
86
+
87
+ log("active platforms: ", [...init.platforms.keys()]);
88
+ listener.start(); // start external services
89
+ janitor.start(); // start cleanup cycle
90
+ log("registering handlers");
91
+ listener.io.on("connection", this.handleIncomingConnection.bind(this));
92
+ }
93
+
94
+ async shutdown() {
95
+ await janitor.stop();
96
+ }
97
+
98
+ private handleIncomingConnection(socket: Socket) {
99
+ // session-specific debug messages
100
+ const sessionLog = debug(`sockethub:server:core:${socket.id}`);
101
+ const sessionSecret = crypto.randToken(16);
102
+ // stores instance is session-specific
103
+ // stores = getSessionStore(this.parentId, this.parentSecret1, socket.id, sessionSecret);
104
+ const credentialsStore: CredentialsStoreInterface =
105
+ new CredentialsStore(
106
+ this.parentId,
107
+ socket.id,
108
+ this.parentSecret1 + sessionSecret,
109
+ config.get("redis"),
110
+ );
111
+
112
+ sessionLog("socket.io connection");
113
+
114
+ socket.on("disconnect", () => {
115
+ sessionLog("disconnect received from client");
116
+ });
117
+
118
+ socket.on(
119
+ "credentials",
120
+ middleware("credentials")
121
+ .use(expandActivityStream)
122
+ .use(validate("credentials", socket.id))
123
+ .use(storeCredentials(credentialsStore))
124
+ .use((err, data, next) => {
125
+ // error handler
126
+ next(attachError(err, data));
127
+ })
128
+ .use((data, next) => {
129
+ next();
130
+ })
131
+ .done(),
132
+ );
133
+
134
+ // when new activity objects are created on the client side, an event is
135
+ // fired, and we receive a copy on the server side.
136
+ socket.on(
137
+ "activity-object",
138
+ middleware("activity-object")
139
+ .use(validate("activity-object", socket.id))
140
+ .use(createActivityObject)
141
+ .use((err, data, next) => {
142
+ next(attachError(err, data));
143
+ })
144
+ .use((data, next) => {
145
+ next();
146
+ })
147
+ .done(),
148
+ );
149
+
150
+ socket.on(
151
+ "message",
152
+ middleware("message")
153
+ .use(expandActivityStream)
154
+ .use(validate("message", socket.id))
155
+ .use((msg, next) => {
156
+ // The platform thread must find the credentials on their own using the given
157
+ // sessionSecret, which indicates that this specific session (socket
158
+ // connection) has provided credentials.
159
+ msg.sessionSecret = sessionSecret;
160
+ next(msg);
161
+ })
162
+ .use((err, data, next) => {
163
+ next(attachError(err, data));
164
+ })
165
+ .use(async (msg: ActivityStream, next) => {
166
+ const platformInstance = this.processManager.get(
167
+ msg.context,
168
+ msg.actor.id,
169
+ socket.id,
170
+ );
171
+ // job validated and queued, stores socket.io callback for when job is completed
172
+ try {
173
+ const job = await platformInstance.queue.add(
174
+ socket.id,
175
+ msg,
176
+ );
177
+ if (job) {
178
+ platformInstance.completedJobHandlers.set(
179
+ job.title,
180
+ next,
181
+ );
182
+ } else {
183
+ // failed to add job to queue, reject handler immediately
184
+ msg.error = "failed to add job to queue";
185
+ next(msg);
186
+ }
187
+ } catch (err) {
188
+ // Queue is closed (platform terminating) - send error to client
189
+ msg.error = err.message || "platform unavailable";
190
+ next(msg);
191
+ }
192
+ })
193
+ .done(),
194
+ );
195
+ }
135
196
  }
136
197
 
137
198
  export default Sockethub;
package/src/util.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { dirname } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ const __filename = fileURLToPath(import.meta.url);
5
+ export const __dirname = dirname(__filename);