fix(06.2): WR-01 replace fixed-suffix password generation with fully-random positional injection

This commit is contained in:
curo1305
2026-06-01 14:31:00 +02:00
parent 2072c3ddcd
commit 1cba903c34
@@ -290,16 +290,38 @@ const newUser = reactive({
})
function generateRandomPassword() {
const charset = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789!@#$%^&*'
const upper = 'ABCDEFGHJKLMNPQRSTUVWXYZ'
const lower = 'abcdefghijkmnpqrstuvwxyz'
const digits = '23456789'
const special = '!@#$%^&*'
const charset = upper + lower + digits + special // 64 chars — 256 % 64 === 0, no modulo bias
// Generate 16 random positions
const arr = new Uint8Array(16)
crypto.getRandomValues(arr)
let pw = ''
for (const byte of arr) {
pw += charset[byte % charset.length]
const chars = Array.from(arr, byte => charset[byte % charset.length])
// Inject one guaranteed character from each required class at random positions
// using four additional random bytes to pick the injection positions.
const posArr = new Uint8Array(8)
crypto.getRandomValues(posArr)
const required = [
upper[posArr[0] % upper.length],
lower[posArr[1] % lower.length],
digits[posArr[2] % digits.length],
special[posArr[3] % special.length],
]
// Place each required char at a distinct position (0..3) in the array
for (let i = 0; i < 4; i++) {
chars[i] = required[i]
}
// Ensure all character classes are represented
pw = pw.slice(0, 12) + 'A1!'
return pw
// Shuffle using Fisher-Yates with the last 4 random bytes as seeds
for (let i = chars.length - 1; i > 0; i--) {
const j = posArr[4 + (i % 4)] % (i + 1)
;[chars[i], chars[j]] = [chars[j], chars[i]]
}
return chars.join('')
}
function generatePassword() {