232 lines
6.6 KiB
JSON
232 lines
6.6 KiB
JSON
{
|
|
"task_id": "LOGIN-AUTH-QUALITY-CHECK-001",
|
|
"scope_ref": "agent-system/runs/LOGIN-AUTH-QUALITY-CHECK-001/plan.json",
|
|
"flows": [
|
|
{
|
|
"flow": "local login",
|
|
"files": [
|
|
"pages/auth/login().php",
|
|
"pages/auth/login(login).phtml",
|
|
"web/js/app-login-init.js",
|
|
"web/js/components/app-password-toggle.js",
|
|
"web/js/components/app-password-hints.js",
|
|
"web/css/pages/app-login.css"
|
|
],
|
|
"guard_ids": [
|
|
"GR-CORE-003",
|
|
"GR-CORE-005",
|
|
"GR-CORE-006",
|
|
"GR-SEC-001",
|
|
"GR-UI-009",
|
|
"GR-UI-010",
|
|
"GR-UI-011",
|
|
"GR-UI-012",
|
|
"GR-UI-013",
|
|
"GR-UI-015"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-LOGIN-001",
|
|
"severity": "medium",
|
|
"status": "resolved",
|
|
"summary": "Password toggle lacked duplicate-init guard and keyboard focus resilience evidence.",
|
|
"evidence": "web/js/components/app-password-toggle.js now has passwordToggleBound guard; tests/Architecture/AuthLoginFrontendCleanupContractTest.php validates guard presence."
|
|
},
|
|
{
|
|
"id": "F-LOGIN-002",
|
|
"severity": "low",
|
|
"status": "resolved",
|
|
"summary": "Unused legacy login CSS selector remained in app-login.css.",
|
|
"evidence": "Selector .back_to_login removed; tests/Architecture/AuthLoginFrontendCleanupContractTest.php asserts absence."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"flow": "register",
|
|
"files": [
|
|
"pages/auth/register().php",
|
|
"pages/auth/register(login).phtml"
|
|
],
|
|
"guard_ids": [
|
|
"GR-CORE-003",
|
|
"GR-CORE-012",
|
|
"GR-SEC-001",
|
|
"GR-UI-009",
|
|
"GR-UI-010"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-REGISTER-001",
|
|
"severity": "high",
|
|
"status": "resolved",
|
|
"summary": "Register POST accepted payload without upfront CSRF verification.",
|
|
"evidence": "pages/auth/register().php now enforces Session::checkCsrfToken() before payload handling; tests/Architecture/AuthRegisterSecurityContractTest.php green."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"flow": "forgot/verify/reset",
|
|
"files": [
|
|
"pages/auth/forgot().php",
|
|
"pages/auth/verify().php",
|
|
"pages/auth/reset().php",
|
|
"lib/Service/Auth/PasswordResetService.php",
|
|
"pages/auth/forgot(login).phtml",
|
|
"pages/auth/verify(login).phtml",
|
|
"pages/auth/reset(login).phtml"
|
|
],
|
|
"guard_ids": [
|
|
"GR-SEC-001",
|
|
"GR-SEC-002",
|
|
"GR-TEST-001",
|
|
"GR-TEST-002",
|
|
"GR-UI-009"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-RESET-001",
|
|
"severity": "medium",
|
|
"status": "resolved",
|
|
"summary": "Edge-case unit regression coverage for reset lifecycle was incomplete.",
|
|
"evidence": "tests/Service/Auth/PasswordResetServiceTest.php adds requestReset/verifyCode/resetPassword edge and failure paths."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"flow": "verify-email",
|
|
"files": [
|
|
"pages/auth/verify-email().php",
|
|
"pages/auth/verify-email(login).phtml",
|
|
"lib/Service/Auth/EmailVerificationService.php"
|
|
],
|
|
"guard_ids": [
|
|
"GR-SEC-001",
|
|
"GR-SEC-002",
|
|
"GR-TEST-001",
|
|
"GR-TEST-002",
|
|
"GR-UI-009"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-VERIFY-001",
|
|
"severity": "medium",
|
|
"status": "resolved",
|
|
"summary": "Automated coverage for verify-email resend/attempt-limit branches was incomplete.",
|
|
"evidence": "tests/Service/Auth/EmailVerificationServiceTest.php covers send/verify/resend including already_verified and attempt limit."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"flow": "microsoft start",
|
|
"files": [
|
|
"pages/auth/microsoft/start().php",
|
|
"lib/Service/Auth/TenantSsoService.php",
|
|
"lib/Service/Auth/MicrosoftOidcService.php"
|
|
],
|
|
"guard_ids": [
|
|
"GR-CORE-005",
|
|
"GR-CORE-006",
|
|
"GR-SEC-002",
|
|
"GR-TEST-001",
|
|
"GR-TEST-002"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-MSSO-START-001",
|
|
"severity": "none",
|
|
"status": "none",
|
|
"summary": "No open finding.",
|
|
"evidence": "tests/Service/Auth/MicrosoftOidcServiceTest.php already covered startAuthorization negative and PKCE happy paths."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"flow": "microsoft callback",
|
|
"files": [
|
|
"pages/auth/microsoft/callback().php",
|
|
"lib/Service/Auth/MicrosoftOidcService.php",
|
|
"lib/Service/Auth/SsoUserLinkService.php",
|
|
"lib/Service/Auth/TenantSsoService.php"
|
|
],
|
|
"guard_ids": [
|
|
"GR-CORE-005",
|
|
"GR-CORE-006",
|
|
"GR-SEC-002",
|
|
"GR-TEST-001",
|
|
"GR-TEST-002"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-MSSO-CALLBACK-001",
|
|
"severity": "medium",
|
|
"status": "resolved",
|
|
"summary": "Missing explicit automated regression case for domain-policy rejection in callback.",
|
|
"evidence": "tests/Service/Auth/MicrosoftOidcServiceTest.php now includes testHandleCallbackReturnsEmailDomainNotAllowedWhenTenantDomainPolicyRejectsUser."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"flow": "api auth login",
|
|
"files": [
|
|
"pages/api/v1/auth/login().php"
|
|
],
|
|
"guard_ids": [
|
|
"GR-CORE-004",
|
|
"GR-CORE-005",
|
|
"GR-SEC-002",
|
|
"GR-SEC-003",
|
|
"GR-CORE-006"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-API-LOGIN-001",
|
|
"severity": "none",
|
|
"status": "none",
|
|
"summary": "No open finding.",
|
|
"evidence": "QG-004 structural checks remain 0 violations; no direct readJsonBody/superglobal drift introduced."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"flow": "api me password",
|
|
"files": [
|
|
"pages/api/v1/me/password().php"
|
|
],
|
|
"guard_ids": [
|
|
"GR-CORE-005",
|
|
"GR-SEC-002",
|
|
"GR-SEC-003",
|
|
"GR-TEST-001"
|
|
],
|
|
"findings": [
|
|
{
|
|
"id": "F-API-ME-PASSWORD-001",
|
|
"severity": "none",
|
|
"status": "none",
|
|
"summary": "No open finding.",
|
|
"evidence": "No API behavior change in this run; quality gates and architecture contracts stay green."
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"priority_summary": {
|
|
"critical": {
|
|
"open": 0,
|
|
"resolved": 0
|
|
},
|
|
"high": {
|
|
"open": 0,
|
|
"resolved": 1
|
|
},
|
|
"medium": {
|
|
"open": 0,
|
|
"resolved": 4
|
|
},
|
|
"low": {
|
|
"open": 0,
|
|
"resolved": 1
|
|
}
|
|
},
|
|
"notes": "Alle kritischen/hohen Findings sind geschlossen; keine offenen critical/high/medium Befunde im In-Scope-Auth-Bereich."
|
|
}
|