From 987eb210ebcf1e26a0f76d654fc8ac5e2a222323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Tue, 8 Sep 2026 13:31:32 -0300 Subject: [PATCH] feat: standardize passwords at eight characters --- PORTAINER.md | 2 +- components/LoginModal.tsx | 4 ++-- pages/AccessTokenPage.tsx | 2 +- server/src/config.ts | 2 +- server/src/routes/auth.ts | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/PORTAINER.md b/PORTAINER.md index c36186e..c046924 100644 --- a/PORTAINER.md +++ b/PORTAINER.md @@ -69,7 +69,7 @@ The built-in Actions job token can be disabled or lack registry scope on self-ho - `JWT_SECRET`: a unique random string of at least 32 characters. - `FRONTEND_ORIGIN`: the exact public application URL, for example `https://hub.example.com`. - `SUPERADMIN_EMAIL`: email address for the initial platform administrator. -- `SUPERADMIN_PASSWORD`: password for that administrator (at least 12 characters). +- `SUPERADMIN_PASSWORD`: password for that administrator (at least 8 characters). - `AUTH_RATE_LIMIT_MAX` and `AUTH_RATE_LIMIT_WINDOW_SECONDS` are optional login and public-auth throttling controls (defaults: 10 attempts per 900 seconds per source IP). - `JWT_SESSION_TTL`, `INVITATION_TTL_HOURS`, `PASSWORD_RESET_TTL_HOURS`, `BUNNY_EMBED_TOKEN_TTL_SECONDS`, and `AUDIT_LOG_PAGE_SIZE` tune operating policy without changing code. diff --git a/components/LoginModal.tsx b/components/LoginModal.tsx index dc4c1b6..7fefb31 100644 --- a/components/LoginModal.tsx +++ b/components/LoginModal.tsx @@ -40,7 +40,7 @@ export const LoginModal: React.FC = ({ isOpen, onClose }) => { if (!signedInUser) { setError(isRegistering - ? 'Não foi possível criar sua conta. Use um e-mail válido e uma senha com pelo menos 12 caracteres.' + ? 'Não foi possível criar sua conta. Use um e-mail válido e uma senha com pelo menos 8 caracteres.' : 'Credenciais inválidas. Verifique seu e-mail e senha.'); return; } @@ -87,7 +87,7 @@ export const LoginModal: React.FC = ({ isOpen, onClose }) => {
{isRegistering && setName(event.target.value)} className="w-full bg-white/10 text-white placeholder:text-white/30 px-4 py-3 rounded-[8px] focus:outline-none focus:ring-2 focus:ring-orange-500/50 focus:bg-white/15 transition-all text-body tracking-body" required autoFocus />} setEmail(event.target.value)} className="w-full bg-white/10 text-white placeholder:text-white/30 px-4 py-3 rounded-[8px] focus:outline-none focus:ring-2 focus:ring-orange-500/50 focus:bg-white/15 transition-all text-body tracking-body" required autoFocus={!isRegistering} /> - setPassword(event.target.value)} minLength={12} className="w-full bg-white/10 text-white placeholder:text-white/30 px-4 py-3 rounded-[8px] focus:outline-none focus:ring-2 focus:ring-orange-500/50 focus:bg-white/15 transition-all text-body tracking-body" required /> + setPassword(event.target.value)} minLength={8} className="w-full bg-white/10 text-white placeholder:text-white/30 px-4 py-3 rounded-[8px] focus:outline-none focus:ring-2 focus:ring-orange-500/50 focus:bg-white/15 transition-all text-body tracking-body" required />
{error &&

{error}

} diff --git a/pages/AccessTokenPage.tsx b/pages/AccessTokenPage.tsx index 0a7cc26..6f7b63b 100644 --- a/pages/AccessTokenPage.tsx +++ b/pages/AccessTokenPage.tsx @@ -20,5 +20,5 @@ export const AccessTokenPage: React.FC<{ mode: 'invite' | 'reset' }> = ({ mode } } catch { setError('Este link é inválido, expirou ou não pôde ser usado.'); } finally { setSaving(false); } }; - return

{mode === 'invite' ? 'Criar seu acesso' : 'Redefinir senha'}

{mode === 'invite' && setName(event.target.value)} placeholder="Seu nome" className="w-full rounded-xl bg-zinc-900 p-3" />} setPassword(event.target.value)} placeholder="Nova senha (mínimo 12 caracteres)" className="w-full rounded-xl bg-zinc-900 p-3" />{error &&

{error}

}
; + return

{mode === 'invite' ? 'Criar seu acesso' : 'Redefinir senha'}

{mode === 'invite' && setName(event.target.value)} placeholder="Seu nome" className="w-full rounded-xl bg-zinc-900 p-3" />} setPassword(event.target.value)} placeholder="Nova senha (mínimo 8 caracteres)" className="w-full rounded-xl bg-zinc-900 p-3" />{error &&

{error}

}
; }; diff --git a/server/src/config.ts b/server/src/config.ts index 1bfe1cd..94f26bb 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -11,7 +11,7 @@ const environmentSchema = z.object({ APP_ENV: z.enum(['development', 'test', 'production']).default('development'), JWT_SECRET: z.string().min(32).default('development-only-secret-change-before-production'), SUPERADMIN_EMAIL: optionalEnvironmentValue(z.string().email()), - SUPERADMIN_PASSWORD: optionalEnvironmentValue(z.string().min(12)), + SUPERADMIN_PASSWORD: optionalEnvironmentValue(z.string().min(8)), SUPERADMIN_NAME: z.string().min(1).max(120).default('Compor HUB Superadmin'), AUTH_RATE_LIMIT_MAX: z.coerce.number().int().min(1).max(1000).default(10), AUTH_RATE_LIMIT_WINDOW_SECONDS: z.coerce.number().int().min(60).max(86_400).default(900), diff --git a/server/src/routes/auth.ts b/server/src/routes/auth.ts index 59c2586..26e3e6b 100644 --- a/server/src/routes/auth.ts +++ b/server/src/routes/auth.ts @@ -9,13 +9,13 @@ import { sendWelcomeEmail } from '../services/email.js'; const credentialsSchema = z.object({ email: z.string().email().transform((email) => email.toLowerCase()), - password: z.string().min(12).max(200), + password: z.string().min(8).max(200), }); const registerSchema = credentialsSchema.extend({ name: z.string().trim().min(2).max(120), }); -const tokenPasswordSchema = z.object({ token: z.string().min(20), password: z.string().min(12).max(200), name: z.string().trim().min(2).max(120).optional() }); +const tokenPasswordSchema = z.object({ token: z.string().min(20), password: z.string().min(8).max(200), name: z.string().trim().min(2).max(120).optional() }); type UserRow = { id: string;