Merge origin/main: Review-Branch mit v2.4.0-Features zusammenführen

Konfliktauflösung kombiniert beide Seiten:
- Auth: Secure-Cookie-Flag + DB-Session-Handler (main)
- UniFiController: createVouchers (n-Parameter, 1 API-Call) + QoS-Optionen (main)
- index.php: IP-Rate-Limit/PRG/Sticky-Forms + CAPTCHA/SMS/QoS/Tageslimit (main)
- users.php: 2FA-Reset (main) auf POST+PRG umgestellt wie übrige Aktionen
- forgot_password: Session-Throttle (main) + IP-Throttle kombiniert
- Eigene Migrationen wegen Nummernkollision auf 0005/0006 umbenannt

https://claude.ai/code/session_01KKVpVPJjrTKGoRgpJcySD4
This commit is contained in:
Claude 2026-06-09 20:03:32 +00:00
commit 1a2f86ed3d
No known key found for this signature in database
65 changed files with 3136 additions and 32 deletions

View file

@ -0,0 +1,27 @@
-- Updater-Migration: Schema fuer erweiterte Funktionen
-- * 2FA (TOTP) fuer lokale Accounts
-- * Bandbreiten-/Datenlimits in Voucher-Profilen
-- * REST-API-Schluessel
-- Idempotent gehalten; "duplicate column"/"already exists" werden vom
-- MigrationRunner ignoriert.
ALTER TABLE `users` ADD COLUMN `totp_secret` VARCHAR(64) NULL;
ALTER TABLE `users` ADD COLUMN `totp_enabled` TINYINT(1) NOT NULL DEFAULT 0;
ALTER TABLE `voucher_templates` ADD COLUMN `qos_rate_max_down` INT NULL;
ALTER TABLE `voucher_templates` ADD COLUMN `qos_rate_max_up` INT NULL;
ALTER TABLE `voucher_templates` ADD COLUMN `qos_usage_quota` INT NULL;
CREATE TABLE IF NOT EXISTS `api_keys` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`key_prefix` VARCHAR(16) NOT NULL,
`key_hash` VARCHAR(255) NOT NULL,
`created_by` INT,
`last_used_at` TIMESTAMP NULL,
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON DELETE SET NULL,
INDEX `idx_prefix` (`key_prefix`),
INDEX `idx_active` (`is_active`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View file

@ -0,0 +1,16 @@
-- Updater-Migration: Reife-Funktionen
-- * 2FA Recovery-/Backup-Codes
-- * API-Scopes & Rate-Limit pro Schlüssel
-- Idempotent; "duplicate column"/"already exists" werden ignoriert.
ALTER TABLE `users` ADD COLUMN `totp_backup_codes` TEXT NULL;
ALTER TABLE `api_keys` ADD COLUMN `scope` VARCHAR(16) NOT NULL DEFAULT 'write';
ALTER TABLE `api_keys` ADD COLUMN `rate_limit` INT NOT NULL DEFAULT 0;
CREATE TABLE IF NOT EXISTS `api_key_hits` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`api_key_id` INT NOT NULL,
`hit_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_key_time` (`api_key_id`, `hit_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View file

@ -0,0 +1,5 @@
-- Updater-Migration: DB-gestützte Sessions zulassen.
-- user_id muss NULL erlauben (anonyme Sessions vor dem Login).
-- Idempotent genug: bei bereits NULL-barer Spalte ist das ein No-Op.
ALTER TABLE `sessions` MODIFY `user_id` INT NULL;