Commit Graph
4 Commits
Author SHA1 Message Date
lyra d2eb914637 fix: must-fix items for v1.0 release
Security:
- Add SecurityHeadersListener (X-Content-Type-Options, X-Frame-Options,
  CSP, Referrer-Policy, HSTS)
- Replace document.write() with document.documentElement.innerHTML
  in login JS to avoid CSP violations
- Add CSS escaping (|e('css')) to env color values in _style.html.twig
- Document CSRF protection model: nonce serves as CSRF token for POST
  form path (single-use, server-generated, 120s TTL)
- Reduce TOTP verification window from 10 periods (±5 min) to 1 (±30s)
- Remove hardcoded APP_SECRET from bin/franken.sh (now uses env or
  generates random)
- Remove backup code values from debug log output
- Add .env to .gitignore

Bug fixes:
- Fix ->json access on possibly-null  in LoginListener
  (uses null-safe operator ?->)
- Fix validReturn() not checking false from parse_url (could cause
  TypeError on malformed URLs)
- Add isHit() race condition check in AcceptListener and AllowListener
- Add try/finally in Kernel::terminate() so parent::terminate() always
  runs even if persist() throws
- Add input validation to GenerateBackupCodesCommand (reject count < 1)
- Use Response::HTTP_INTERNAL_SERVER_ERROR constant in GetTotpTrait
  instead of literal 500

Docker/CI:
- Explicitly install curl in Docker final image (needed for healthcheck)
- Update workflow tag pattern to v*.*.* (standardize on v-prefix)
- Extract version without v-prefix for Docker image tag
- Remove stale develop branch from CI triggers
- Fix publish.yaml git remote add to use set-url on re-runs

Code quality:
- Add declare(strict_types=1) to all interface files
- Add #[AsCommand] attribute to GenerateBackupCodesCommand
- Fix BackupCodeInterface default count to match implementation (10)
- Lowercase host before TLD lookup in DomainManager
- Expand TLD list with many missing multi-part TLDs (.com.au, .co.jp,
  .com.br, .co.kr, .com.tw, .co.za, etc.) to prevent open redirect
  vulnerabilities
- Disable unused Symfony sessions in framework.yaml

Tests:
- Update DomainManagerTest for corrected TLD parsing (.com.au, .co.jp,
  .com.br now correctly recognized as multi-part)
- Update GetTotpTraitTest for corrected error message
- Update GenerateBackupCodesCommandTest: zero count now throws exception
2026-08-11 16:33:00 -04:00
lyra cb378e20bc chore: add php-cs-fixer with PSR-12 config and CI check
Sync GitHub / sync (push) Failing after 5s
Tests / test (pull_request) Successful in 49s
- Add friendsofphp/php-cs-fixer to require-dev
- Create .php-cs-fixer.dist.php configured for @PSR12 ruleset
- Add php-cs-fixer dry-run step to CI pipeline
- Auto-fix existing PSR-12 violations
- Document code style tooling in readme.md
2026-08-11 08:30:05 -04:00
lyra 12ba6cde7b Add unit tests for untested edge cases and code paths
Sync GitHub / sync (push) Successful in 9s
PayloadTest:
- decode() with invalid JSON, JSON array, null, boolean, number
- load() with all fields present but empty strings
- create() with invalid scope string (falls back to cookie)
- create() with missing json property (defaults to true)

DomainManagerTest:
- TLD table coverage: com.au, co.jp, com.br, co.nz, com.mx, co.in, br.com
- Single-label host matching behavior
- Empty string host
- validReturn with URL containing port, without path, different domain with port

MakeNonceTraitTest:
- Retry-then-succeed path (first attempt collides, second succeeds)
- Zero retries throws immediately on collision

StringTraitTest:
- Only invalid characters collapses to single underscore
- Exactly 128 characters boundary
- Multibyte characters (é, ö) replaced with underscore
- Emoji replaced with underscore

GetTotpTraitTest:
- HOTP URI triggers HttpException(500) via instanceof check

LoginManagerTest:
- ULID collision throws HttpException(500)
- Central auth cookie sets domain on matching host (uses auth cookie name)
- Central auth cookie uses null domain on non-matching host
- Empty return parameter falls back to request path

BackupCodeManagerTest:
- Empty string code returns false
- Code with value false (consumed) verified via cache state
- Generated codes are unique (50 codes)
- Code length equals TOTP digits + 2

MonitorCacheKeysTest:
- saveDeferred on __key_list and __chg_list throws OutOfBoundsException
- getKeys returns empty when key list is lost
- deleteItem/deleteItems return true assertions

PersistCacheTest:
- Mixed updates and removals in same persist cycle
- Multiple boot-modify-persist cycles with interleaved modifications
2026-08-06 06:10:31 -04:00
lyra 890cc225ef Add PHPUnit test suite and supporting infrastructure
- Add phpunit/phpunit ^13.2, symfony/browser-kit and symfony/css-selector
  to require-dev, plus the autoload-dev mapping for App\Tests- Add phpunit.dist.xml (strict deprecation/notice/warning failures,
  APP_ENV=test forced) and .env.test / bin/phpunit / tests/bootstrap.php
  from the PHPUnit recipe
- Add tests/Support/TotpTestHelper providing a deterministic TOTP
  fixture, frozen clock and ConfigBag/cache-pool helpers
- Add 121 unit tests covering Clock, ConfigBag, Data/Payload, Enum/Scope,
  MonitorCacheKeys, PersistCache, Utilities, all five Traits and the
  three Service managers (BackupCode, Domain, Login)
- Fix LoginManagerTest nonce lookups to use makeCacheKey() so the cache
  key matches the one the manager actually reads/writes
- Gitignore bin/.phpunit.result.cache
2026-08-05 16:52:44 -04:00