diff --git a/resources/scripts/install-bun.js b/resources/scripts/install-bun.js index 78354f8f..6ed512d1 100644 --- a/resources/scripts/install-bun.js +++ b/resources/scripts/install-bun.js @@ -14,7 +14,6 @@ /* global console, process */ import AdmZip from 'adm-zip'; -import { execSync } from 'child_process'; import fs from 'fs'; import os from 'os'; import path from 'path'; @@ -178,7 +177,7 @@ function detectPlatformAndArch() { function detectIsMusl() { try { // Simple check for Alpine Linux which uses MUSL - const output = execSync('cat /etc/os-release').toString(); + const output = fs.readFileSync('/etc/os-release', 'utf8'); return output.toLowerCase().includes('alpine'); } catch (error) { console.error(`Error detecting MUSL: ${error}`); diff --git a/resources/scripts/install-uv.js b/resources/scripts/install-uv.js index d3a789d1..cfb46c15 100644 --- a/resources/scripts/install-uv.js +++ b/resources/scripts/install-uv.js @@ -15,7 +15,6 @@ /* global console, process */ // @ts-check import AdmZip from 'adm-zip'; -import { execSync } from 'child_process'; import fs from 'fs'; import os from 'os'; import path from 'path'; @@ -175,7 +174,7 @@ function detectPlatformAndArch() { function detectIsMusl() { try { // Simple check for Alpine Linux which uses MUSL - const output = execSync('cat /etc/os-release').toString(); + const output = fs.readFileSync('/etc/os-release', 'utf8'); return output.toLowerCase().includes('alpine'); } catch (error) { console.error(`Error detecting MUSL: ${error}`); diff --git a/src/lib/oauth.ts b/src/lib/oauth.ts index a2854f8c..0daf7721 100644 --- a/src/lib/oauth.ts +++ b/src/lib/oauth.ts @@ -246,10 +246,29 @@ export class OAuth { async random(size: number) { const mask = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'; - const randomUints = crypto.getRandomValues(new Uint8Array(size)); - return Array.from(randomUints) - .map((i) => mask[i % mask.length]) - .join(''); + const maskLength = mask.length; + const result = []; + + // Use rejection sampling to avoid modulo bias + // Generate extra random values to account for rejections + let randomValues = crypto.getRandomValues(new Uint8Array(size * 2)); + let index = 0; + + while (result.length < size) { + if (index >= randomValues.length) { + // Need more random values + randomValues = crypto.getRandomValues(new Uint8Array(size * 2)); + index = 0; + } + + const value = randomValues[index++]; + // Only use values that don't cause modulo bias + if (value < 256 - (256 % maskLength)) { + result.push(mask[value % maskLength]); + } + } + + return result.join(''); } }