consolidate build scripts, reorganize source into src/ directory, fix favicon injection

This commit is contained in:
Nystik
2026-03-20 23:46:17 +01:00
parent 2add5238b8
commit 0747a4540d
56 changed files with 46 additions and 45 deletions

View File

@@ -0,0 +1,74 @@
export function createHash(algorithm) {
const alg = algorithm.toUpperCase().replace("-", "");
const subtleAlg =
alg === "SHA256"
? "SHA-256"
: alg === "SHA1"
? "SHA-1"
: alg === "SHA512"
? "SHA-512"
: alg;
let inputData = new Uint8Array(0);
return {
update(data) {
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
const merged = new Uint8Array(inputData.length + data.length);
merged.set(inputData);
merged.set(data, inputData.length);
inputData = merged;
return this;
},
digest(encoding) {
console.warn("[shim:crypto] createHash.digest - using placeholder");
const hash = simpleHash(inputData);
if (encoding === "hex") {
return hash;
}
if (encoding === "base64") {
return btoa(hash);
}
return hash;
},
async digestAsync(encoding) {
const hashBuffer = await crypto.subtle.digest(subtleAlg, inputData);
const hashArray = new Uint8Array(hashBuffer);
if (encoding === "hex") {
return Array.from(hashArray)
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
if (encoding === "base64") {
return btoa(String.fromCharCode(...hashArray));
}
return hashArray;
},
};
}
function simpleHash(data) {
let hash = 0;
for (let i = 0; i < data.length; i++) {
hash = ((hash << 5) - hash + data[i]) | 0;
}
return Math.abs(hash).toString(16).padStart(8, "0");
}

View File

@@ -0,0 +1,9 @@
import { randomBytes } from "./random-bytes.js";
import { createHash } from "./create-hash.js";
import { scrypt } from "./scrypt.js";
export const cryptoShim = {
randomBytes,
createHash,
scrypt,
};

View File

@@ -0,0 +1,20 @@
export function randomBytes(size) {
const buf = new Uint8Array(size);
crypto.getRandomValues(buf);
buf.toString = function (encoding) {
if (encoding === "hex") {
return Array.from(this)
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
if (encoding === "base64") {
return btoa(String.fromCharCode(...this));
}
return new TextDecoder().decode(this);
};
return buf;
}

View File

@@ -0,0 +1,26 @@
export function scrypt(password, salt, keylen, options, callback) {
if (typeof options === "function") {
callback = options;
options = {};
}
const N = options?.N || 32768;
const r = options?.r || 8;
const p = options?.p || 1;
if (window.scrypt && window.scrypt.scrypt) {
const pwBytes =
typeof password === "string"
? new TextEncoder().encode(password)
: password;
const saltBytes =
typeof salt === "string" ? new TextEncoder().encode(salt) : salt;
window.scrypt
.scrypt(pwBytes, saltBytes, N, r, p, keylen)
.then((result) => callback(null, new Uint8Array(result)))
.catch((err) => callback(err));
} else {
callback(new Error("scrypt not available"));
}
}