feat: Generate username automatically from first and last name during registration
This commit is contained in:
+6
-1
@@ -6850,10 +6850,15 @@ def register():
|
|||||||
return redirect(url_for('login'))
|
return redirect(url_for('login'))
|
||||||
if 'username' in session:
|
if 'username' in session:
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
username = request.form['username']
|
|
||||||
password = request.form['password']
|
password = request.form['password']
|
||||||
name = (request.form.get('name') or '').strip()
|
name = (request.form.get('name') or '').strip()
|
||||||
last_name = (request.form.get('last-name') or '').strip()
|
last_name = (request.form.get('last-name') or '').strip()
|
||||||
|
|
||||||
|
# Generate username from name and last_name if not provided or empty
|
||||||
|
username = (request.form.get('username') or '').strip()
|
||||||
|
if not username:
|
||||||
|
username = us.build_username_from_name(name, last_name)
|
||||||
|
|
||||||
permission_preset = (request.form.get('permission_preset') or 'standard_user').strip()
|
permission_preset = (request.form.get('permission_preset') or 'standard_user').strip()
|
||||||
use_custom_permissions = request.form.get('use_custom_permissions') == 'on'
|
use_custom_permissions = request.form.get('use_custom_permissions') == 'on'
|
||||||
is_student = bool(request.form.get('is_student')) if cfg.STUDENT_CARDS_MODULE_ENABLED else False
|
is_student = bool(request.form.get('is_student')) if cfg.STUDENT_CARDS_MODULE_ENABLED else False
|
||||||
|
|||||||
@@ -34,22 +34,22 @@
|
|||||||
<div class="form-card">
|
<div class="form-card">
|
||||||
<form method="POST" action="{{ url_for('register') }}">
|
<form method="POST" action="{{ url_for('register') }}">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username">Benutzername</label>
|
|
||||||
<div class="input-container">
|
|
||||||
<span class="input-icon">👤</span>
|
|
||||||
<input type="text" id="username" name="username" placeholder="Geben Sie einen Benutzernamen ein" required>
|
|
||||||
</div>
|
|
||||||
<label for="name">Vorname</label>
|
<label for="name">Vorname</label>
|
||||||
<div class="input-container">
|
<div class="input-container">
|
||||||
<span class="input-icon">👤</span>
|
<span class="input-icon">👤</span>
|
||||||
<input type="text" id="name" name="name" placeholder="Geben Sie den Vornamen ein" required>
|
<input type="text" id="name" name="name" placeholder="Geben Sie den Vornamen ein" required onchange="generateUsername()" oninput="generateUsername()">
|
||||||
</div>
|
</div>
|
||||||
<label for="last-name">Nachname</label>
|
<label for="last-name">Nachname</label>
|
||||||
<div class="input-container">
|
<div class="input-container">
|
||||||
<span class="input-icon">👤</span>
|
<span class="input-icon">👤</span>
|
||||||
<input type="text" id="last-name" name="last-name" placeholder="Geben Sie den Nachnamen ein" required>
|
<input type="text" id="last-name" name="last-name" placeholder="Geben Sie den Nachnamen ein" required onchange="generateUsername()" oninput="generateUsername()">
|
||||||
</div>
|
</div>
|
||||||
<p class="anonymize-hint">Klarnamen werden nur zur Erzeugung eines Kuerzels (z.B. SimFri) verwendet und nicht als Klarname gespeichert.</p>
|
<label for="username">Benutzername <span style="color: #9ca3af;">(wird automatisch generiert)</span></label>
|
||||||
|
<div class="input-container">
|
||||||
|
<span class="input-icon">👤</span>
|
||||||
|
<input type="text" id="username" name="username" placeholder="Automatisch aus Name und Nachname" readonly style="background-color: #f3f4f6; cursor: not-allowed;">
|
||||||
|
</div>
|
||||||
|
<p class="anonymize-hint">Klarnamen werden nur zur Erzeugung des Benutzernamens und eines Kuerzels (z.B. SimFri) verwendet und nicht als Klarname gespeichert.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -446,6 +446,46 @@ input::placeholder {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// Function to generate username from first and last name (helper function)
|
||||||
|
function cleanNameForUsername(text) {
|
||||||
|
if (!text) return '';
|
||||||
|
// Remove special characters, convert umlauts, lowercase
|
||||||
|
let cleaned = text
|
||||||
|
.replace(/[^a-zA-Zäöüß\s-]/g, '')
|
||||||
|
.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
// Convert German umlauts to ASCII
|
||||||
|
cleaned = cleaned
|
||||||
|
.replace(/ä/g, 'ae')
|
||||||
|
.replace(/ö/g, 'oe')
|
||||||
|
.replace(/ü/g, 'ue')
|
||||||
|
.replace(/ß/g, 'ss');
|
||||||
|
|
||||||
|
return cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate username from name and last_name fields
|
||||||
|
function generateUsername() {
|
||||||
|
const firstName = cleanNameForUsername(document.getElementById('name').value || '');
|
||||||
|
const lastName = cleanNameForUsername(document.getElementById('last-name').value || '');
|
||||||
|
let username = '';
|
||||||
|
|
||||||
|
if (firstName && lastName) {
|
||||||
|
username = firstName + lastName;
|
||||||
|
} else if (firstName) {
|
||||||
|
username = firstName;
|
||||||
|
} else if (lastName) {
|
||||||
|
username = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the username field
|
||||||
|
const usernameField = document.getElementById('username');
|
||||||
|
if (usernameField) {
|
||||||
|
usernameField.value = username || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const permissionPresets = {{ permission_presets | tojson }};
|
const permissionPresets = {{ permission_presets | tojson }};
|
||||||
const presetSelect = document.getElementById('permission-preset');
|
const presetSelect = document.getElementById('permission-preset');
|
||||||
|
|||||||
+27
@@ -57,6 +57,33 @@ def build_name_synonym(first_name, last_name=''):
|
|||||||
return combined[:6].title()
|
return combined[:6].title()
|
||||||
|
|
||||||
|
|
||||||
|
def build_username_from_name(first_name, last_name=''):
|
||||||
|
"""
|
||||||
|
Build a deterministic username from first and last name.
|
||||||
|
Format: firstnameLastname (CamelCase, e.g., 'SimonFrings' or 'SFrings')
|
||||||
|
Ensures uniqueness by allowing server to check existence.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
first_name (str): First name
|
||||||
|
last_name (str): Last name (optional)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Generated username
|
||||||
|
"""
|
||||||
|
first = _clean_name_fragment(first_name)
|
||||||
|
last = _clean_name_fragment(last_name)
|
||||||
|
|
||||||
|
if first and last:
|
||||||
|
# Full: FirstLast (e.g., 'SimonFrings')
|
||||||
|
return (first + last).lower()
|
||||||
|
elif first:
|
||||||
|
return first.lower()
|
||||||
|
elif last:
|
||||||
|
return last.lower()
|
||||||
|
else:
|
||||||
|
return 'user'
|
||||||
|
|
||||||
|
|
||||||
ACTION_PERMISSION_KEYS = (
|
ACTION_PERMISSION_KEYS = (
|
||||||
'can_borrow',
|
'can_borrow',
|
||||||
'can_insert',
|
'can_insert',
|
||||||
|
|||||||
Reference in New Issue
Block a user