generated from jric11/baseProject
103 lines
5.4 KiB
Markdown
103 lines
5.4 KiB
Markdown
# Development security/capacity migration — October 20, 2026
|
|
|
|
Completed against the approved development target,
|
|
`192.168.1.190/huntingclubroster`, using its previously approved non-TLS connection.
|
|
|
|
## Backup and migration
|
|
|
|
- Backup: `.tools/backups/20261020-190128/huntingclubroster.sql`.
|
|
- Size: 53,033 bytes; 23 existing tables.
|
|
- SHA-256: `e7301cc5429f57bf93e9f1627b6c77afc9d8678ea0757a56a445e597417e0570`.
|
|
- Verified the completion marker and checksum, restored the backup to an
|
|
isolated loopback database, and matched all 23 table row counts.
|
|
- Applied `bin/migrate-security-capacity.php` and reran it to confirm repeatability.
|
|
The database now has 26 tables, including `user_mfa`, `mfa_recovery` and
|
|
`club_resource_usage`.
|
|
- Compared every original table's row fingerprints before and after migration;
|
|
existing values were preserved.
|
|
|
|
## Persistent development MFA key
|
|
|
|
- Generated a cryptographically random 32-byte key outside the project, in
|
|
`C:\Users\JamesRichie\AppData\Local\HuntingClubRoster\secrets\development-mfa.key`.
|
|
- Configured its path in ignored `xml/settings.local.xml`. Development servers
|
|
can read this persistent key without inheriting a temporary shell variable.
|
|
No key value is stored in the repository or this report.
|
|
- The key has protected Windows permissions allowing only the current Windows
|
|
account and SYSTEM. A protected recovery copy was saved under the same
|
|
external secrets folder's `recovery` subdirectory. This is a local recovery
|
|
copy, not an off-host backup.
|
|
- Added a development-only key-file loader. It rejects missing, oversized,
|
|
malformed and in-project key files. Production continues to require its
|
|
explicitly injected environment key.
|
|
- Eight key-configuration regression checks passed and are included in the test
|
|
runner.
|
|
|
|
## Development acceptance
|
|
|
|
All **68 development acceptance checks passed**, using owned temporary clubs,
|
|
accounts and records:
|
|
|
|
- Super System Administrator and club administrator authenticator enrollment;
|
|
administrator URLs and AJAX denied before MFA; valid authenticator acceptance;
|
|
encrypted secrets; recovery-code consumption and rejection of reused codes.
|
|
- Password login still requires the enrolled factor. Ordinary members keep their
|
|
normal login flow. Sensitive changes require recent password/MFA confirmation.
|
|
- Independent eight-hour absolute and 30-minute idle session expiration, tested
|
|
by aging only private test sessions rather than changing server time or waiting.
|
|
- Last-page access for members, seasons, dues, payments, corrections and
|
|
invitations; paged ticket conversations; invalid page handling; personal
|
|
counts and cross-club access denial.
|
|
- Shared ticket, reply, invitation email and export budgets across different
|
|
users, independent budgets for another club, and hourly-window reset.
|
|
- Oversized CSV, Excel, PDF and financial exports rejected without truncation.
|
|
|
|
The verification servers temporarily used lower limits to exercise boundaries;
|
|
normal development defaults were not changed. SMTP was redirected to an unused
|
|
loopback port, so no real email was sent. The MFA key was loaded from the actual
|
|
protected development key file, not a disposable test key.
|
|
|
|
All temporary accounts, factors, recovery codes, clubs, ledger rows, tickets,
|
|
audits, counters and private sessions were removed. Row fingerprints for all
|
|
26 tables then matched their pre-test state. Real account passwords, roles,
|
|
email verification and MFA enrollment were unchanged.
|
|
|
|
Detailed private evidence is retained beside the backup in
|
|
`security-migration-result.json`, `security-acceptance-result.json` and
|
|
`security-cleanup-result.json`.
|
|
|
|
The final development health check passed. Source validation passed for 61 PHP
|
|
files, 57 application JavaScript files and 39 XSL stylesheets, including browser
|
|
dependency integrity. The local backup-restoration copy was removed and its
|
|
isolated database server stopped.
|
|
|
|
The existing Super System Administrator will be prompted to enroll an
|
|
authenticator at the next sign-in; its owner must save the recovery codes.
|
|
No real account was enrolled on the owner's behalf.
|
|
|
|
## Actual development web-server follow-up
|
|
|
|
The browser application runs on `ositsdevels` under Rocky Linux Apache/PHP-FPM,
|
|
not on the Windows workstation used for the original acceptance server. Its
|
|
copied Windows key path caused login to fail before displaying MFA setup.
|
|
|
|
The owner ran the prepared administrator installer on that server. It installed
|
|
the unchanged key at `/etc/httpd/huntingclubroster/development-mfa.key`, restricted
|
|
its permissions to root and the Apache group, restored its SELinux context, and
|
|
configured the application's FastCGI requests with `HCR_MFA_KEY_FILE`. This
|
|
development-only override prevents workstation settings from replacing the
|
|
server's key path. Nine key-configuration regression checks passed.
|
|
|
|
The installer also enabled the app's existing private-directory rules, validated
|
|
Apache configuration and reloaded Apache. Its staged key was outside the web
|
|
root in the server home directory and was removed after installation.
|
|
|
|
Verified through the actual Apache/PHP-FPM server after installation:
|
|
|
|
- Configured MFA key is readable and can encrypt a secret.
|
|
- Authenticator library can generate and verify a code entirely in memory.
|
|
- Login page returns HTTP 200.
|
|
- `.tools/`, local settings, classes and vendor endpoints return HTTP 403.
|
|
- The staged key is removed. All temporary token-protected diagnostics were
|
|
immediately removed, and no real account was enrolled or changed.
|