@couch-kit/core 0.5.1 → 0.6.0
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/CHANGELOG.md +29 -0
- package/dist/index.js +9 -1
- package/lib/constants.d.ts +14 -8
- package/lib/constants.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +23 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @couch-kit/core
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#16](https://github.com/faluciano/react-native-couch-kit/pull/16) [`86b5ff3`](https://github.com/faluciano/react-native-couch-kit/commit/86b5ff353ce9baac0c48e6a8315bbb57eb155daf) Thanks [@faluciano](https://github.com/faluciano)! - ### Phase 1: Quick Wins — Bug Fixes, Security, and Cleanup
|
|
8
|
+
|
|
9
|
+
**Bug fixes:**
|
|
10
|
+
- Fix `simulate` command: add missing `secret` to JOIN payload so bots are no longer rejected with `INVALID_SECRET`
|
|
11
|
+
- Send `RECONNECTED` message (instead of `WELCOME`) when a player reconnects, enabling clients to distinguish reconnections
|
|
12
|
+
- Wire `ASSETS_LOADED` end-to-end: `usePreload` now accepts an optional `sendMessage` callback to notify the host when assets finish loading; host tracks per-player asset status
|
|
13
|
+
- Include dispatched action(s) in `STATE_UPDATE` broadcasts via an action queue, so clients receive the `action` field
|
|
14
|
+
|
|
15
|
+
**Security:**
|
|
16
|
+
- Replace `derivePlayerId` with SHA-256 (Web Crypto API) — the old implementation exposed the first 16 hex chars of the player secret
|
|
17
|
+
- Add dual-derivation migration: host tries SHA-256 first, falls back to legacy ID for existing players
|
|
18
|
+
- Add per-socket rate limiting (60 actions/second) with `RATE_LIMITED` error response
|
|
19
|
+
- Cache `socketId → playerId` mapping to avoid async derivation in hot paths
|
|
20
|
+
|
|
21
|
+
**Cleanup:**
|
|
22
|
+
- Remove dead code: `buffer-utils.ts`, `declarations.d.ts`, and their test file (TCP WebSocket remnants)
|
|
23
|
+
- Deprecate unused constants: `MAX_FRAME_SIZE`, `KEEPALIVE_INTERVAL`, `KEEPALIVE_TIMEOUT` (will be removed in next major)
|
|
24
|
+
- Extract `DEFAULT_DISCONNECT_TIMEOUT` constant (replaces hardcoded 5-minute magic number)
|
|
25
|
+
- Add configurable `disconnectTimeout` to `GameHostConfig`
|
|
26
|
+
|
|
27
|
+
**DX improvements:**
|
|
28
|
+
- Auto-detect package manager in `bundle` command (checks lock files instead of hardcoding `bun`)
|
|
29
|
+
- Show build output (`stdio: "inherit"` instead of `"ignore"`)
|
|
30
|
+
- Log bot WELCOME/ERROR responses in `simulate` command
|
|
31
|
+
|
|
3
32
|
## 0.5.1
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -89,6 +89,7 @@ var DEFAULT_BASE_DELAY = 1000;
|
|
|
89
89
|
var DEFAULT_MAX_DELAY = 1e4;
|
|
90
90
|
var DEFAULT_SYNC_INTERVAL = 5000;
|
|
91
91
|
var MAX_PENDING_PINGS = 50;
|
|
92
|
+
var DEFAULT_DISCONNECT_TIMEOUT = 5 * 60 * 1000;
|
|
92
93
|
var KEEPALIVE_INTERVAL = 30000;
|
|
93
94
|
var KEEPALIVE_TIMEOUT = 1e4;
|
|
94
95
|
function generateId() {
|
|
@@ -108,7 +109,12 @@ function isValidSecret(secret) {
|
|
|
108
109
|
const hex = secret.replace(/-/g, "");
|
|
109
110
|
return hex.length >= 32 && /^[0-9a-f]+$/i.test(hex);
|
|
110
111
|
}
|
|
111
|
-
function derivePlayerId(secret) {
|
|
112
|
+
async function derivePlayerId(secret) {
|
|
113
|
+
const data = new TextEncoder().encode(secret);
|
|
114
|
+
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
115
|
+
return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 16);
|
|
116
|
+
}
|
|
117
|
+
function derivePlayerIdLegacy(secret) {
|
|
112
118
|
return secret.replace(/-/g, "").slice(0, 16);
|
|
113
119
|
}
|
|
114
120
|
function toErrorMessage(error) {
|
|
@@ -120,6 +126,7 @@ export {
|
|
|
120
126
|
toErrorMessage,
|
|
121
127
|
isValidSecret,
|
|
122
128
|
generateId,
|
|
129
|
+
derivePlayerIdLegacy,
|
|
123
130
|
derivePlayerId,
|
|
124
131
|
createGameReducer,
|
|
125
132
|
MessageTypes,
|
|
@@ -133,5 +140,6 @@ export {
|
|
|
133
140
|
DEFAULT_MAX_RETRIES,
|
|
134
141
|
DEFAULT_MAX_DELAY,
|
|
135
142
|
DEFAULT_HTTP_PORT,
|
|
143
|
+
DEFAULT_DISCONNECT_TIMEOUT,
|
|
136
144
|
DEFAULT_BASE_DELAY
|
|
137
145
|
};
|
package/lib/constants.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
export declare const DEFAULT_HTTP_PORT = 8080;
|
|
4
4
|
/** Default WebSocket port offset from the HTTP port (skips Metro on +1). */
|
|
5
5
|
export declare const DEFAULT_WS_PORT_OFFSET = 2;
|
|
6
|
-
/**
|
|
6
|
+
/** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
|
|
7
7
|
export declare const MAX_FRAME_SIZE: number;
|
|
8
8
|
/** Default maximum reconnection attempts for the client. */
|
|
9
9
|
export declare const DEFAULT_MAX_RETRIES = 5;
|
|
@@ -15,9 +15,11 @@ export declare const DEFAULT_MAX_DELAY = 10000;
|
|
|
15
15
|
export declare const DEFAULT_SYNC_INTERVAL = 5000;
|
|
16
16
|
/** Maximum number of outstanding pings before cleanup. */
|
|
17
17
|
export declare const MAX_PENDING_PINGS = 50;
|
|
18
|
-
/**
|
|
18
|
+
/** Default timeout (ms) before a disconnected player is removed from state. */
|
|
19
|
+
export declare const DEFAULT_DISCONNECT_TIMEOUT: number;
|
|
20
|
+
/** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
|
|
19
21
|
export declare const KEEPALIVE_INTERVAL = 30000;
|
|
20
|
-
/**
|
|
22
|
+
/** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
|
|
21
23
|
export declare const KEEPALIVE_TIMEOUT = 10000;
|
|
22
24
|
/**
|
|
23
25
|
* Generate a cryptographically random ID string.
|
|
@@ -31,13 +33,17 @@ export declare function generateId(): string;
|
|
|
31
33
|
*/
|
|
32
34
|
export declare function isValidSecret(secret: string): boolean;
|
|
33
35
|
/**
|
|
34
|
-
* Derives a stable, public player ID from a secret UUID.
|
|
36
|
+
* Derives a stable, public player ID from a secret UUID using SHA-256.
|
|
35
37
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* state that gets broadcast to all clients.
|
|
38
|
+
* Takes the first 16 hex characters of the SHA-256 hash, producing
|
|
39
|
+
* a deterministic ID that cannot be reversed to recover the secret.
|
|
39
40
|
*/
|
|
40
|
-
export declare function derivePlayerId(secret: string): string
|
|
41
|
+
export declare function derivePlayerId(secret: string): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated Legacy player ID derivation. Insecure — exposes first 16 hex chars of secret.
|
|
44
|
+
* Kept temporarily for dual-derivation migration in the host. Will be removed in next major.
|
|
45
|
+
*/
|
|
46
|
+
export declare function derivePlayerIdLegacy(secret: string): string;
|
|
41
47
|
/**
|
|
42
48
|
* Safely extract an error message from an unknown caught value.
|
|
43
49
|
* In JavaScript, anything can be thrown -- this normalizes it.
|
package/lib/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,4EAA4E;AAC5E,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,8FAA8F;AAC9F,eAAO,MAAM,cAAc,QAAc,CAAC;AAE1C,4DAA4D;AAC5D,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,QAAgB,CAAC;AAExD,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAExC,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAwBnC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOpE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGrD"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -6,7 +6,7 @@ export const DEFAULT_HTTP_PORT = 8080;
|
|
|
6
6
|
/** Default WebSocket port offset from the HTTP port (skips Metro on +1). */
|
|
7
7
|
export const DEFAULT_WS_PORT_OFFSET = 2;
|
|
8
8
|
|
|
9
|
-
/**
|
|
9
|
+
/** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
|
|
10
10
|
export const MAX_FRAME_SIZE = 1024 * 1024;
|
|
11
11
|
|
|
12
12
|
/** Default maximum reconnection attempts for the client. */
|
|
@@ -24,10 +24,13 @@ export const DEFAULT_SYNC_INTERVAL = 5000;
|
|
|
24
24
|
/** Maximum number of outstanding pings before cleanup. */
|
|
25
25
|
export const MAX_PENDING_PINGS = 50;
|
|
26
26
|
|
|
27
|
-
/**
|
|
27
|
+
/** Default timeout (ms) before a disconnected player is removed from state. */
|
|
28
|
+
export const DEFAULT_DISCONNECT_TIMEOUT = 5 * 60 * 1000;
|
|
29
|
+
|
|
30
|
+
/** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
|
|
28
31
|
export const KEEPALIVE_INTERVAL = 30000;
|
|
29
32
|
|
|
30
|
-
/**
|
|
33
|
+
/** @deprecated Not used by Couch Kit internals. Will be removed in the next major version. */
|
|
31
34
|
export const KEEPALIVE_TIMEOUT = 10000;
|
|
32
35
|
|
|
33
36
|
/**
|
|
@@ -71,13 +74,25 @@ export function isValidSecret(secret: string): boolean {
|
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
/**
|
|
74
|
-
* Derives a stable, public player ID from a secret UUID.
|
|
77
|
+
* Derives a stable, public player ID from a secret UUID using SHA-256.
|
|
75
78
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
|
|
79
|
+
* Takes the first 16 hex characters of the SHA-256 hash, producing
|
|
80
|
+
* a deterministic ID that cannot be reversed to recover the secret.
|
|
81
|
+
*/
|
|
82
|
+
export async function derivePlayerId(secret: string): Promise<string> {
|
|
83
|
+
const data = new TextEncoder().encode(secret);
|
|
84
|
+
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
85
|
+
return Array.from(new Uint8Array(hash))
|
|
86
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
87
|
+
.join("")
|
|
88
|
+
.slice(0, 16);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @deprecated Legacy player ID derivation. Insecure — exposes first 16 hex chars of secret.
|
|
93
|
+
* Kept temporarily for dual-derivation migration in the host. Will be removed in next major.
|
|
79
94
|
*/
|
|
80
|
-
export function
|
|
95
|
+
export function derivePlayerIdLegacy(secret: string): string {
|
|
81
96
|
return secret.replace(/-/g, "").slice(0, 16);
|
|
82
97
|
}
|
|
83
98
|
|