@hocuspocus/extension-throttle 1.0.0-alpha.48 → 1.0.0-alpha.49
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/hocuspocus-throttle.cjs +8 -1
- package/dist/hocuspocus-throttle.cjs.map +1 -1
- package/dist/hocuspocus-throttle.esm.js +8 -1
- package/dist/hocuspocus-throttle.esm.js.map +1 -1
- package/dist/packages/common/src/awarenessStatesToArray.d.ts +3 -0
- package/dist/packages/common/src/index.d.ts +1 -0
- package/dist/packages/extension-throttle/src/index.d.ts +6 -2
- package/dist/packages/provider/src/index.d.ts +0 -1
- package/dist/packages/server/src/types.d.ts +11 -1
- package/dist/tests/extension-throttle/configuration.d.ts +1 -0
- package/dist/tests/provider/observeDeep.d.ts +1 -0
- package/package.json +3 -3
- package/src/index.ts +12 -2
- package/dist/packages/provider/src/utils/awarenessStatesToArray.d.ts +0 -4
- package/dist/packages/provider/src/utils/index.d.ts +0 -1
|
@@ -3,13 +3,20 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
class Throttle {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Constructor
|
|
8
|
+
*/
|
|
9
|
+
constructor(configuration) {
|
|
7
10
|
this.configuration = {
|
|
8
11
|
throttle: 15,
|
|
9
12
|
banTime: 5,
|
|
10
13
|
};
|
|
11
14
|
this.connectionsByIp = new Map();
|
|
12
15
|
this.bannedIps = new Map();
|
|
16
|
+
this.configuration = {
|
|
17
|
+
...this.configuration,
|
|
18
|
+
...configuration,
|
|
19
|
+
};
|
|
13
20
|
}
|
|
14
21
|
/**
|
|
15
22
|
* Throttle requests
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hocuspocus-throttle.cjs","sources":["../src/index.ts"],"sourcesContent":["import {\n Extension,\n onConnectPayload,\n} from '@hocuspocus/server'\n\nexport interface
|
|
1
|
+
{"version":3,"file":"hocuspocus-throttle.cjs","sources":["../src/index.ts"],"sourcesContent":["import {\n Extension,\n onConnectPayload,\n} from '@hocuspocus/server'\n\nexport interface ThrottleConfiguration {\n throttle: number | null | false,\n banTime: number,\n}\n\nexport class Throttle implements Extension {\n\n configuration: ThrottleConfiguration = {\n throttle: 15,\n banTime: 5,\n }\n\n connectionsByIp: Map<string, Array<number>> = new Map()\n\n bannedIps: Map<string, number> = new Map()\n\n /**\n * Constructor\n */\n constructor(configuration?: Partial<ThrottleConfiguration>) {\n this.configuration = {\n ...this.configuration,\n ...configuration,\n }\n }\n\n /**\n * Throttle requests\n * @private\n */\n private throttle(ip: string): Boolean {\n if (!this.configuration.throttle) {\n return false\n }\n\n const bannedAt = this.bannedIps.get(ip) || 0\n\n if (Date.now() < (bannedAt + (this.configuration.banTime * 60 * 1000))) {\n return true\n }\n\n this.bannedIps.delete(ip)\n\n // add this connection try to the list of previous connections\n const previousConnections = this.connectionsByIp.get(ip) || []\n previousConnections.push(Date.now())\n\n // calculate the previous connections in the last minute\n const previousConnectionsInTheLastMinute = previousConnections\n .filter(timestamp => timestamp + (60 * 1000) > Date.now())\n\n this.connectionsByIp.set(ip, previousConnectionsInTheLastMinute)\n\n if (previousConnectionsInTheLastMinute.length > this.configuration.throttle) {\n this.bannedIps.set(ip, Date.now())\n return true\n }\n\n return false\n }\n\n /**\n * onConnect hook\n * @param data\n */\n onConnect(data: onConnectPayload): Promise<any> {\n const { request } = data\n\n // get the remote ip address\n const ip = request.headers['x-real-ip']\n || request.headers['x-forwarded-for']\n || request.socket.remoteAddress\n || ''\n\n // throttle the connection\n return this.throttle(<string> ip) ? Promise.reject() : Promise.resolve()\n }\n\n}\n"],"names":[],"mappings":";;;;MAUa,QAAQ;;;;IAcnB,YAAY,aAA8C;QAZ1D,kBAAa,GAA0B;YACrC,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,CAAC;SACX,CAAA;QAED,oBAAe,GAA+B,IAAI,GAAG,EAAE,CAAA;QAEvD,cAAS,GAAwB,IAAI,GAAG,EAAE,CAAA;QAMxC,IAAI,CAAC,aAAa,GAAG;YACnB,GAAG,IAAI,CAAC,aAAa;YACrB,GAAG,aAAa;SACjB,CAAA;KACF;;;;;IAMO,QAAQ,CAAC,EAAU;QACzB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;YAChC,OAAO,KAAK,CAAA;SACb;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QAE5C,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE;YACtE,OAAO,IAAI,CAAA;SACZ;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;;QAGzB,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;QAC9D,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;;QAGpC,MAAM,kCAAkC,GAAG,mBAAmB;aAC3D,MAAM,CAAC,SAAS,IAAI,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAE5D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,kCAAkC,CAAC,CAAA;QAEhE,IAAI,kCAAkC,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;YAC3E,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;SACZ;QAED,OAAO,KAAK,CAAA;KACb;;;;;IAMD,SAAS,CAAC,IAAsB;QAC9B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;;QAGxB,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;eAClC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;eAClC,OAAO,CAAC,MAAM,CAAC,aAAa;eAC5B,EAAE,CAAA;;QAGP,OAAO,IAAI,CAAC,QAAQ,CAAU,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;KACzE;;;;;"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
class Throttle {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Constructor
|
|
4
|
+
*/
|
|
5
|
+
constructor(configuration) {
|
|
3
6
|
this.configuration = {
|
|
4
7
|
throttle: 15,
|
|
5
8
|
banTime: 5,
|
|
6
9
|
};
|
|
7
10
|
this.connectionsByIp = new Map();
|
|
8
11
|
this.bannedIps = new Map();
|
|
12
|
+
this.configuration = {
|
|
13
|
+
...this.configuration,
|
|
14
|
+
...configuration,
|
|
15
|
+
};
|
|
9
16
|
}
|
|
10
17
|
/**
|
|
11
18
|
* Throttle requests
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hocuspocus-throttle.esm.js","sources":["../src/index.ts"],"sourcesContent":["import {\n Extension,\n onConnectPayload,\n} from '@hocuspocus/server'\n\nexport interface
|
|
1
|
+
{"version":3,"file":"hocuspocus-throttle.esm.js","sources":["../src/index.ts"],"sourcesContent":["import {\n Extension,\n onConnectPayload,\n} from '@hocuspocus/server'\n\nexport interface ThrottleConfiguration {\n throttle: number | null | false,\n banTime: number,\n}\n\nexport class Throttle implements Extension {\n\n configuration: ThrottleConfiguration = {\n throttle: 15,\n banTime: 5,\n }\n\n connectionsByIp: Map<string, Array<number>> = new Map()\n\n bannedIps: Map<string, number> = new Map()\n\n /**\n * Constructor\n */\n constructor(configuration?: Partial<ThrottleConfiguration>) {\n this.configuration = {\n ...this.configuration,\n ...configuration,\n }\n }\n\n /**\n * Throttle requests\n * @private\n */\n private throttle(ip: string): Boolean {\n if (!this.configuration.throttle) {\n return false\n }\n\n const bannedAt = this.bannedIps.get(ip) || 0\n\n if (Date.now() < (bannedAt + (this.configuration.banTime * 60 * 1000))) {\n return true\n }\n\n this.bannedIps.delete(ip)\n\n // add this connection try to the list of previous connections\n const previousConnections = this.connectionsByIp.get(ip) || []\n previousConnections.push(Date.now())\n\n // calculate the previous connections in the last minute\n const previousConnectionsInTheLastMinute = previousConnections\n .filter(timestamp => timestamp + (60 * 1000) > Date.now())\n\n this.connectionsByIp.set(ip, previousConnectionsInTheLastMinute)\n\n if (previousConnectionsInTheLastMinute.length > this.configuration.throttle) {\n this.bannedIps.set(ip, Date.now())\n return true\n }\n\n return false\n }\n\n /**\n * onConnect hook\n * @param data\n */\n onConnect(data: onConnectPayload): Promise<any> {\n const { request } = data\n\n // get the remote ip address\n const ip = request.headers['x-real-ip']\n || request.headers['x-forwarded-for']\n || request.socket.remoteAddress\n || ''\n\n // throttle the connection\n return this.throttle(<string> ip) ? Promise.reject() : Promise.resolve()\n }\n\n}\n"],"names":[],"mappings":"MAUa,QAAQ;;;;IAcnB,YAAY,aAA8C;QAZ1D,kBAAa,GAA0B;YACrC,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,CAAC;SACX,CAAA;QAED,oBAAe,GAA+B,IAAI,GAAG,EAAE,CAAA;QAEvD,cAAS,GAAwB,IAAI,GAAG,EAAE,CAAA;QAMxC,IAAI,CAAC,aAAa,GAAG;YACnB,GAAG,IAAI,CAAC,aAAa;YACrB,GAAG,aAAa;SACjB,CAAA;KACF;;;;;IAMO,QAAQ,CAAC,EAAU;QACzB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;YAChC,OAAO,KAAK,CAAA;SACb;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QAE5C,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE;YACtE,OAAO,IAAI,CAAA;SACZ;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;;QAGzB,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;QAC9D,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;;QAGpC,MAAM,kCAAkC,GAAG,mBAAmB;aAC3D,MAAM,CAAC,SAAS,IAAI,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAE5D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,kCAAkC,CAAC,CAAA;QAEhE,IAAI,kCAAkC,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE;YAC3E,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;YAClC,OAAO,IAAI,CAAA;SACZ;QAED,OAAO,KAAK,CAAA;KACb;;;;;IAMD,SAAS,CAAC,IAAsB;QAC9B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;;QAGxB,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;eAClC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;eAClC,OAAO,CAAC,MAAM,CAAC,aAAa;eAC5B,EAAE,CAAA;;QAGP,OAAO,IAAI,CAAC,QAAQ,CAAU,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;KACzE;;;;;"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { Extension, onConnectPayload } from '@hocuspocus/server';
|
|
2
|
-
export interface
|
|
2
|
+
export interface ThrottleConfiguration {
|
|
3
3
|
throttle: number | null | false;
|
|
4
4
|
banTime: number;
|
|
5
5
|
}
|
|
6
6
|
export declare class Throttle implements Extension {
|
|
7
|
-
configuration:
|
|
7
|
+
configuration: ThrottleConfiguration;
|
|
8
8
|
connectionsByIp: Map<string, Array<number>>;
|
|
9
9
|
bannedIps: Map<string, number>;
|
|
10
|
+
/**
|
|
11
|
+
* Constructor
|
|
12
|
+
*/
|
|
13
|
+
constructor(configuration?: Partial<ThrottleConfiguration>);
|
|
10
14
|
/**
|
|
11
15
|
* Throttle requests
|
|
12
16
|
* @private
|
|
@@ -38,6 +38,7 @@ export interface Extension {
|
|
|
38
38
|
onListen?(data: onListenPayload): Promise<any>;
|
|
39
39
|
onUpgrade?(data: onUpgradePayload): Promise<any>;
|
|
40
40
|
onConnect?(data: onConnectPayload): Promise<any>;
|
|
41
|
+
connected?(data: connectedPayload): Promise<any>;
|
|
41
42
|
onAuthenticate?(data: onAuthenticatePayload): Promise<any>;
|
|
42
43
|
/**
|
|
43
44
|
* @deprecated onCreateDocument is deprecated, use onLoadDocument instead
|
|
@@ -53,7 +54,7 @@ export interface Extension {
|
|
|
53
54
|
onDisconnect?(data: onDisconnectPayload): Promise<any>;
|
|
54
55
|
onDestroy?(data: onDestroyPayload): Promise<any>;
|
|
55
56
|
}
|
|
56
|
-
export declare type Hook = 'onConfigure' | 'onListen' | 'onUpgrade' | 'onConnect' | 'onAuthenticate' |
|
|
57
|
+
export declare type Hook = 'onConfigure' | 'onListen' | 'onUpgrade' | 'onConnect' | 'connected' | 'onAuthenticate' |
|
|
57
58
|
/**
|
|
58
59
|
* @deprecated onCreateDocument is deprecated, use onLoadDocument instead
|
|
59
60
|
*/
|
|
@@ -116,6 +117,15 @@ export interface onConnectPayload {
|
|
|
116
117
|
socketId: string;
|
|
117
118
|
connection: ConnectionConfiguration;
|
|
118
119
|
}
|
|
120
|
+
export interface connectedPayload {
|
|
121
|
+
documentName: string;
|
|
122
|
+
instance: Hocuspocus;
|
|
123
|
+
request: IncomingMessage;
|
|
124
|
+
requestHeaders: IncomingHttpHeaders;
|
|
125
|
+
requestParameters: URLSearchParams;
|
|
126
|
+
socketId: string;
|
|
127
|
+
connection: ConnectionConfiguration;
|
|
128
|
+
}
|
|
119
129
|
export interface onLoadDocumentPayload {
|
|
120
130
|
context: any;
|
|
121
131
|
document: Document;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hocuspocus/extension-throttle",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.49",
|
|
4
4
|
"description": "hocuspocus throttle extension",
|
|
5
5
|
"homepage": "https://hocuspocus.dev",
|
|
6
6
|
"keywords": [
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dist"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@hocuspocus/server": "^1.0.0-alpha.
|
|
30
|
+
"@hocuspocus/server": "^1.0.0-alpha.93"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "05a7eb3d660175613d2fe7b6d9ec030e8e509683"
|
|
33
33
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
onConnectPayload,
|
|
4
4
|
} from '@hocuspocus/server'
|
|
5
5
|
|
|
6
|
-
export interface
|
|
6
|
+
export interface ThrottleConfiguration {
|
|
7
7
|
throttle: number | null | false,
|
|
8
8
|
banTime: number,
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export class Throttle implements Extension {
|
|
12
12
|
|
|
13
|
-
configuration:
|
|
13
|
+
configuration: ThrottleConfiguration = {
|
|
14
14
|
throttle: 15,
|
|
15
15
|
banTime: 5,
|
|
16
16
|
}
|
|
@@ -19,6 +19,16 @@ export class Throttle implements Extension {
|
|
|
19
19
|
|
|
20
20
|
bannedIps: Map<string, number> = new Map()
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Constructor
|
|
24
|
+
*/
|
|
25
|
+
constructor(configuration?: Partial<ThrottleConfiguration>) {
|
|
26
|
+
this.configuration = {
|
|
27
|
+
...this.configuration,
|
|
28
|
+
...configuration,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
/**
|
|
23
33
|
* Throttle requests
|
|
24
34
|
* @private
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as awarenessStatesToArray } from './awarenessStatesToArray';
|