From fe5efd7651e6209b699278154477a523752e8b64 Mon Sep 17 00:00:00 2001 From: mhbdev Date: Tue, 6 Jan 2026 16:26:42 +0330 Subject: [PATCH] Added a built-in password generator to the shared input --- .../settings/profile/configure-2fa.tsx | 1 + .../dashboard/settings/profile/enable-2fa.tsx | 1 + .../settings/profile/profile-form.tsx | 1 + .../settings/servers/setup-monitoring.tsx | 1 + .../shared/toggle-visibility-input.tsx | 7 +- apps/dokploy/components/ui/input.tsx | 100 +++++++++++++++--- apps/dokploy/lib/password-utils.ts | 37 +++++++ 7 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 apps/dokploy/lib/password-utils.ts diff --git a/apps/dokploy/components/dashboard/settings/profile/configure-2fa.tsx b/apps/dokploy/components/dashboard/settings/profile/configure-2fa.tsx index 17220cd11..788ea55ac 100644 --- a/apps/dokploy/components/dashboard/settings/profile/configure-2fa.tsx +++ b/apps/dokploy/components/dashboard/settings/profile/configure-2fa.tsx @@ -263,6 +263,7 @@ export const Configure2FA = () => { type="password" placeholder="Enter your password" {...field} + enablePasswordGenerator={false} /> diff --git a/apps/dokploy/components/dashboard/settings/profile/enable-2fa.tsx b/apps/dokploy/components/dashboard/settings/profile/enable-2fa.tsx index 656b27401..573dae8f8 100644 --- a/apps/dokploy/components/dashboard/settings/profile/enable-2fa.tsx +++ b/apps/dokploy/components/dashboard/settings/profile/enable-2fa.tsx @@ -290,6 +290,7 @@ export const Enable2FA = () => { type="password" placeholder="Enter your password" {...field} + enablePasswordGenerator={false} /> diff --git a/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx b/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx index ad66aa0fa..c2ee0c230 100644 --- a/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx +++ b/apps/dokploy/components/dashboard/settings/profile/profile-form.tsx @@ -236,6 +236,7 @@ export const ProfileForm = () => { placeholder={t("settings.profile.password")} {...field} value={field.value || ""} + enablePasswordGenerator={false} /> diff --git a/apps/dokploy/components/dashboard/settings/servers/setup-monitoring.tsx b/apps/dokploy/components/dashboard/settings/servers/setup-monitoring.tsx index 09260b1a2..d2b9b999b 100644 --- a/apps/dokploy/components/dashboard/settings/servers/setup-monitoring.tsx +++ b/apps/dokploy/components/dashboard/settings/servers/setup-monitoring.tsx @@ -568,6 +568,7 @@ export const SetupMonitoring = ({ serverId }: Props) => { type={showToken ? "text" : "password"} placeholder="Enter your metrics token" {...field} + enablePasswordGenerator={false} /> )} - + + )} {errorMessage && ( diff --git a/apps/dokploy/lib/password-utils.ts b/apps/dokploy/lib/password-utils.ts new file mode 100644 index 000000000..3da2aca73 --- /dev/null +++ b/apps/dokploy/lib/password-utils.ts @@ -0,0 +1,37 @@ +const DEFAULT_PASSWORD_LENGTH = 20; +const DEFAULT_PASSWORD_CHARSET = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +export const generateRandomPassword = ( + length: number = DEFAULT_PASSWORD_LENGTH, + charset: string = DEFAULT_PASSWORD_CHARSET, +) => { + const safeLength = Number.isFinite(length) && length > 0 + ? Math.floor(length) + : DEFAULT_PASSWORD_LENGTH; + + if (safeLength <= 0 || charset.length === 0) { + return ""; + } + + const cryptoApi = + typeof globalThis !== "undefined" ? globalThis.crypto : undefined; + + if (!cryptoApi?.getRandomValues) { + let fallback = ""; + for (let i = 0; i < safeLength; i += 1) { + fallback += charset[Math.floor(Math.random() * charset.length)]; + } + return fallback; + } + + const values = new Uint32Array(safeLength); + cryptoApi.getRandomValues(values); + + let result = ""; + for (const value of values) { + result += charset[value % charset.length]; + } + + return result; +};