fix: relax password requirements and improve password UI
Test and Lint / backend-test (push) Successful in 1m9s
continuous-integration/drone/push Build is passing
Test and Lint / frontend-test (push) Successful in 2m13s
Version and Release / version-bump (push) Successful in 35s
Version and Release / trigger-drone (push) Successful in 3s

- Reduce minimum password length from 12 to 8 characters
- Make special characters optional for gallery passwords
- Lower strength requirement from score 3 to 1 for galleries
- Add eye icon toggle for password visibility on each field
- Remove redundant 'Show passwords' checkbox
- Add translation for password security requirements error
- Update both English and German translations

This allows users to use simpler passwords like 'Sommer2025\!' for events
while maintaining security through other measures like expiration dates.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-14 14:05:23 +02:00
parent c546657285
commit e2d0a83d51
4 changed files with 58 additions and 35 deletions
+1
View File
@@ -872,6 +872,7 @@
"passwordRequired": "Passwort ist erforderlich",
"passwordMinLength": "Passwort muss mindestens 6 Zeichen lang sein",
"passwordsDoNotMatch": "Passwörter stimmen nicht überein",
"passwordSecurityRequirements": "Passwort erfüllt nicht die Sicherheitsanforderungen",
"expirationRange": "Ablauf muss zwischen 1 und 365 Tagen liegen"
},
"maintenance": {
+1
View File
@@ -792,6 +792,7 @@
"passwordRequired": "Password is required",
"passwordMinLength": "Password must be at least 6 characters",
"passwordsDoNotMatch": "Passwords do not match",
"passwordSecurityRequirements": "Password does not meet security requirements",
"expirationRange": "Expiration must be between 1 and 365 days"
},
"legal": {
+47 -23
View File
@@ -7,7 +7,9 @@ import {
Clock,
ArrowLeft,
Info,
Upload
Upload,
Eye,
EyeOff
} from 'lucide-react';
import { format, addDays } from 'date-fns';
import { toast } from 'react-toastify';
@@ -168,7 +170,13 @@ export const CreateEventPage: React.FC = () => {
toast.error(t('errors.sessionExpired'));
navigate('/admin/login');
} else {
toast.error(error.response?.data?.error || t('errors.failedToCreateEvent'));
const errorMessage = error.response?.data?.error;
// Check if it's the password security requirements error
if (errorMessage === 'Password does not meet security requirements') {
toast.error(t('validation.passwordSecurityRequirements'));
} else {
toast.error(errorMessage || t('errors.failedToCreateEvent'));
}
}
},
});
@@ -405,7 +413,20 @@ export const CreateEventPage: React.FC = () => {
error={errors.password}
placeholder={t('events.enterPassword')}
leftIcon={<Lock className="w-5 h-5 text-neutral-400" />}
className="pr-10"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute inset-y-0 right-0 pr-3 flex items-center"
style={{ top: errors.password ? '0' : '0' }}
>
{showPassword ? (
<EyeOff className="w-5 h-5 text-neutral-400 hover:text-neutral-600" />
) : (
<Eye className="w-5 h-5 text-neutral-400 hover:text-neutral-600" />
)}
</button>
</div>
</div>
@@ -414,29 +435,32 @@ export const CreateEventPage: React.FC = () => {
<label htmlFor="confirm_password" className="block text-sm font-medium text-neutral-700 mb-1">
{t('events.confirmPassword')}
</label>
<Input
id="confirm_password"
type={showPassword ? 'text' : 'password'}
value={formData.confirm_password}
onChange={handleInputChange('confirm_password')}
error={errors.confirm_password}
placeholder={t('events.confirmPasswordPlaceholder')}
leftIcon={<Lock className="w-5 h-5 text-neutral-400" />}
/>
<div className="relative">
<Input
id="confirm_password"
type={showPassword ? 'text' : 'password'}
value={formData.confirm_password}
onChange={handleInputChange('confirm_password')}
error={errors.confirm_password}
placeholder={t('events.confirmPasswordPlaceholder')}
leftIcon={<Lock className="w-5 h-5 text-neutral-400" />}
className="pr-10"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute inset-y-0 right-0 pr-3 flex items-center"
style={{ top: errors.confirm_password ? '0' : '0' }}
>
{showPassword ? (
<EyeOff className="w-5 h-5 text-neutral-400 hover:text-neutral-600" />
) : (
<Eye className="w-5 h-5 text-neutral-400 hover:text-neutral-600" />
)}
</button>
</div>
</div>
</div>
<div className="mt-4">
<label className="flex items-center">
<input
type="checkbox"
checked={showPassword}
onChange={(e) => setShowPassword(e.target.checked)}
className="w-4 h-4 text-primary-600 border-neutral-300 rounded focus:ring-primary-500"
/>
<span className="ml-2 text-sm text-neutral-700">{t('events.showPasswords')}</span>
</label>
</div>
</Card>
{/* Gallery Settings */}