Lizenzkey Format

Dieser Commit ist enthalten in:
2025-06-09 04:59:26 +02:00
Ursprung fa9d79089a
Commit 75e1ecc692
6 geänderte Dateien mit 127 neuen und 15 gelöschten Zeilen

Datei anzeigen

@@ -2158,4 +2158,49 @@ Ein Pool-System für Domains, IPv4-Adressen und Telefonnummern, wobei bei jeder
- `v2_adminpanel/templates/setup_2fa.html` - Neues Step-by-Step Design
- `v2_adminpanel/templates/backup_codes.html` - Modernisiertes Layout
**Status:** ✅ Abgeschlossen - Login funktioniert, UI im konsistenten Design
**Status:** ✅ Abgeschlossen - Login funktioniert, UI im konsistenten Design
### 2025-06-09: Lizenzschlüssel-Format geändert
**Änderung:**
- Altes Format: `AF-YYYYMMFT-XXXX-YYYY-ZZZZ` (z.B. AF-202506F-V55Y-9DWE-GL5G)
- Neues Format: `AF-F-YYYYMM-XXXX-YYYY-ZZZZ` (z.B. AF-F-202506-V55Y-9DWE-GL5G)
**Vorteile:**
- Klarere Struktur mit separatem Typ-Indikator
- Einfacher zu lesen und zu verstehen
- Typ (F/T) sofort im zweiten Block erkennbar
**Geänderte Dateien:**
- `v2_adminpanel/app.py`:
- `generate_license_key()` - Generiert Keys im neuen Format
- `validate_license_key()` - Validiert Keys mit neuem Regex-Pattern
- `v2_adminpanel/templates/index.html`:
- Placeholder und Pattern für Input-Feld angepasst
- JavaScript charAt() Position für Typ-Prüfung korrigiert
- `v2_adminpanel/templates/batch_form.html`:
- Vorschau-Format für Batch-Generierung angepasst
**Hinweis:** Alte Keys im bisherigen Format bleiben ungültig. Bei Bedarf könnte eine Migration oder Dual-Support implementiert werden.
**Status:** ✅ Implementiert
### 2025-06-09: Datenbank-Migration der Lizenzschlüssel
**Durchgeführt:**
- Alle bestehenden Lizenzschlüssel in der Datenbank auf das neue Format migriert
- 18 Lizenzschlüssel erfolgreich konvertiert (16 Full, 2 Test)
**Migration:**
- Von: `AF-YYYYMMFT-XXXX-YYYY-ZZZZ`
- Nach: `AF-F-YYYYMM-XXXX-YYYY-ZZZZ`
**Beispiele:**
- Alt: `AF-202506F-V55Y-9DWE-GL5G`
- Neu: `AF-F-202506-V55Y-9DWE-GL5G`
**Geänderte Dateien:**
- `v2_adminpanel/migrate_license_keys.sql` - Migrations-Script (temporär)
- `v2_adminpanel/fix_license_keys.sql` - Korrektur-Script (temporär)
**Status:** ✅ Alle Lizenzschlüssel erfolgreich migriert

Datei anzeigen

@@ -641,12 +641,12 @@ def verify_recaptcha(response):
def generate_license_key(license_type='full'):
"""
Generiert einen Lizenzschlüssel im Format: AF-YYYYMMFT-XXXX-YYYY-ZZZZ
Generiert einen Lizenzschlüssel im Format: AF-F-YYYYMM-XXXX-YYYY-ZZZZ
AF = Account Factory (Produktkennung)
F/T = F für Fullversion, T für Testversion
YYYY = Jahr
MM = Monat
FT = F für Fullversion, T für Testversion
XXXX-YYYY-ZZZZ = Zufällige alphanumerische Zeichen
"""
# Erlaubte Zeichen (ohne verwirrende wie 0/O, 1/I/l)
@@ -664,21 +664,21 @@ def generate_license_key(license_type='full'):
parts.append(part)
# Key zusammensetzen
key = f"AF-{date_part}{type_char}-{parts[0]}-{parts[1]}-{parts[2]}"
key = f"AF-{type_char}-{date_part}-{parts[0]}-{parts[1]}-{parts[2]}"
return key
def validate_license_key(key):
"""
Validiert das License Key Format
Erwartet: AF-YYYYMMFT-XXXX-YYYY-ZZZZ
Erwartet: AF-F-YYYYMM-XXXX-YYYY-ZZZZ oder AF-T-YYYYMM-XXXX-YYYY-ZZZZ
"""
if not key:
return False
# Pattern für das spezifische Format
# AF- (fest) + 6 Ziffern (YYYYMM) + F oder T + - + 4 Zeichen + - + 4 Zeichen + - + 4 Zeichen
pattern = r'^AF-\d{6}[FT]-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$'
# Pattern für das neue Format
# AF- (fest) + F oder T + - + 6 Ziffern (YYYYMM) + - + 4 Zeichen + - + 4 Zeichen + - + 4 Zeichen
pattern = r'^AF-[FT]-\d{6}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$'
# Großbuchstaben für Vergleich
return bool(re.match(pattern, key.upper()))

Datei anzeigen

