@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.
- package/README.md +54 -60
- package/bin/sockethub +4 -3
- package/package.json +42 -54
- package/res/socket.io.js +4908 -0
- package/res/sockethub-client.js +602 -0
- package/res/sockethub-client.min.js +19 -0
- package/sockethub.config.example.json +2 -3
- package/src/bootstrap/init.d.ts +16 -13
- package/src/bootstrap/init.test.ts +211 -0
- package/src/bootstrap/init.ts +152 -76
- package/src/bootstrap/load-platforms.ts +151 -0
- package/src/config.test.ts +27 -22
- package/src/config.ts +82 -86
- package/src/defaults.json +24 -16
- package/src/index.ts +61 -22
- package/src/janitor.test.ts +191 -169
- package/src/janitor.ts +141 -118
- package/src/listener.ts +148 -58
- package/src/middleware/create-activity-object.test.ts +28 -8
- package/src/middleware/create-activity-object.ts +16 -10
- package/src/middleware/expand-activity-stream.test.data.ts +331 -345
- package/src/middleware/expand-activity-stream.test.ts +65 -66
- package/src/middleware/expand-activity-stream.ts +26 -21
- package/src/middleware/store-credentials.test.ts +74 -60
- package/src/middleware/store-credentials.ts +14 -8
- package/src/middleware/validate.test.data.ts +240 -242
- package/src/middleware/validate.test.ts +39 -78
- package/src/middleware/validate.ts +62 -36
- package/src/middleware.test.ts +168 -138
- package/src/middleware.ts +57 -55
- package/src/platform-instance.test.ts +508 -214
- package/src/platform-instance.ts +324 -231
- package/src/platform.test.ts +375 -0
- package/src/platform.ts +306 -117
- package/src/process-manager.ts +75 -51
- package/src/routes.test.ts +43 -89
- package/src/routes.ts +40 -78
- package/src/sentry.test.ts +106 -0
- package/src/sentry.ts +19 -0
- package/src/sockethub.ts +190 -129
- package/src/util.ts +5 -0
- package/coverage/tmp/coverage-39338-1663949520416-0.json +0 -1
- package/dist/bootstrap/init.d.ts +0 -18
- package/dist/bootstrap/init.js +0 -64
- package/dist/bootstrap/init.js.map +0 -1
- package/dist/bootstrap/platforms.js +0 -75
- package/dist/config.d.ts +0 -12
- package/dist/config.js +0 -107
- package/dist/config.js.map +0 -1
- package/dist/defaults.json +0 -28
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -29
- package/dist/index.js.map +0 -1
- package/dist/janitor.d.ts +0 -30
- package/dist/janitor.js +0 -120
- package/dist/janitor.js.map +0 -1
- package/dist/listener.d.ts +0 -31
- package/dist/listener.js +0 -94
- package/dist/listener.js.map +0 -1
- package/dist/middleware/create-activity-object.d.ts +0 -8
- package/dist/middleware/create-activity-object.js +0 -19
- package/dist/middleware/create-activity-object.js.map +0 -1
- package/dist/middleware/expand-activity-stream.d.ts +0 -3
- package/dist/middleware/expand-activity-stream.js +0 -36
- package/dist/middleware/expand-activity-stream.js.map +0 -1
- package/dist/middleware/expand-activity-stream.test.data.d.ts +0 -480
- package/dist/middleware/expand-activity-stream.test.data.js +0 -360
- package/dist/middleware/expand-activity-stream.test.data.js.map +0 -1
- package/dist/middleware/store-credentials.d.ts +0 -3
- package/dist/middleware/store-credentials.js +0 -9
- package/dist/middleware/store-credentials.js.map +0 -1
- package/dist/middleware/validate.d.ts +0 -2
- package/dist/middleware/validate.js +0 -56
- package/dist/middleware/validate.js.map +0 -1
- package/dist/middleware/validate.test.data.d.ts +0 -532
- package/dist/middleware/validate.test.data.js +0 -263
- package/dist/middleware/validate.test.data.js.map +0 -1
- package/dist/middleware.d.ts +0 -21
- package/dist/middleware.js +0 -56
- package/dist/middleware.js.map +0 -1
- package/dist/platform-instance.d.ts +0 -78
- package/dist/platform-instance.js +0 -226
- package/dist/platform-instance.js.map +0 -1
- package/dist/platform.d.ts +0 -6
- package/dist/platform.js +0 -176
- package/dist/platform.js.map +0 -1
- package/dist/process-manager.d.ts +0 -11
- package/dist/process-manager.js +0 -82
- package/dist/process-manager.js.map +0 -1
- package/dist/routes.d.ts +0 -13
- package/dist/routes.js +0 -83
- package/dist/routes.js.map +0 -1
- package/dist/sockethub.d.ts +0 -18
- package/dist/sockethub.js +0 -112
- package/dist/sockethub.js.map +0 -1
- package/src/bootstrap/platforms.js +0 -75
- package/test/init-suite.js +0 -41
- package/test/sockethub-suite.js +0 -25
- package/tsconfig.json +0 -18
- package/views/examples/dummy.ejs +0 -95
- package/views/examples/feeds.ejs +0 -90
- package/views/examples/irc.ejs +0 -239
- package/views/examples/shared.js +0 -72
- package/views/examples/xmpp.ejs +0 -217
- package/views/index.ejs +0 -17
package/src/routes.test.ts
CHANGED
|
@@ -1,100 +1,54 @@
|
|
|
1
|
-
import { expect } from
|
|
2
|
-
import * as sinon from 'sinon';
|
|
1
|
+
import { afterEach, describe, expect, it } from "bun:test";
|
|
3
2
|
import { existsSync } from "fs";
|
|
3
|
+
import * as sinon from "sinon";
|
|
4
4
|
|
|
5
|
-
import routes, { basePaths,
|
|
5
|
+
import routes, { basePaths, type IRoutePaths } from "./routes.js";
|
|
6
6
|
|
|
7
|
-
describe(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
sinon.restore();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('can find each of the base files it serves', () => {
|
|
14
|
-
Object.values(basePaths).forEach((fwd: string) => {
|
|
15
|
-
try {
|
|
16
|
-
expect(existsSync(fwd)).to.be.true;
|
|
17
|
-
} catch (e) {
|
|
18
|
-
throw new Error(`Unable to resolve path ${fwd}`);
|
|
19
|
-
}
|
|
7
|
+
describe("routes/base", () => {
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
sinon.restore();
|
|
20
10
|
});
|
|
21
|
-
});
|
|
22
11
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
12
|
+
it("can find each of the base files it serves", () => {
|
|
13
|
+
Object.values(basePaths).forEach((fwd: string) => {
|
|
14
|
+
try {
|
|
15
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
16
|
+
expect(existsSync(fwd)).toBeTrue();
|
|
17
|
+
} catch (e) {
|
|
18
|
+
throw new Error(`Unable to resolve path ${fwd}`);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
30
21
|
});
|
|
31
|
-
});
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
23
|
+
it("adds base routes", () => {
|
|
24
|
+
const app = {
|
|
25
|
+
get: sinon.spy(),
|
|
26
|
+
};
|
|
27
|
+
routes.setup(app);
|
|
28
|
+
sinon.assert.callCount(app.get, Object.keys(basePaths).length);
|
|
40
29
|
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('adds base routes', () => {
|
|
44
|
-
const app = {
|
|
45
|
-
get: sinon.spy()
|
|
46
|
-
};
|
|
47
|
-
routes.setup(app, false);
|
|
48
|
-
sinon.assert.callCount(
|
|
49
|
-
app.get,
|
|
50
|
-
Object.keys(basePaths).length
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
30
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
app.get,
|
|
61
|
-
Object.keys(basePaths).length
|
|
62
|
-
+ Object.keys(examplePaths).length
|
|
63
|
-
+ Object.keys(examplePages).length
|
|
64
|
-
);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('handles calls to base routes as expected', () => {
|
|
68
|
-
let routeHandlers: any = {};
|
|
69
|
-
let app = {
|
|
70
|
-
get: (path: string | number, route: any) => {
|
|
71
|
-
routeHandlers[path] = route;
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
routes.setup(app, true);
|
|
75
|
-
|
|
76
|
-
function verifyPathRoutes(pathMap: IRoutePaths) {
|
|
77
|
-
Object.keys(pathMap).forEach((path) => {
|
|
78
|
-
const res = {
|
|
79
|
-
setHeader: sinon.spy(),
|
|
80
|
-
sendFile: sinon.spy()
|
|
31
|
+
it("handles calls to base routes as expected", () => {
|
|
32
|
+
const routeHandlers: any = {};
|
|
33
|
+
const app = {
|
|
34
|
+
get: (path: string | number, route: any) => {
|
|
35
|
+
routeHandlers[path] = route;
|
|
36
|
+
},
|
|
81
37
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
sinon.assert.called(res.render);
|
|
38
|
+
routes.setup(app);
|
|
39
|
+
|
|
40
|
+
function verifyPathRoutes(pathMap: IRoutePaths) {
|
|
41
|
+
Object.keys(pathMap).forEach((path) => {
|
|
42
|
+
const res = {
|
|
43
|
+
setHeader: sinon.spy(),
|
|
44
|
+
sendFile: sinon.spy(),
|
|
45
|
+
};
|
|
46
|
+
expect(pathMap[path].endsWith(".ejs")).toBeFalse();
|
|
47
|
+
routeHandlers[path]({ url: path }, res);
|
|
48
|
+
sinon.assert.called(res.setHeader);
|
|
49
|
+
sinon.assert.calledWith(res.sendFile, pathMap[path]);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
verifyPathRoutes(basePaths);
|
|
98
53
|
});
|
|
99
|
-
|
|
100
|
-
});
|
|
54
|
+
});
|
package/src/routes.ts
CHANGED
|
@@ -1,99 +1,61 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import
|
|
3
|
-
import debug from 'debug';
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import debug from "debug";
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
config.get('public:host') + ':' +
|
|
9
|
-
config.get('public:port') +
|
|
10
|
-
config.get('public:path');
|
|
4
|
+
import { __dirname } from "./util.js";
|
|
5
|
+
|
|
6
|
+
const logger = debug("sockethub:server:routes");
|
|
11
7
|
|
|
12
8
|
export interface IRoutePaths {
|
|
13
|
-
|
|
9
|
+
[key: string]: string;
|
|
14
10
|
}
|
|
15
11
|
|
|
16
12
|
export const basePaths: IRoutePaths = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
13
|
+
"/sockethub-client.js": path.resolve(
|
|
14
|
+
__dirname,
|
|
15
|
+
"..",
|
|
16
|
+
"res",
|
|
17
|
+
"sockethub-client.js",
|
|
18
|
+
),
|
|
19
|
+
"/sockethub-client.min.js": path.resolve(
|
|
20
|
+
__dirname,
|
|
21
|
+
"..",
|
|
22
|
+
"res",
|
|
23
|
+
"sockethub-client.min.js",
|
|
24
|
+
),
|
|
25
|
+
"/socket.io.js": path.resolve(__dirname, "..", "res", "socket.io.js"),
|
|
30
26
|
};
|
|
31
27
|
|
|
32
|
-
export const examplePages: IRoutePaths = {
|
|
33
|
-
'/': path.resolve(`${__dirname}/../views/index.ejs`),
|
|
34
|
-
'/examples/dummy': path.resolve(`${__dirname}/../views/examples/dummy.ejs`),
|
|
35
|
-
'/examples/feeds': path.resolve(`${__dirname}/../views/examples/feeds.ejs`),
|
|
36
|
-
'/examples/irc': path.resolve(`${__dirname}/../views/examples/irc.ejs`),
|
|
37
|
-
'/examples/xmpp': path.resolve(`${__dirname}/../views/examples/xmpp.ejs`)
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
|
|
41
28
|
function prepFileRoutes(pathMap) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
29
|
+
const _routes = [];
|
|
30
|
+
for (const key of Object.keys(pathMap)) {
|
|
31
|
+
_routes.push({
|
|
32
|
+
meta: {
|
|
33
|
+
method: "GET",
|
|
34
|
+
path: key,
|
|
35
|
+
},
|
|
36
|
+
route: (req, res) => {
|
|
37
|
+
logger(`serving resource ${req.url}`);
|
|
38
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
39
|
+
res.sendFile(pathMap[req.url]);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return _routes;
|
|
57
44
|
}
|
|
58
45
|
const baseRoutes = prepFileRoutes(basePaths);
|
|
59
|
-
const exampleRoutes = prepFileRoutes(examplePaths);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Object.keys(examplePages).forEach((key) => {
|
|
63
|
-
exampleRoutes.push({
|
|
64
|
-
meta: {
|
|
65
|
-
method: 'GET',
|
|
66
|
-
path: key
|
|
67
|
-
},
|
|
68
|
-
route: (req, res) => {
|
|
69
|
-
logger(`serving page ${req.url}`);
|
|
70
|
-
res.render(examplePages[req.url], {
|
|
71
|
-
debug_scope: debug_scope,
|
|
72
|
-
address: address,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
46
|
|
|
78
47
|
function addRoute(app) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
route.route
|
|
83
|
-
);
|
|
84
|
-
};
|
|
48
|
+
return (route) => {
|
|
49
|
+
app[route.meta.method.toLowerCase()](route.meta.path, route.route);
|
|
50
|
+
};
|
|
85
51
|
}
|
|
86
52
|
|
|
87
53
|
/**
|
|
88
54
|
* Setup
|
|
89
55
|
*/
|
|
90
56
|
const routes = {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (examplesEnabled) {
|
|
95
|
-
exampleRoutes.forEach(addRoute(app));
|
|
96
|
-
}
|
|
97
|
-
}
|
|
57
|
+
setup: (app: unknown) => {
|
|
58
|
+
baseRoutes.forEach(addRoute(app));
|
|
59
|
+
},
|
|
98
60
|
};
|
|
99
61
|
export default routes;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, mock } from "bun:test";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
|
|
4
|
+
// Mock config to avoid loading real configuration
|
|
5
|
+
const mockConfig = {
|
|
6
|
+
get: mock((key: string) => {
|
|
7
|
+
if (key === "sentry:dsn") {
|
|
8
|
+
return "https://ffc702eb2f3b24d9e06ca20e1ef1fd09@o4508859714895872.ingest.de.sentry.io/4508859718369360";
|
|
9
|
+
}
|
|
10
|
+
if (key === "sentry") {
|
|
11
|
+
return {
|
|
12
|
+
dsn: "https://ffc702eb2f3b24d9e06ca20e1ef1fd09@o4508859714895872.ingest.de.sentry.io/4508859718369360",
|
|
13
|
+
environment: "test",
|
|
14
|
+
traceSampleRate: 1.0
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
})
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
describe("Sentry Integration Bug - Issue #918", () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
// Clear any existing Sentry instances
|
|
24
|
+
delete require.cache[require.resolve("./sentry.js")];
|
|
25
|
+
mockConfig.get.mockClear();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should reproduce 'A Proxy's target should be an Object' error", async () => {
|
|
29
|
+
// This test reproduces the bug by initializing Sentry with Bun server instrumentation
|
|
30
|
+
// The error occurs when Sentry's Bun integration tries to instrument server options
|
|
31
|
+
let sentryError: Error | null = null;
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
// Create a proper mock that implements the config interface
|
|
35
|
+
const configPath = require.resolve("./config.js");
|
|
36
|
+
|
|
37
|
+
// Clear the config from cache first
|
|
38
|
+
delete require.cache[configPath];
|
|
39
|
+
|
|
40
|
+
// Mock the config module before importing sentry
|
|
41
|
+
require.cache[configPath] = {
|
|
42
|
+
exports: {
|
|
43
|
+
default: mockConfig,
|
|
44
|
+
__esModule: true
|
|
45
|
+
},
|
|
46
|
+
loaded: true,
|
|
47
|
+
children: [],
|
|
48
|
+
parent: null,
|
|
49
|
+
filename: configPath,
|
|
50
|
+
id: configPath,
|
|
51
|
+
paths: [],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Import Sentry module which triggers initialization
|
|
55
|
+
const sentryPath = require.resolve("./sentry.js");
|
|
56
|
+
delete require.cache[sentryPath]; // Clear sentry from cache
|
|
57
|
+
await import("./sentry.js");
|
|
58
|
+
} catch (error) {
|
|
59
|
+
sentryError = error as Error;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// With the upgrade to @sentry/bun 10.15.0, this should now work without the Proxy error
|
|
63
|
+
// If we're still on the old version, we'd expect the Proxy error
|
|
64
|
+
// If we're on the new version, Sentry should initialize successfully
|
|
65
|
+
if (sentryError) {
|
|
66
|
+
// If there's still an error, it should NOT be the Proxy error (since we upgraded)
|
|
67
|
+
expect(sentryError.message).not.toContain("A Proxy's 'target' should be an Object");
|
|
68
|
+
} else {
|
|
69
|
+
// Success - the upgrade fixed the issue
|
|
70
|
+
expect(sentryError).toBeNull();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("should verify the Sentry version has been upgraded to fix the bug", () => {
|
|
75
|
+
// This test documents that the problematic version has been fixed
|
|
76
|
+
const packageJson = require("../package.json");
|
|
77
|
+
const currentVersion = packageJson.dependencies["@sentry/bun"];
|
|
78
|
+
|
|
79
|
+
// Should now be version 10.x or higher (which fixes the Proxy bug)
|
|
80
|
+
expect(currentVersion).toMatch(/^(\^?10\.|^10\.|latest)/);
|
|
81
|
+
|
|
82
|
+
// Document the bug details for reference
|
|
83
|
+
const bugInfo = {
|
|
84
|
+
brokenVersion: "9.5.0",
|
|
85
|
+
fixedVersion: "10.15.0",
|
|
86
|
+
bugDescription: "A Proxy's 'target' should be an Object",
|
|
87
|
+
location: "instrumentBunServeOptions in @sentry/bun"
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
expect(bugInfo.brokenVersion).toBe("9.5.0");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe("Sentry Integration Workaround", () => {
|
|
95
|
+
it("should suggest disabling Sentry DSN as temporary workaround", () => {
|
|
96
|
+
// Document the workaround: set sentry.dsn to empty string or remove it
|
|
97
|
+
const workaroundConfig = {
|
|
98
|
+
sentry: {
|
|
99
|
+
dsn: "", // Empty DSN disables Sentry
|
|
100
|
+
environment: "production"
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
expect(workaroundConfig.sentry.dsn).toBe("");
|
|
105
|
+
});
|
|
106
|
+
});
|
package/src/sentry.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is only imported if sentry reporting is enabled in the Sockethub config.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as Sentry from "@sentry/bun";
|
|
6
|
+
import debug from "debug";
|
|
7
|
+
import config from "./config";
|
|
8
|
+
|
|
9
|
+
const logger = debug("sockethub:sentry");
|
|
10
|
+
if (!config.get("sentry:dsn")) {
|
|
11
|
+
throw new Error("Sentry attempted initialization with no DSN provided");
|
|
12
|
+
}
|
|
13
|
+
logger("initialized");
|
|
14
|
+
Sentry.init(config.get("sentry"));
|
|
15
|
+
|
|
16
|
+
export function reportError(err: Error): void {
|
|
17
|
+
logger("reporting error");
|
|
18
|
+
Sentry.captureException(err);
|
|
19
|
+
}
|