53 lines
2.7 KiB
PowerShell
53 lines
2.7 KiB
PowerShell
$ErrorActionPreference = 'Stop'
|
|
|
|
$root = Split-Path -Parent $PSScriptRoot
|
|
$apiPath = Join-Path $root 'utils/api.js'
|
|
$a01Path = Join-Path $root 'pages/auth/a01-entry.vue'
|
|
$runtimePath = Join-Path $PSScriptRoot 'auth-api-runtime-smoke.js'
|
|
$issues = New-Object System.Collections.Generic.List[string]
|
|
|
|
foreach ($path in @($apiPath, $a01Path, $runtimePath)) {
|
|
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
|
|
$issues.Add("missing authentication owner: $path")
|
|
}
|
|
}
|
|
|
|
if ($issues.Count -eq 0) {
|
|
$api = Get-Content -Raw -Encoding UTF8 -LiteralPath $apiPath
|
|
$a01 = Get-Content -Raw -Encoding UTF8 -LiteralPath $a01Path
|
|
$passwordOwner = [regex]::Match($api, '(?s)async loginWithPassword\(\{ phone, passwordHash, validToken \}.*?(?=\s+async loginWithSms)')
|
|
if (-not $passwordOwner.Success) {
|
|
$issues.Add('missing bounded password login owner')
|
|
} else {
|
|
foreach ($required in @("url: '/genealogy/app/auth/login'", "tenantId: runtimeConfig.tenantId", "grantType: 'password'", 'password: assertPasswordHash(passwordHash)', 'const normalizedValidToken = normalizeOptionalValidToken(validToken)', '...(normalizedValidToken ? { validToken: normalizedValidToken } : {})')) {
|
|
if (-not $passwordOwner.Value.Contains($required)) { $issues.Add("password login owner missing: $required") }
|
|
}
|
|
if ($passwordOwner.Value.Contains('authPayload(')) {
|
|
$issues.Add('password login must not put clientId in the body')
|
|
}
|
|
}
|
|
foreach ($required in @('const preparePasswordLogin = async () =>', 'appApi.loginWithPassword', 'TAC')) {
|
|
if (-not $a01.Contains($required)) { $issues.Add("A01 missing password TAC precondition: $required") }
|
|
}
|
|
$smsOwner = [regex]::Match($api, '(?s)async sendSmsCode\(\{ operationCode, phone, validToken \}.*?(?=\s+async loginWithPassword)')
|
|
if (-not $smsOwner.Success -or -not $smsOwner.Value.Contains('const normalizedValidToken = normalizeOptionalValidToken(validToken)') -or -not $smsOwner.Value.Contains('...(normalizedValidToken ? { validToken: normalizedValidToken } : {})')) {
|
|
$issues.Add('SMS owner must remain the sole validToken consumer and omit it only when the server policy closes TAC')
|
|
}
|
|
}
|
|
|
|
if ($issues.Count -eq 0) {
|
|
$runtimeOutput = @(& node $runtimePath 2>&1)
|
|
if ($LASTEXITCODE -ne 0 -or 'AUTH-API-RUNTIME-SMOKE PASS' -notin $runtimeOutput) {
|
|
$issues.Add("password and SMS wire runtime smoke failed: $($runtimeOutput -join ' | ')")
|
|
}
|
|
}
|
|
|
|
if ($issues.Count -gt 0) {
|
|
Write-Output 'AUTH-TAC-OPENAPI-CONTRACT BLOCKED'
|
|
foreach ($issue in $issues) { Write-Output "- $issue" }
|
|
Write-Output '- Password login and SMS operations send a validToken only after the server marks that operation as verification-required.'
|
|
exit 1
|
|
}
|
|
|
|
Write-Output 'AUTH-TAC-OPENAPI-CONTRACT PASS'
|