add fallback to hash

This commit is contained in:
PhilReact 2025-03-27 15:55:29 +02:00
parent 36e00390e7
commit 069eca59d0
3 changed files with 104 additions and 13 deletions

78
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "qapp-core",
"version": "1.0.9",
"version": "1.0.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "qapp-core",
"version": "1.0.9",
"version": "1.0.11",
"license": "MIT",
"dependencies": {
"@emotion/react": "^11.14.0",
@ -18,6 +18,7 @@
"bloom-filters": "^3.0.4",
"buffer": "^6.0.3",
"compressorjs": "^1.2.1",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"dompurify": "^3.2.4",
"react": "^19.0.0",
@ -28,6 +29,7 @@
"zustand": "^4.3.2"
},
"devDependencies": {
"@types/crypto-js": "^4.2.2",
"tsup": "^8.4.0",
"typescript": "^5.2.0"
}
@ -1269,6 +1271,12 @@
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@types/crypto-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz",
"integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==",
"dev": true
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@ -1594,6 +1602,11 @@
"node": ">= 8"
}
},
"node_modules/crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@ -2094,6 +2107,26 @@
"thenify-all": "^1.0.0"
}
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"optional": true,
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -2200,6 +2233,36 @@
"node": ">= 6"
}
},
"node_modules/postcss": {
"version": "8.5.3",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"optional": true,
"peer": true,
"dependencies": {
"nanoid": "^3.3.8",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-load-config": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
@ -2506,6 +2569,17 @@
"node": ">= 8"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",

View File

@ -29,6 +29,7 @@
"bloom-filters": "^3.0.4",
"buffer": "^6.0.3",
"compressorjs": "^1.2.1",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"dompurify": "^3.2.4",
"react": "^19.0.0",
@ -39,6 +40,7 @@
"zustand": "^4.3.2"
},
"devDependencies": {
"@types/crypto-js": "^4.2.2",
"tsup": "^8.4.0",
"typescript": "^5.2.0"
},

View File

@ -4,6 +4,8 @@ import { objectToBase64, uint8ArrayToBase64 } from "./base64";
import { RequestQueueWithPromise } from "./queue";
import { base64ToUint8Array } from "./publish";
import nacl from "../deps/nacl-fast";
import SHA256 from 'crypto-js/sha256';
import EncBase64 from 'crypto-js/enc-base64';
export const requestQueueGetPublicKeys = new RequestQueueWithPromise(10);
@ -19,18 +21,31 @@ export async function hashWord(
word: string,
collisionStrength: number,
publicSalt: string
) {
const saltedWord = publicSalt + word; // Use public salt directly
const encoded = new TextEncoder().encode(saltedWord);
const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
): Promise<string> {
const saltedWord = publicSalt + word;
// Convert to base64 and make it URL-safe
return Buffer.from(hashBuffer)
.toString("base64")
.replace(/\+/g, "-") // Replace '+' with '-'
.replace(/\//g, "_") // Replace '/' with '_'
.replace(/=+$/, "") // Remove trailing '='
.slice(0, collisionStrength);
try {
if (!crypto?.subtle?.digest) throw new Error("Web Crypto not available");
const encoded = new TextEncoder().encode(saltedWord);
const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
return Buffer.from(hashBuffer)
.toString("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "")
.slice(0, collisionStrength);
} catch (err) {
const hash = SHA256(saltedWord);
const base64 = EncBase64.stringify(hash);
return base64
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "")
.slice(0, collisionStrength);
}
}
const uid = new ShortUniqueId({ length: 10, dictionary: "alphanum" });