@sockethub/server 5.0.0-beta.0 → 5.0.0-beta.2
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/connection-scope.d.ts +1 -0
- package/dist/cors.d.ts +3 -3
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1212 -932
- 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 +5 -1
- package/dist/platform.js +107 -26
- package/dist/process-manager.d.ts +13 -10
- package/dist/trust-proxy.d.ts +19 -0
- package/package.json +22 -16
- package/res/sockethub-client.js +17 -17
|
@@ -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?;
|
|
@@ -63,12 +64,14 @@ export default class PlatformInstance {
|
|
|
63
64
|
private heartbeatFailureHandled;
|
|
64
65
|
private replaced;
|
|
65
66
|
private shutdownResult?;
|
|
67
|
+
private retirementError?;
|
|
66
68
|
/**
|
|
67
69
|
* Actor this instance was opened for. Updated when the platform re-keys
|
|
68
70
|
* (IRC nick change) so a later rename moves the credential scope off the
|
|
69
71
|
* actor the client is using now, not the one from process start.
|
|
70
72
|
*/
|
|
71
73
|
private actor?;
|
|
74
|
+
get actorId(): string | undefined;
|
|
72
75
|
constructor(params: PlatformInstanceParams);
|
|
73
76
|
createQueue(): void;
|
|
74
77
|
resolveSentryEnv(): string | undefined;
|
|
@@ -97,7 +100,7 @@ export default class PlatformInstance {
|
|
|
97
100
|
* independent run would resolve while the first is still obliterating
|
|
98
101
|
* the queue name the replacement is about to reuse.
|
|
99
102
|
*/
|
|
100
|
-
shutdown(): Promise<void>;
|
|
103
|
+
shutdown(pendingJobError?: string): Promise<void>;
|
|
101
104
|
private teardown;
|
|
102
105
|
/**
|
|
103
106
|
* When jobs are completed or failed, we prepare the results and send them to the client socket
|
|
@@ -110,6 +113,7 @@ export default class PlatformInstance {
|
|
|
110
113
|
* mid-job) don't leak handlers for the lifetime of the instance.
|
|
111
114
|
*/
|
|
112
115
|
registerCompletedJobHandler(title: string, handler: CompletedJobHandler): void;
|
|
116
|
+
private failRetiredJob;
|
|
113
117
|
private takeCompletedJobHandler;
|
|
114
118
|
private pruneExpiredJobHandlers;
|
|
115
119
|
/**
|
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.2",
|
|
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: "1f74d4e07311496f0acc021855137bc197d79eab",
|
|
20571
20571
|
types: "./dist/index.d.ts"
|
|
20572
20572
|
};
|
|
20573
20573
|
});
|
|
@@ -20676,8 +20676,11 @@ var init_sockethub_config = __esm(() => {
|
|
|
20676
20676
|
"@sockethub/platform-caldav",
|
|
20677
20677
|
"@sockethub/platform-dummy",
|
|
20678
20678
|
"@sockethub/platform-feeds",
|
|
20679
|
+
"@sockethub/platform-email",
|
|
20679
20680
|
"@sockethub/platform-irc",
|
|
20680
20681
|
"@sockethub/platform-metadata",
|
|
20682
|
+
"@sockethub/platform-messenger",
|
|
20683
|
+
"@sockethub/platform-instagram",
|
|
20681
20684
|
"@sockethub/platform-xmpp"
|
|
20682
20685
|
]
|
|
20683
20686
|
},
|
|
@@ -20693,7 +20696,8 @@ var init_sockethub_config = __esm(() => {
|
|
|
20693
20696
|
connectTimeoutMs: { type: "integer", minimum: 1 },
|
|
20694
20697
|
allowPrivateAddresses: { type: "boolean" },
|
|
20695
20698
|
allowInsecureHttp: { type: "boolean" },
|
|
20696
|
-
concurrency: { type: "integer", minimum: 1 }
|
|
20699
|
+
concurrency: { type: "integer", minimum: 1 },
|
|
20700
|
+
discoveryCacheTtlMs: { type: "integer", minimum: 0 }
|
|
20697
20701
|
}
|
|
20698
20702
|
},
|
|
20699
20703
|
"@sockethub/platform-caldav": {
|
|
@@ -20703,7 +20707,20 @@ var init_sockethub_config = __esm(() => {
|
|
|
20703
20707
|
connectTimeoutMs: { type: "integer", minimum: 1 },
|
|
20704
20708
|
allowPrivateAddresses: { type: "boolean" },
|
|
20705
20709
|
allowInsecureHttp: { type: "boolean" },
|
|
20706
|
-
concurrency: { type: "integer", minimum: 1 }
|
|
20710
|
+
concurrency: { type: "integer", minimum: 1 },
|
|
20711
|
+
discoveryCacheTtlMs: { type: "integer", minimum: 0 }
|
|
20712
|
+
}
|
|
20713
|
+
},
|
|
20714
|
+
"@sockethub/platform-email": {
|
|
20715
|
+
type: "object",
|
|
20716
|
+
additionalProperties: false,
|
|
20717
|
+
properties: {
|
|
20718
|
+
connectTimeoutMs: {
|
|
20719
|
+
type: "integer",
|
|
20720
|
+
minimum: 5000,
|
|
20721
|
+
maximum: 120000
|
|
20722
|
+
},
|
|
20723
|
+
allowPrivateAddresses: { type: "boolean" }
|
|
20707
20724
|
}
|
|
20708
20725
|
},
|
|
20709
20726
|
"@sockethub/platform-dummy": {
|
|
@@ -20726,14 +20743,16 @@ var init_sockethub_config = __esm(() => {
|
|
|
20726
20743
|
type: "object",
|
|
20727
20744
|
additionalProperties: false,
|
|
20728
20745
|
properties: {
|
|
20729
|
-
connectTimeoutMs: { type: "number" }
|
|
20746
|
+
connectTimeoutMs: { type: "number" },
|
|
20747
|
+
allowPrivateAddresses: { type: "boolean" }
|
|
20730
20748
|
}
|
|
20731
20749
|
},
|
|
20732
20750
|
"@sockethub/platform-xmpp": {
|
|
20733
20751
|
type: "object",
|
|
20734
20752
|
additionalProperties: false,
|
|
20735
20753
|
properties: {
|
|
20736
|
-
connectTimeoutMs: { type: "number" }
|
|
20754
|
+
connectTimeoutMs: { type: "number" },
|
|
20755
|
+
allowPrivateAddresses: { type: "boolean" }
|
|
20737
20756
|
}
|
|
20738
20757
|
},
|
|
20739
20758
|
"@sockethub/platform-metadata": {
|
|
@@ -20823,11 +20842,29 @@ var init_sockethub_config = __esm(() => {
|
|
|
20823
20842
|
type: "object",
|
|
20824
20843
|
additionalProperties: false,
|
|
20825
20844
|
properties: {
|
|
20845
|
+
maxInstancesPerSession: {
|
|
20846
|
+
type: "integer",
|
|
20847
|
+
minimum: 0,
|
|
20848
|
+
default: 10,
|
|
20849
|
+
description: "Maximum persistent instances per socket session. 0 disables the cap."
|
|
20850
|
+
},
|
|
20851
|
+
maxInstancesPerIp: {
|
|
20852
|
+
type: "integer",
|
|
20853
|
+
minimum: 0,
|
|
20854
|
+
default: 20,
|
|
20855
|
+
description: "Maximum persistent instances per client IP, including HTTP actions. 0 disables the cap."
|
|
20856
|
+
},
|
|
20857
|
+
maxStartsPerIpPerMinute: {
|
|
20858
|
+
type: "integer",
|
|
20859
|
+
minimum: 0,
|
|
20860
|
+
default: 60,
|
|
20861
|
+
description: "Maximum new persistent instances a client IP may start per minute, " + "including HTTP actions. Bounds fork/teardown churn that the " + "concurrent caps allow. Reusing a running instance does not count. " + "0 disables the cap."
|
|
20862
|
+
},
|
|
20826
20863
|
maxPlatformInstances: {
|
|
20827
20864
|
type: "number",
|
|
20828
20865
|
minimum: 0,
|
|
20829
20866
|
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."
|
|
20867
|
+
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
20868
|
}
|
|
20832
20869
|
}
|
|
20833
20870
|
},
|
|
@@ -27196,15 +27233,33 @@ var require_ajv = __commonJS(function(exports, module) {
|
|
|
27196
27233
|
} });
|
|
27197
27234
|
});
|
|
27198
27235
|
|
|
27236
|
+
// ../schemas/src/helpers/codegen.ts
|
|
27237
|
+
function isCodegenAvailable() {
|
|
27238
|
+
if (available === undefined) {
|
|
27239
|
+
try {
|
|
27240
|
+
new Function("return true");
|
|
27241
|
+
available = true;
|
|
27242
|
+
} catch {
|
|
27243
|
+
available = false;
|
|
27244
|
+
}
|
|
27245
|
+
}
|
|
27246
|
+
return available;
|
|
27247
|
+
}
|
|
27248
|
+
function warnCodegenUnavailable() {
|
|
27249
|
+
if (warned) {
|
|
27250
|
+
return;
|
|
27251
|
+
}
|
|
27252
|
+
warned = true;
|
|
27253
|
+
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.");
|
|
27254
|
+
}
|
|
27255
|
+
var available, warned = false;
|
|
27256
|
+
|
|
27199
27257
|
// ../schemas/src/schemas/service-descriptor.ts
|
|
27200
27258
|
var init_service_descriptor = () => {};
|
|
27201
27259
|
|
|
27202
27260
|
// ../schemas/src/service-descriptor.ts
|
|
27203
|
-
var import_ajv, ajv;
|
|
27204
27261
|
var init_service_descriptor2 = __esm(() => {
|
|
27205
27262
|
init_service_descriptor();
|
|
27206
|
-
import_ajv = __toESM(require_ajv(), 1);
|
|
27207
|
-
ajv = new import_ajv.default({ strictTypes: false, allErrors: true });
|
|
27208
27263
|
});
|
|
27209
27264
|
|
|
27210
27265
|
// ../../node_modules/ajv-formats/dist/formats.js
|
|
@@ -36752,15 +36807,35 @@ var init_error_parser = __esm(() => {
|
|
|
36752
36807
|
});
|
|
36753
36808
|
|
|
36754
36809
|
// ../schemas/src/validator.ts
|
|
36810
|
+
function getAjv() {
|
|
36811
|
+
if (!isCodegenAvailable()) {
|
|
36812
|
+
warnCodegenUnavailable();
|
|
36813
|
+
return;
|
|
36814
|
+
}
|
|
36815
|
+
if (!ajv) {
|
|
36816
|
+
const instance = new import_ajv.default({ strictTypes: false, allErrors: true });
|
|
36817
|
+
import_ajv_formats.default(instance);
|
|
36818
|
+
import_ajv_formats_draft2019.default(instance);
|
|
36819
|
+
for (const uri in schemas) {
|
|
36820
|
+
instance.addSchema(schemas[uri], uri);
|
|
36821
|
+
}
|
|
36822
|
+
ajv = instance;
|
|
36823
|
+
}
|
|
36824
|
+
return ajv;
|
|
36825
|
+
}
|
|
36755
36826
|
function registerSystemContext(platformId, contextUrl) {
|
|
36756
36827
|
registerPlatformContext(platformId, contextUrl, `${schemaURL}/context/${platformId}/messages`, `${schemaURL}/context/${platformId}/credentials`);
|
|
36828
|
+
const instance = getAjv();
|
|
36829
|
+
if (!instance) {
|
|
36830
|
+
return;
|
|
36831
|
+
}
|
|
36757
36832
|
const messageSchemaRef = `${schemaURL}/context/${platformId}/messages`;
|
|
36758
|
-
if (!
|
|
36759
|
-
|
|
36833
|
+
if (!instance.getSchema(messageSchemaRef)) {
|
|
36834
|
+
instance.addSchema({}, messageSchemaRef);
|
|
36760
36835
|
}
|
|
36761
36836
|
const credentialsSchemaRef = `${schemaURL}/context/${platformId}/credentials`;
|
|
36762
|
-
if (!
|
|
36763
|
-
|
|
36837
|
+
if (!instance.getSchema(credentialsSchemaRef)) {
|
|
36838
|
+
instance.addSchema({}, credentialsSchemaRef);
|
|
36764
36839
|
}
|
|
36765
36840
|
}
|
|
36766
36841
|
function registerSystemPlatformContexts() {
|
|
@@ -36772,17 +36847,21 @@ function registerSystemPlatformContexts() {
|
|
|
36772
36847
|
systemContextsRegistered = true;
|
|
36773
36848
|
}
|
|
36774
36849
|
function validateSockethubConfig(config) {
|
|
36850
|
+
const instance = getAjv();
|
|
36851
|
+
if (!instance) {
|
|
36852
|
+
return "";
|
|
36853
|
+
}
|
|
36775
36854
|
if (!sockethubConfigValidator) {
|
|
36776
|
-
sockethubConfigValidator =
|
|
36855
|
+
sockethubConfigValidator = instance.compile(SockethubConfigSchema);
|
|
36777
36856
|
}
|
|
36778
36857
|
if (sockethubConfigValidator(config)) {
|
|
36779
36858
|
return "";
|
|
36780
36859
|
}
|
|
36781
|
-
return
|
|
36860
|
+
return instance.errorsText(sockethubConfigValidator.errors, {
|
|
36782
36861
|
dataVar: "config"
|
|
36783
36862
|
});
|
|
36784
36863
|
}
|
|
36785
|
-
var
|
|
36864
|
+
var import_ajv, import_ajv_formats, import_ajv_formats_draft2019, schemaURL = "https://sockethub.org/schemas/v0", schemas, systemContextsRegistered = false, ajv, sockethubConfigValidator;
|
|
36786
36865
|
var init_validator = __esm(() => {
|
|
36787
36866
|
init_context();
|
|
36788
36867
|
init_error_parser();
|
|
@@ -36790,17 +36869,11 @@ var init_validator = __esm(() => {
|
|
|
36790
36869
|
init_activity_stream();
|
|
36791
36870
|
init_platform();
|
|
36792
36871
|
init_sockethub_config();
|
|
36793
|
-
|
|
36872
|
+
import_ajv = __toESM(require_ajv(), 1);
|
|
36794
36873
|
import_ajv_formats = __toESM(require_dist(), 1);
|
|
36795
36874
|
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
36875
|
schemas = {};
|
|
36800
36876
|
schemas[`${schemaURL}/activity-stream`] = ActivityStreamSchema;
|
|
36801
|
-
for (const uri in schemas) {
|
|
36802
|
-
ajv2.addSchema(schemas[uri], uri);
|
|
36803
|
-
}
|
|
36804
36877
|
registerSystemPlatformContexts();
|
|
36805
36878
|
});
|
|
36806
36879
|
|
|
@@ -73881,6 +73954,9 @@ var init_config_schema = __esm(() => {
|
|
|
73881
73954
|
"rateLimiter.maxRequests": { format: "nat" },
|
|
73882
73955
|
"rateLimiter.blockDurationMs": { format: "nat" },
|
|
73883
73956
|
"rateLimiter.maxConnectionsPerIp": { format: "nat" },
|
|
73957
|
+
"limits.maxInstancesPerSession": { format: "nat" },
|
|
73958
|
+
"limits.maxInstancesPerIp": { format: "nat" },
|
|
73959
|
+
"limits.maxStartsPerIpPerMinute": { format: "nat" },
|
|
73884
73960
|
"limits.maxPlatformInstances": { format: "nat" },
|
|
73885
73961
|
"credentials.ttlMs": {
|
|
73886
73962
|
format: "nat",
|
|
@@ -95701,6 +95777,7 @@ class JobWorker extends JobBase {
|
|
|
95701
95777
|
redisConfig;
|
|
95702
95778
|
queueId;
|
|
95703
95779
|
concurrency;
|
|
95780
|
+
maxStalledCount;
|
|
95704
95781
|
initialized = false;
|
|
95705
95782
|
constructor(parentId, instanceId, secret, redisConfig, options = {}) {
|
|
95706
95783
|
super(secret);
|
|
@@ -95709,6 +95786,7 @@ class JobWorker extends JobBase {
|
|
|
95709
95786
|
throw new Error(`JobWorker concurrency must be a positive integer, got ${options.concurrency}`);
|
|
95710
95787
|
}
|
|
95711
95788
|
this.concurrency = concurrency;
|
|
95789
|
+
this.maxStalledCount = options.maxStalledCount ?? 3;
|
|
95712
95790
|
this.log = createLogger(`data-layer:worker:${parentId}:${instanceId}`);
|
|
95713
95791
|
this.connectionName = getLoggerNamespace(this.log);
|
|
95714
95792
|
redisConfig.connectionName = this.connectionName;
|
|
@@ -95724,7 +95802,7 @@ class JobWorker extends JobBase {
|
|
|
95724
95802
|
this.worker = new import_bullmq2.Worker(queueName, this.jobHandler.bind(this), {
|
|
95725
95803
|
connection: this.redisConfig,
|
|
95726
95804
|
concurrency: this.concurrency,
|
|
95727
|
-
maxStalledCount:
|
|
95805
|
+
maxStalledCount: this.maxStalledCount
|
|
95728
95806
|
});
|
|
95729
95807
|
this.worker.on("error", (err) => {
|
|
95730
95808
|
this.log.warn(`worker error: ${err.message}`);
|
|
@@ -96165,7 +96243,10 @@ async function startPlatformProcess() {
|
|
|
96165
96243
|
}
|
|
96166
96244
|
}
|
|
96167
96245
|
const concurrency = getWorkerConcurrency();
|
|
96168
|
-
jobWorker = new JobWorker(parentId, queueInstanceId, parentSecret1 + parentSecret2, { url: redisUrl }, {
|
|
96246
|
+
jobWorker = new JobWorker(parentId, queueInstanceId, parentSecret1 + parentSecret2, { url: redisUrl }, {
|
|
96247
|
+
concurrency,
|
|
96248
|
+
maxStalledCount: platform.config.persist && platform.config.retryStalledJobs === false ? 0 : 3
|
|
96249
|
+
});
|
|
96169
96250
|
logger.info(`listening on the queue for incoming jobs (concurrency: ${concurrency})`);
|
|
96170
96251
|
jobWorker.onJob(getJobHandler());
|
|
96171
96252
|
jobWorkerStarted = true;
|
|
@@ -6,6 +6,8 @@ declare class ProcessManager {
|
|
|
6
6
|
private readonly parentSecret2;
|
|
7
7
|
private init;
|
|
8
8
|
private readonly ensureChains;
|
|
9
|
+
private readonly startsPerIp;
|
|
10
|
+
private startsWindowBegan;
|
|
9
11
|
constructor(parentId: string, parentSecret1: string, parentSecret2: string, init: IInitObject);
|
|
10
12
|
/**
|
|
11
13
|
* @param sessionId socket id to register with the instance; absent for HTTP
|
|
@@ -24,18 +26,19 @@ declare class ProcessManager {
|
|
|
24
26
|
*/
|
|
25
27
|
private ensureProcess;
|
|
26
28
|
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.
|
|
29
|
+
/** Stateless workers are bounded by the enabled platform count, independently
|
|
30
|
+
* of client occupancy. Check owners even when attaching to a shared worker.
|
|
37
31
|
*/
|
|
38
32
|
private assertInstanceCapacity;
|
|
33
|
+
/**
|
|
34
|
+
* Instance caps bound how many workers run at once, not how fast a client
|
|
35
|
+
* can churn them (e.g. replacing credentials forks a fresh worker each
|
|
36
|
+
* time). Budget new persistent starts per IP, the one key a client cannot
|
|
37
|
+
* rotate.
|
|
38
|
+
* shortcut: fixed one-minute window allows a 2x burst at the boundary;
|
|
39
|
+
* switch to a sliding window if that burst matters.
|
|
40
|
+
*/
|
|
41
|
+
private assertStartRate;
|
|
39
42
|
private isProcessAlive;
|
|
40
43
|
}
|
|
41
44
|
export default ProcessManager;
|
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.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"author": "Nick Jennings <nick@silverbucket.net>",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"bin": "bin/sockethub",
|
|
27
27
|
"preferGlobal": true,
|
|
28
28
|
"engines": {
|
|
29
|
-
"node": ">=20"
|
|
29
|
+
"node": ">=20.19"
|
|
30
30
|
},
|
|
31
31
|
"keywords": [
|
|
32
32
|
"sockethub",
|
|
@@ -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.2",
|
|
57
|
+
"@sockethub/data-layer": "^1.0.0-beta.2",
|
|
58
|
+
"@sockethub/logger": "^1.0.0-beta.2",
|
|
59
|
+
"@sockethub/schemas": "^3.0.0-beta.2",
|
|
60
|
+
"@sockethub/util": "^1.0.0-beta.2",
|
|
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,25 @@
|
|
|
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-
|
|
96
|
-
"@sockethub/platform-
|
|
97
|
-
"@sockethub/platform-
|
|
98
|
-
"@sockethub/platform-
|
|
94
|
+
"@sockethub/examples": "^1.0.0-beta.2",
|
|
95
|
+
"@sockethub/platform-caldav": "^1.0.0-beta.2",
|
|
96
|
+
"@sockethub/platform-carddav": "^1.0.0-beta.2",
|
|
97
|
+
"@sockethub/platform-dummy": "^3.0.0-beta.2",
|
|
98
|
+
"@sockethub/platform-email": "^1.0.0-beta.2",
|
|
99
|
+
"@sockethub/platform-feeds": "^4.0.0-beta.2",
|
|
100
|
+
"@sockethub/platform-instagram": "^1.0.0-beta.2",
|
|
101
|
+
"@sockethub/platform-irc": "^4.0.0-beta.2",
|
|
102
|
+
"@sockethub/platform-messenger": "^1.0.0-beta.2",
|
|
103
|
+
"@sockethub/platform-metadata": "^1.0.1-beta.2",
|
|
104
|
+
"@sockethub/platform-xmpp": "^5.0.0-beta.2"
|
|
99
105
|
},
|
|
100
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "d241420f9743f66a15ed083a1390595b331a96ac",
|
|
101
107
|
"types": "./dist/index.d.ts"
|
|
102
108
|
}
|