@sockethub/server 5.0.0-beta.0 → 5.0.0-beta.1
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/dist/cors.d.ts +3 -3
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1069 -896
- package/dist/message-handlers.d.ts +1 -3
- package/dist/middleware/normalize-activity-stream.d.ts +13 -0
- package/dist/payload-debug.d.ts +2 -0
- package/dist/platform-instance.d.ts +1 -0
- package/dist/platform.js +72 -21
- package/dist/process-manager.d.ts +2 -10
- package/dist/trust-proxy.d.ts +19 -0
- package/package.json +18 -15
- package/res/sockethub-client.js +13 -13
|
@@ -30,7 +30,5 @@ export interface MessageHandlersOptions {
|
|
|
30
30
|
* Normalize middleware errors into payload-safe error responses.
|
|
31
31
|
* Removes internal-only properties that must never be sent to clients.
|
|
32
32
|
*/
|
|
33
|
-
export declare function attachError<T extends ActivityStream>(err: unknown, msg?: T):
|
|
34
|
-
sessionSecret?: string;
|
|
35
|
-
});
|
|
33
|
+
export declare function attachError<T extends ActivityStream>(err: unknown, msg?: T): T | Error;
|
|
36
34
|
export declare function createMessageHandlers(options: MessageHandlersOptions): MessageHandlers;
|
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import type { ActivityStream } from "@sockethub/schemas";
|
|
2
2
|
import type { MiddlewareChainInterface } from "../middleware.js";
|
|
3
|
+
/**
|
|
4
|
+
* Maximum nesting depth accepted for client-supplied messages. Validation
|
|
5
|
+
* error formatting and the socket.io encoder both recurse over the message, so
|
|
6
|
+
* an unbounded depth lets a single payload overflow the stack and crash the
|
|
7
|
+
* server.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MAX_MESSAGE_DEPTH = 64;
|
|
10
|
+
/**
|
|
11
|
+
* Iteratively check whether a value nests deeper than `max` levels. Must not
|
|
12
|
+
* recurse itself, since it guards the recursive code paths.
|
|
13
|
+
*/
|
|
14
|
+
export declare function exceedsDepth(root: unknown, max?: number): boolean;
|
|
15
|
+
/** Reject malformed or over-deep input before normalizing an activity. */
|
|
3
16
|
export default function normalizeActivityStreamMiddleware<T extends ActivityStream>(msg: T, done: MiddlewareChainInterface<T>): void;
|
|
@@ -55,6 +55,7 @@ export default class PlatformInstance {
|
|
|
55
55
|
readonly parentId: string;
|
|
56
56
|
private readonly parentSecret1?;
|
|
57
57
|
readonly sessions: Set<string>;
|
|
58
|
+
readonly ownerIps: Set<string>;
|
|
58
59
|
readonly sessionIps: Map<string, string>;
|
|
59
60
|
private readonly sessionSecrets;
|
|
60
61
|
private processMessageListener?;
|
package/dist/platform.js
CHANGED
|
@@ -20497,7 +20497,7 @@ var init_package = __esm(() => {
|
|
|
20497
20497
|
package_default = {
|
|
20498
20498
|
name: "@sockethub/schemas",
|
|
20499
20499
|
description: "JSON schema files for validating Sockethub Activity Streams",
|
|
20500
|
-
version: "3.0.0-beta.
|
|
20500
|
+
version: "3.0.0-beta.1",
|
|
20501
20501
|
type: "module",
|
|
20502
20502
|
private: false,
|
|
20503
20503
|
author: "Nick Jennings <nick@silverbucket.net>",
|
|
@@ -20567,7 +20567,7 @@ var init_package = __esm(() => {
|
|
|
20567
20567
|
"ajv-formats": "^2.1.1",
|
|
20568
20568
|
"ajv-formats-draft2019": "^1.6.1"
|
|
20569
20569
|
},
|
|
20570
|
-
gitHead: "
|
|
20570
|
+
gitHead: "06c9062f1cb5f0c0599fd979e6e91da79f08eda0",
|
|
20571
20571
|
types: "./dist/index.d.ts"
|
|
20572
20572
|
};
|
|
20573
20573
|
});
|
|
@@ -20733,7 +20733,8 @@ var init_sockethub_config = __esm(() => {
|
|
|
20733
20733
|
type: "object",
|
|
20734
20734
|
additionalProperties: false,
|
|
20735
20735
|
properties: {
|
|
20736
|
-
connectTimeoutMs: { type: "number" }
|
|
20736
|
+
connectTimeoutMs: { type: "number" },
|
|
20737
|
+
allowPrivateAddresses: { type: "boolean" }
|
|
20737
20738
|
}
|
|
20738
20739
|
},
|
|
20739
20740
|
"@sockethub/platform-metadata": {
|
|
@@ -20823,11 +20824,23 @@ var init_sockethub_config = __esm(() => {
|
|
|
20823
20824
|
type: "object",
|
|
20824
20825
|
additionalProperties: false,
|
|
20825
20826
|
properties: {
|
|
20827
|
+
maxInstancesPerSession: {
|
|
20828
|
+
type: "integer",
|
|
20829
|
+
minimum: 0,
|
|
20830
|
+
default: 10,
|
|
20831
|
+
description: "Maximum persistent instances per socket session. 0 disables the cap."
|
|
20832
|
+
},
|
|
20833
|
+
maxInstancesPerIp: {
|
|
20834
|
+
type: "integer",
|
|
20835
|
+
minimum: 0,
|
|
20836
|
+
default: 20,
|
|
20837
|
+
description: "Maximum persistent instances per client IP, including HTTP actions. 0 disables the cap."
|
|
20838
|
+
},
|
|
20826
20839
|
maxPlatformInstances: {
|
|
20827
20840
|
type: "number",
|
|
20828
20841
|
minimum: 0,
|
|
20829
20842
|
default: 100,
|
|
20830
|
-
description: "Upper bound on concurrently running platform instances " + "(child processes). Each persistent-platform actor forks " + "its own process, so an unbounded count is a resource " + "exhaustion risk on public instances. 0 disables the cap."
|
|
20843
|
+
description: "Upper bound on concurrently running persistent platform instances " + "(child processes). Each persistent-platform actor forks " + "its own process, so an unbounded count is a resource " + "exhaustion risk on public instances. 0 disables the cap."
|
|
20831
20844
|
}
|
|
20832
20845
|
}
|
|
20833
20846
|
},
|
|
@@ -27196,15 +27209,33 @@ var require_ajv = __commonJS(function(exports, module) {
|
|
|
27196
27209
|
} });
|
|
27197
27210
|
});
|
|
27198
27211
|
|
|
27212
|
+
// ../schemas/src/helpers/codegen.ts
|
|
27213
|
+
function isCodegenAvailable() {
|
|
27214
|
+
if (available === undefined) {
|
|
27215
|
+
try {
|
|
27216
|
+
new Function("return true");
|
|
27217
|
+
available = true;
|
|
27218
|
+
} catch {
|
|
27219
|
+
available = false;
|
|
27220
|
+
}
|
|
27221
|
+
}
|
|
27222
|
+
return available;
|
|
27223
|
+
}
|
|
27224
|
+
function warnCodegenUnavailable() {
|
|
27225
|
+
if (warned) {
|
|
27226
|
+
return;
|
|
27227
|
+
}
|
|
27228
|
+
warned = true;
|
|
27229
|
+
console.warn("[@sockethub/schemas] Schema validation is disabled: this environment's Content Security Policy blocks `new Function`, which Ajv needs to compile schemas. The Sockethub server still validates every message.");
|
|
27230
|
+
}
|
|
27231
|
+
var available, warned = false;
|
|
27232
|
+
|
|
27199
27233
|
// ../schemas/src/schemas/service-descriptor.ts
|
|
27200
27234
|
var init_service_descriptor = () => {};
|
|
27201
27235
|
|
|
27202
27236
|
// ../schemas/src/service-descriptor.ts
|
|
27203
|
-
var import_ajv, ajv;
|
|
27204
27237
|
var init_service_descriptor2 = __esm(() => {
|
|
27205
27238
|
init_service_descriptor();
|
|
27206
|
-
import_ajv = __toESM(require_ajv(), 1);
|
|
27207
|
-
ajv = new import_ajv.default({ strictTypes: false, allErrors: true });
|
|
27208
27239
|
});
|
|
27209
27240
|
|
|
27210
27241
|
// ../../node_modules/ajv-formats/dist/formats.js
|
|
@@ -36752,15 +36783,35 @@ var init_error_parser = __esm(() => {
|
|
|
36752
36783
|
});
|
|
36753
36784
|
|
|
36754
36785
|
// ../schemas/src/validator.ts
|
|
36786
|
+
function getAjv() {
|
|
36787
|
+
if (!isCodegenAvailable()) {
|
|
36788
|
+
warnCodegenUnavailable();
|
|
36789
|
+
return;
|
|
36790
|
+
}
|
|
36791
|
+
if (!ajv) {
|
|
36792
|
+
const instance = new import_ajv.default({ strictTypes: false, allErrors: true });
|
|
36793
|
+
import_ajv_formats.default(instance);
|
|
36794
|
+
import_ajv_formats_draft2019.default(instance);
|
|
36795
|
+
for (const uri in schemas) {
|
|
36796
|
+
instance.addSchema(schemas[uri], uri);
|
|
36797
|
+
}
|
|
36798
|
+
ajv = instance;
|
|
36799
|
+
}
|
|
36800
|
+
return ajv;
|
|
36801
|
+
}
|
|
36755
36802
|
function registerSystemContext(platformId, contextUrl) {
|
|
36756
36803
|
registerPlatformContext(platformId, contextUrl, `${schemaURL}/context/${platformId}/messages`, `${schemaURL}/context/${platformId}/credentials`);
|
|
36804
|
+
const instance = getAjv();
|
|
36805
|
+
if (!instance) {
|
|
36806
|
+
return;
|
|
36807
|
+
}
|
|
36757
36808
|
const messageSchemaRef = `${schemaURL}/context/${platformId}/messages`;
|
|
36758
|
-
if (!
|
|
36759
|
-
|
|
36809
|
+
if (!instance.getSchema(messageSchemaRef)) {
|
|
36810
|
+
instance.addSchema({}, messageSchemaRef);
|
|
36760
36811
|
}
|
|
36761
36812
|
const credentialsSchemaRef = `${schemaURL}/context/${platformId}/credentials`;
|
|
36762
|
-
if (!
|
|
36763
|
-
|
|
36813
|
+
if (!instance.getSchema(credentialsSchemaRef)) {
|
|
36814
|
+
instance.addSchema({}, credentialsSchemaRef);
|
|
36764
36815
|
}
|
|
36765
36816
|
}
|
|
36766
36817
|
function registerSystemPlatformContexts() {
|
|
@@ -36772,17 +36823,21 @@ function registerSystemPlatformContexts() {
|
|
|
36772
36823
|
systemContextsRegistered = true;
|
|
36773
36824
|
}
|
|
36774
36825
|
function validateSockethubConfig(config) {
|
|
36826
|
+
const instance = getAjv();
|
|
36827
|
+
if (!instance) {
|
|
36828
|
+
return "";
|
|
36829
|
+
}
|
|
36775
36830
|
if (!sockethubConfigValidator) {
|
|
36776
|
-
sockethubConfigValidator =
|
|
36831
|
+
sockethubConfigValidator = instance.compile(SockethubConfigSchema);
|
|
36777
36832
|
}
|
|
36778
36833
|
if (sockethubConfigValidator(config)) {
|
|
36779
36834
|
return "";
|
|
36780
36835
|
}
|
|
36781
|
-
return
|
|
36836
|
+
return instance.errorsText(sockethubConfigValidator.errors, {
|
|
36782
36837
|
dataVar: "config"
|
|
36783
36838
|
});
|
|
36784
36839
|
}
|
|
36785
|
-
var
|
|
36840
|
+
var import_ajv, import_ajv_formats, import_ajv_formats_draft2019, schemaURL = "https://sockethub.org/schemas/v0", schemas, systemContextsRegistered = false, ajv, sockethubConfigValidator;
|
|
36786
36841
|
var init_validator = __esm(() => {
|
|
36787
36842
|
init_context();
|
|
36788
36843
|
init_error_parser();
|
|
@@ -36790,17 +36845,11 @@ var init_validator = __esm(() => {
|
|
|
36790
36845
|
init_activity_stream();
|
|
36791
36846
|
init_platform();
|
|
36792
36847
|
init_sockethub_config();
|
|
36793
|
-
|
|
36848
|
+
import_ajv = __toESM(require_ajv(), 1);
|
|
36794
36849
|
import_ajv_formats = __toESM(require_dist(), 1);
|
|
36795
36850
|
import_ajv_formats_draft2019 = __toESM(require_ajv_formats_draft2019(), 1);
|
|
36796
|
-
ajv2 = new import_ajv2.default({ strictTypes: false, allErrors: true });
|
|
36797
|
-
import_ajv_formats.default(ajv2);
|
|
36798
|
-
import_ajv_formats_draft2019.default(ajv2);
|
|
36799
36851
|
schemas = {};
|
|
36800
36852
|
schemas[`${schemaURL}/activity-stream`] = ActivityStreamSchema;
|
|
36801
|
-
for (const uri in schemas) {
|
|
36802
|
-
ajv2.addSchema(schemas[uri], uri);
|
|
36803
|
-
}
|
|
36804
36853
|
registerSystemPlatformContexts();
|
|
36805
36854
|
});
|
|
36806
36855
|
|
|
@@ -73881,6 +73930,8 @@ var init_config_schema = __esm(() => {
|
|
|
73881
73930
|
"rateLimiter.maxRequests": { format: "nat" },
|
|
73882
73931
|
"rateLimiter.blockDurationMs": { format: "nat" },
|
|
73883
73932
|
"rateLimiter.maxConnectionsPerIp": { format: "nat" },
|
|
73933
|
+
"limits.maxInstancesPerSession": { format: "nat" },
|
|
73934
|
+
"limits.maxInstancesPerIp": { format: "nat" },
|
|
73884
73935
|
"limits.maxPlatformInstances": { format: "nat" },
|
|
73885
73936
|
"credentials.ttlMs": {
|
|
73886
73937
|
format: "nat",
|
|
@@ -24,16 +24,8 @@ declare class ProcessManager {
|
|
|
24
24
|
*/
|
|
25
25
|
private ensureProcess;
|
|
26
26
|
private ensureProcessNow;
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
* bound, a public instance can be driven into resource exhaustion.
|
|
30
|
-
* Throws when the configured cap (`limits.maxPlatformInstances`, 0 =
|
|
31
|
-
* disabled) has been reached and a new instance would be created.
|
|
32
|
-
*
|
|
33
|
-
* `identifier`'s existing (dead) slot, if any, is excluded from the
|
|
34
|
-
* count: replacing a crashed instance for the same actor doesn't
|
|
35
|
-
* increase the total instance count, so it shouldn't be blocked by
|
|
36
|
-
* the cap.
|
|
27
|
+
/** Stateless workers are bounded by the enabled platform count, independently
|
|
28
|
+
* of client occupancy. Check owners even when attaching to a shared worker.
|
|
37
29
|
*/
|
|
38
30
|
private assertInstanceCapacity;
|
|
39
31
|
private isProcessAlive;
|
package/dist/trust-proxy.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
import type { IncomingMessage } from "node:http";
|
|
2
|
+
import type { Express } from "express";
|
|
3
|
+
/** Resolve socket admission using the same compiled proxy policy as Express req.ip. */
|
|
4
|
+
export declare function getRequestClientIp(request: IncomingMessage, app: Express): string;
|
|
5
|
+
/**
|
|
6
|
+
* Client address for socket admission, per-IP quotas, and anonymous reconnect.
|
|
7
|
+
*
|
|
8
|
+
* `x-forwarded-for` is a chain. The nearest proxy appends the address it
|
|
9
|
+
* actually accepted, and anything to the left of that may have been set by
|
|
10
|
+
* the client. Reading the first entry treats that prefix as the client, so
|
|
11
|
+
* an attacker can present a victim's address and, during janitor grace,
|
|
12
|
+
* take over that victim's anonymous connection (the reconnect key is the
|
|
13
|
+
* actor plus this address). Hop count is already what HTTP uses: one trusted
|
|
14
|
+
* hop yields the address the proxy appended, not the spoofed prefix.
|
|
15
|
+
*
|
|
16
|
+
* A custom `proxyHeader` is not a chain Express understands. The operator
|
|
17
|
+
* vouched for that header, and its first address is the value.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveSocketClientIp(request: IncomingMessage, app: Express | undefined, reconnectIpSource: unknown, proxyHeader: unknown, fallbackAddress: string | undefined): string;
|
|
1
20
|
/**
|
|
2
21
|
* Resolution of Express's `trust proxy` setting.
|
|
3
22
|
*
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sockethub/server",
|
|
3
3
|
"description": "A polyglot messaging service, server libraries",
|
|
4
|
-
"version": "5.0.0-beta.
|
|
4
|
+
"version": "5.0.0-beta.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"author": "Nick Jennings <nick@silverbucket.net>",
|
|
@@ -53,17 +53,19 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@sentry/node": "^10.36.0",
|
|
55
55
|
"@sentry/profiling-node": "10.36.0",
|
|
56
|
-
"@sockethub/client": "^5.0.0-beta.
|
|
57
|
-
"@sockethub/data-layer": "^1.0.0-beta.
|
|
58
|
-
"@sockethub/logger": "^1.0.0-beta.
|
|
59
|
-
"@sockethub/schemas": "^3.0.0-beta.
|
|
60
|
-
"@sockethub/util": "^1.0.0-beta.
|
|
56
|
+
"@sockethub/client": "^5.0.0-beta.1",
|
|
57
|
+
"@sockethub/data-layer": "^1.0.0-beta.1",
|
|
58
|
+
"@sockethub/logger": "^1.0.0-beta.1",
|
|
59
|
+
"@sockethub/schemas": "^3.0.0-beta.1",
|
|
60
|
+
"@sockethub/util": "^1.0.0-beta.1",
|
|
61
61
|
"chalk": "^5.6.2",
|
|
62
62
|
"convict": "^6.2.5",
|
|
63
|
+
"debug": "^4.4.3",
|
|
63
64
|
"ejs": "^3.1.10",
|
|
64
65
|
"express": "^5.1.0",
|
|
65
66
|
"express-rate-limit": "^8.2.1",
|
|
66
67
|
"jquery": "^3.7.1",
|
|
68
|
+
"proxy-addr": "^2.0.7",
|
|
67
69
|
"rate-limit-redis": "^4.2.0",
|
|
68
70
|
"socket.io": "^4.8.3"
|
|
69
71
|
},
|
|
@@ -82,21 +84,22 @@
|
|
|
82
84
|
"@types/debug": "^4.1.12",
|
|
83
85
|
"@types/express": "^5.0.0",
|
|
84
86
|
"@types/jquery": "^3.5.33",
|
|
87
|
+
"@types/proxy-addr": "^2.0.3",
|
|
85
88
|
"@types/sinon": "^17.0.4",
|
|
86
89
|
"jaribu": "^2.2.3",
|
|
87
90
|
"sinon": "^17.0.2",
|
|
88
91
|
"web-streams-polyfill": "^3.3.3"
|
|
89
92
|
},
|
|
90
93
|
"optionalDependencies": {
|
|
91
|
-
"@sockethub/examples": "^1.0.0-beta.
|
|
92
|
-
"@sockethub/platform-caldav": "^1.0.0-beta.
|
|
93
|
-
"@sockethub/platform-carddav": "^1.0.0-beta.
|
|
94
|
-
"@sockethub/platform-dummy": "^3.0.0-beta.
|
|
95
|
-
"@sockethub/platform-feeds": "^4.0.0-beta.
|
|
96
|
-
"@sockethub/platform-irc": "^4.0.0-beta.
|
|
97
|
-
"@sockethub/platform-metadata": "^1.0.1-beta.
|
|
98
|
-
"@sockethub/platform-xmpp": "^5.0.0-beta.
|
|
94
|
+
"@sockethub/examples": "^1.0.0-beta.1",
|
|
95
|
+
"@sockethub/platform-caldav": "^1.0.0-beta.1",
|
|
96
|
+
"@sockethub/platform-carddav": "^1.0.0-beta.1",
|
|
97
|
+
"@sockethub/platform-dummy": "^3.0.0-beta.1",
|
|
98
|
+
"@sockethub/platform-feeds": "^4.0.0-beta.1",
|
|
99
|
+
"@sockethub/platform-irc": "^4.0.0-beta.1",
|
|
100
|
+
"@sockethub/platform-metadata": "^1.0.1-beta.1",
|
|
101
|
+
"@sockethub/platform-xmpp": "^5.0.0-beta.1"
|
|
99
102
|
},
|
|
100
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "928f0c480e4828f492fb29a97712474a8f1bcaef",
|
|
101
104
|
"types": "./dist/index.d.ts"
|
|
102
105
|
}
|