@couch-kit/core 0.8.1 → 0.8.3
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 +12 -0
- package/dist/index.js +10 -7
- package/lib/constants.d.ts +3 -0
- package/lib/constants.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +23 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @couch-kit/core
|
|
2
2
|
|
|
3
|
+
## 0.8.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#33](https://github.com/faluciano/react-native-couch-kit/pull/33) [`8773b1d`](https://github.com/faluciano/react-native-couch-kit/commit/8773b1d8687247f3f77faf116c041a26c634c8d0) Thanks [@faluciano](https://github.com/faluciano)! - Access `crypto` via `globalThis.crypto` to avoid `ReferenceError` in React Native's Hermes engine where `typeof crypto` throws instead of returning `"undefined"`. Fixes `derivePlayerId` and `generateId` on Android TV.
|
|
8
|
+
|
|
9
|
+
## 0.8.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#31](https://github.com/faluciano/react-native-couch-kit/pull/31) [`e5178dc`](https://github.com/faluciano/react-native-couch-kit/commit/e5178dc666f95c2893e803f1f290abcfd7db6306) Thanks [@faluciano](https://github.com/faluciano)! - Fall back to legacy player ID derivation when `crypto.subtle` is unavailable (React Native / Hermes). Previously, `derivePlayerId` unconditionally called `crypto.subtle.digest("SHA-256", ...)` which threw in Hermes, silently preventing the JOIN handshake from completing and leaving clients stuck on a loading spinner.
|
|
14
|
+
|
|
3
15
|
## 0.8.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -172,12 +172,12 @@ var DEFAULT_DISCONNECT_TIMEOUT = 5 * 60 * 1000;
|
|
|
172
172
|
var KEEPALIVE_INTERVAL = 30000;
|
|
173
173
|
var KEEPALIVE_TIMEOUT = 1e4;
|
|
174
174
|
function generateId() {
|
|
175
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
176
|
-
return crypto.randomUUID();
|
|
175
|
+
if (typeof globalThis.crypto !== "undefined" && typeof globalThis.crypto.randomUUID === "function") {
|
|
176
|
+
return globalThis.crypto.randomUUID();
|
|
177
177
|
}
|
|
178
|
-
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
178
|
+
if (typeof globalThis.crypto !== "undefined" && typeof globalThis.crypto.getRandomValues === "function") {
|
|
179
179
|
const bytes = new Uint8Array(16);
|
|
180
|
-
crypto.getRandomValues(bytes);
|
|
180
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
181
181
|
return Array.from(bytes).map((b2) => b2.toString(16).padStart(2, "0")).join("");
|
|
182
182
|
}
|
|
183
183
|
const a = Math.random().toString(36).substring(2, 15);
|
|
@@ -189,9 +189,12 @@ function isValidSecret(secret) {
|
|
|
189
189
|
return hex.length >= 32 && /^[0-9a-f]+$/i.test(hex);
|
|
190
190
|
}
|
|
191
191
|
async function derivePlayerId(secret) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
if (typeof globalThis.crypto !== "undefined" && typeof globalThis.crypto.subtle?.digest === "function") {
|
|
193
|
+
const data = new TextEncoder().encode(secret);
|
|
194
|
+
const hash = await globalThis.crypto.subtle.digest("SHA-256", data);
|
|
195
|
+
return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 16);
|
|
196
|
+
}
|
|
197
|
+
return derivePlayerIdLegacy(secret);
|
|
195
198
|
}
|
|
196
199
|
function derivePlayerIdLegacy(secret) {
|
|
197
200
|
return secret.replace(/-/g, "").slice(0, 16);
|
package/lib/constants.d.ts
CHANGED
|
@@ -39,6 +39,9 @@ export declare function isValidSecret(secret: string): boolean;
|
|
|
39
39
|
*
|
|
40
40
|
* Takes the first 16 hex characters of the SHA-256 hash, producing
|
|
41
41
|
* a deterministic ID that cannot be reversed to recover the secret.
|
|
42
|
+
*
|
|
43
|
+
* Falls back to {@link derivePlayerIdLegacy} when the Web Crypto API
|
|
44
|
+
* (`crypto.subtle`) is unavailable (e.g. React Native / Hermes).
|
|
42
45
|
*/
|
|
43
46
|
export declare function derivePlayerId(secret: string): Promise<string>;
|
|
44
47
|
/**
|
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,0DAA0D;AAC1D,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,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
|
|
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,0DAA0D;AAC1D,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,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;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAepE;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
|
@@ -44,19 +44,19 @@ export const KEEPALIVE_TIMEOUT = 10000;
|
|
|
44
44
|
*/
|
|
45
45
|
export function generateId(): string {
|
|
46
46
|
if (
|
|
47
|
-
typeof crypto !== "undefined" &&
|
|
48
|
-
typeof crypto.randomUUID === "function"
|
|
47
|
+
typeof globalThis.crypto !== "undefined" &&
|
|
48
|
+
typeof globalThis.crypto.randomUUID === "function"
|
|
49
49
|
) {
|
|
50
|
-
return crypto.randomUUID();
|
|
50
|
+
return globalThis.crypto.randomUUID();
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// Fallback: 32 hex chars from crypto.getRandomValues
|
|
54
54
|
if (
|
|
55
|
-
typeof crypto !== "undefined" &&
|
|
56
|
-
typeof crypto.getRandomValues === "function"
|
|
55
|
+
typeof globalThis.crypto !== "undefined" &&
|
|
56
|
+
typeof globalThis.crypto.getRandomValues === "function"
|
|
57
57
|
) {
|
|
58
58
|
const bytes = new Uint8Array(16);
|
|
59
|
-
crypto.getRandomValues(bytes);
|
|
59
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
60
60
|
return Array.from(bytes)
|
|
61
61
|
.map((b) => b.toString(16).padStart(2, "0"))
|
|
62
62
|
.join("");
|
|
@@ -81,14 +81,25 @@ export function isValidSecret(secret: string): boolean {
|
|
|
81
81
|
*
|
|
82
82
|
* Takes the first 16 hex characters of the SHA-256 hash, producing
|
|
83
83
|
* a deterministic ID that cannot be reversed to recover the secret.
|
|
84
|
+
*
|
|
85
|
+
* Falls back to {@link derivePlayerIdLegacy} when the Web Crypto API
|
|
86
|
+
* (`crypto.subtle`) is unavailable (e.g. React Native / Hermes).
|
|
84
87
|
*/
|
|
85
88
|
export async function derivePlayerId(secret: string): Promise<string> {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.
|
|
91
|
-
.
|
|
89
|
+
if (
|
|
90
|
+
typeof globalThis.crypto !== "undefined" &&
|
|
91
|
+
typeof globalThis.crypto.subtle?.digest === "function"
|
|
92
|
+
) {
|
|
93
|
+
const data = new TextEncoder().encode(secret);
|
|
94
|
+
const hash = await globalThis.crypto.subtle.digest("SHA-256", data);
|
|
95
|
+
return Array.from(new Uint8Array(hash))
|
|
96
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
97
|
+
.join("")
|
|
98
|
+
.slice(0, 16);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Web Crypto unavailable (React Native / Hermes) — fall back to legacy derivation
|
|
102
|
+
return derivePlayerIdLegacy(secret);
|
|
92
103
|
}
|
|
93
104
|
|
|
94
105
|
/**
|