From 7dea598adb6d4cbafd22fcf24778005f80c3af5e Mon Sep 17 00:00:00 2001 From: Nycz-lab Date: Wed, 12 Aug 2026 16:00:03 +0200 Subject: [PATCH 1/3] feat: add password generator for user creation pw field --- .../src/features/users/ManageUsersDialog.tsx | 167 +++++++++++++++++- .../src/lib/passwordGenerator.test.ts | 70 ++++++++ src/renderer/src/lib/passwordGenerator.ts | 66 +++++++ 3 files changed, 294 insertions(+), 9 deletions(-) create mode 100644 src/renderer/src/lib/passwordGenerator.test.ts create mode 100644 src/renderer/src/lib/passwordGenerator.ts diff --git a/src/renderer/src/features/users/ManageUsersDialog.tsx b/src/renderer/src/features/users/ManageUsersDialog.tsx index 3a73be0..c05542d 100644 --- a/src/renderer/src/features/users/ManageUsersDialog.tsx +++ b/src/renderer/src/features/users/ManageUsersDialog.tsx @@ -1,7 +1,18 @@ import { type FormEvent, useEffect, useMemo, useState } from 'react' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { toast } from 'sonner' -import { ArrowLeft, KeyRound, Loader2, Plus, ServerCrash, Trash2, UserCog } from 'lucide-react' +import { + ArrowLeft, + Copy, + KeyRound, + Loader2, + Plus, + RefreshCw, + ServerCrash, + Trash2, + UserCog, + Wand2 +} from 'lucide-react' import { Dialog, DialogContent, @@ -24,6 +35,15 @@ import { AlertDialogTitle } from '@/components/ui/alert-dialog' import { api, ApiError } from '@/lib/api' +import { + CHARSETS, + DEFAULT_OPTIONS, + generatePassword, + MAX_LENGTH, + MIN_LENGTH, + type CharsetKey, + type PasswordOptions +} from '@/lib/passwordGenerator' import { queryKeys } from '@/lib/queryClient' import { cn } from '@/lib/utils' import type { DatabaseUser, DatabaseUserRole } from '@shared/types' @@ -316,6 +336,7 @@ function UserForm({ const [username, setUsername] = useState(initial.username) const [password, setPassword] = useState('') + const [generatorOpen, setGeneratorOpen] = useState(false) const [selectedRoles, setSelectedRoles] = useState>(new Set(initial.selectedRoles)) const [customRoles, setCustomRoles] = useState(initial.customRoles) const [serverError, setServerError] = useState(null) @@ -434,17 +455,37 @@ function UserForm({ {mode === 'edit' ? 'New password (optional)' : 'Password'} - setPassword(e.target.value)} - autoComplete="new-password" - placeholder={mode === 'edit' ? 'Leave blank to keep current' : ''} - /> +
+ setPassword(e.target.value)} + autoComplete="new-password" + placeholder={mode === 'edit' ? 'Leave blank to keep current' : ''} + /> + +
+ {generatorOpen && } +