@@ -0,0 +1,13 @@
-- Fix für die fehlerhafte Migration - entfernt doppelte Bindestriche
UPDATE licenses
SET license_key = REPLACE(license_key, 'AF--', 'AF-')
WHERE license_key LIKE 'AF--%';
UPDATE licenses
SET license_key = REPLACE(license_key, '6--', '6-')
WHERE license_key LIKE '%6--%';
-- Zeige die korrigierten Keys
SELECT id, license_key, license_type
FROM licenses
ORDER BY id;

Datei anzeigen

@@ -0,0 +1,54 @@
-- Migration der Lizenzschlüssel vom alten Format zum neuen Format
-- Alt: AF-YYYYMMFT-XXXX-YYYY-ZZZZ
-- Neu: AF-F-YYYYMM-XXXX-YYYY-ZZZZ
-- Backup der aktuellen Schlüssel erstellen (für Sicherheit)
CREATE TEMP TABLE license_backup AS
SELECT id, license_key FROM licenses;
-- Update für Fullversion Keys (F)
UPDATE licenses
SET license_key =
CONCAT(
SUBSTRING(license_key, 1, 3), -- 'AF-'
'-F-',
SUBSTRING(license_key, 4, 6), -- 'YYYYMM'
'-',
SUBSTRING(license_key, 11) -- Rest des Keys
)
WHERE license_key LIKE 'AF-%F-%'
AND license_type = 'full'
AND license_key NOT LIKE 'AF-F-%'; -- Nicht bereits migriert
-- Update für Testversion Keys (T)
UPDATE licenses
SET license_key =
CONCAT(
SUBSTRING(license_key, 1, 3), -- 'AF-'
'-T-',
SUBSTRING(license_key, 4, 6), -- 'YYYYMM'
'-',
SUBSTRING(license_key, 11) -- Rest des Keys
)
WHERE license_key LIKE 'AF-%T-%'
AND license_type = 'test'
AND license_key NOT LIKE 'AF-T-%'; -- Nicht bereits migriert
-- Zeige die Änderungen
SELECT
b.license_key as old_key,
l.license_key as new_key,
l.license_type
FROM licenses l
JOIN license_backup b ON l.id = b.id
WHERE b.license_key != l.license_key
ORDER BY l.id;
-- Anzahl der migrierten Keys
SELECT
COUNT(*) as total_migrated,
SUM(CASE WHEN license_type = 'full' THEN 1 ELSE 0 END) as full_licenses,
SUM(CASE WHEN license_type = 'test' THEN 1 ELSE 0 END) as test_licenses
FROM licenses l
JOIN license_backup b ON l.id = b.id
WHERE b.license_key != l.license_key;

Datei anzeigen

@@ -173,7 +173,7 @@
<div class="modal-body">
<p>Es werden <strong id="previewQuantity">10</strong> Lizenzen im folgenden Format generiert:</p>
<div class="bg-light p-3 rounded font-monospace" id="previewFormat">
AF-YYYYMMFT-XXXX-YYYY-ZZZZ
AF-F-YYYYMM-XXXX-YYYY-ZZZZ
</div>
<p class="mt-3 mb-0">Die Keys werden automatisch eindeutig generiert und in der Datenbank gespeichert.</p>
</div>
@@ -324,7 +324,7 @@ function previewKeys() {
const dateStr = date.getFullYear() + ('0' + (date.getMonth() + 1)).slice(-2);
document.getElementById('previewQuantity').textContent = quantity;
document.getElementById('previewFormat').textContent = `AF-${dateStr}${typeChar}-XXXX-YYYY-ZZZZ`;
document.getElementById('previewFormat').textContent = `AF-${typeChar}-${dateStr}-XXXX-YYYY-ZZZZ`;
const modal = new bootstrap.Modal(document.getElementById('previewModal'));
modal.show();

Datei anzeigen

@@ -37,14 +37,14 @@
<label for="licenseKey" class="form-label">Lizenzschlüssel</label>
<div class="input-group">
<input type="text" class="form-control" id="licenseKey" name="license_key"
placeholder="AF-YYYYMMFT-XXXX-YYYY-ZZZZ" required
pattern="AF-\d{6}[FT]-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}"
title="Format: AF-YYYYMMFT-XXXX-YYYY-ZZZZ">
placeholder="AF-F-YYYYMM-XXXX-YYYY-ZZZZ" required
pattern="AF-[FT]-\d{6}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}"
title="Format: AF-F-YYYYMM-XXXX-YYYY-ZZZZ">
<button type="button" class="btn btn-outline-primary" onclick="generateLicenseKey()">
🔑 Generieren
</button>
</div>
<div class="form-text">Format: AF-YYYYMMFT-XXXX-YYYY-ZZZZ (F=Full, T=Test)</div>
<div class="form-text">Format: AF-F-YYYYMM-XXXX-YYYY-ZZZZ (F=Full, T=Test)</div>
</div>
<div class="col-md-4">
<label for="licenseType" class="form-label">Lizenztyp</label>
@@ -206,7 +206,7 @@ document.getElementById('licenseType').addEventListener('change', function() {
if (keyField.value && keyField.value.startsWith('AF-')) {
// Prüfe ob der Key zum neuen Typ passt
const currentType = this.value;
const keyType = keyField.value.charAt(9); // Position des F/T im Key
const keyType = keyField.value.charAt(3); // Position des F/T im Key (AF-F-...)
if ((currentType === 'full' && keyType === 'T') ||
(currentType === 'test' && keyType === 'F')) {