<%
'=======================================================================================================================
' Cloudflare Turnstile (CAPTCHA) server-side verification
'=======================================================================================================================
' Verifies a Turnstile response token against Cloudflare's siteverify endpoint. Unlike
' JurisdictionValidator's fail-open behavior (missing reference data shouldn't block orders),
' this fails CLOSED: a missing token or a failed/unreachable verification call is treated as
' "not verified" rather than being let through, since the whole point is to block automated
' submissions.
'=======================================================================================================================

Const TURNSTILE_VERIFY_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify"

' Verifies a Turnstile response token (the value of the widget's "cf-turnstile-response"
' field / the token returned to the data-callback). remoteIp is optional - pass "" to omit it.
Function VerifyTurnstileToken(responseToken, remoteIp)
    VerifyTurnstileToken = False

    responseToken = Trim(responseToken)
    If Len(responseToken) = 0 Then Exit Function

    Dim secretKey : secretKey = GetAppSetting("TurnstileSecretKey")
    If Len(secretKey) = 0 Then Exit Function

    Dim body
    body = "secret=" & Server.URLEncode(secretKey) & "&response=" & Server.URLEncode(responseToken)
    If Len(remoteIp) > 0 Then body = body & "&remoteip=" & Server.URLEncode(remoteIp)

    On Error Resume Next

    Dim http : Set http = Server.CreateObject("Msxml2.ServerXMLHTTP")
    http.setTimeouts 5000, 5000, 5000, 5000
    http.Open "POST", TURNSTILE_VERIFY_URL, False
    http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    http.Send body

    If Err.Number = 0 And http.Status = 200 Then
        Dim re
        Set re = New RegExp
        re.Pattern = """success""\s*:\s*true"
        re.IgnoreCase = True
        VerifyTurnstileToken = re.Test(http.responseText)
    End If

    Err.Clear
    On Error GoTo 0
End Function
%>
