From 1cba903c349a83df5355d20d88b99f2947781839 Mon Sep 17 00:00:00 2001 From: curo1305 Date: Mon, 1 Jun 2026 14:31:00 +0200 Subject: [PATCH] fix(06.2): WR-01 replace fixed-suffix password generation with fully-random positional injection --- .../src/components/admin/AdminUsersTab.vue | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/admin/AdminUsersTab.vue b/frontend/src/components/admin/AdminUsersTab.vue index 259ad31..2a70cbe 100644 --- a/frontend/src/components/admin/AdminUsersTab.vue +++ b/frontend/src/components/admin/AdminUsersTab.vue @@ -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() {