code-challenge.php
Code-Challenge library layer: trigger decision, transient-backed token codec, and random code generator. REST handlers and route registration live at the bottom of this file (added in Task 10).
Table of Contents
Functions
- creationell_captcha_should_issue_code_challenge() : bool
- Decides whether the current /challenge request should attach a code-challenge instruction. Returns true iff:
- creationell_captcha_code_charset() : string
- Returns the active charset string for the configured option.
- creationell_captcha_generate_code() : string
- Generates a fresh random code from the configured charset.
- creationell_captcha_code_token_issue() : string
- Issues a token backed by a server-side WP transient that stores the expected code for at most $expiry_seconds. Returns the opaque ID that `/code-image` and `/code-verify` use to look the code up again.
- creationell_captcha_code_token_verify() : string|null
- Looks up the code for a token and returns it, or null on: - malformed token (not 32 hex chars) - missing transient (expired or unknown)
- creationell_captcha_rest_code_image() : WP_REST_Response
- Handles GET /code-image?t=<token>. Looks up the code from the token (server-side transient), renders the PNG, returns 410 on token failure.
- creationell_captcha_rest_code_verify() : WP_REST_Response
- Handles POST /code-verify. Two body shapes:
- creationell_captcha_register_code_challenge_routes() : void
- Registers the two code-challenge REST routes. The /challenge handler itself stays in includes/rest.php; Task 11 extends it with the codeChallenge field and the data.ccode embed.
Functions
creationell_captcha_should_issue_code_challenge()
Decides whether the current /challenge request should attach a code-challenge instruction. Returns true iff:
creationell_captcha_should_issue_code_challenge() : bool
- the master toggle is on, AND
- PHP-GD is available, AND
- at least one of the three trigger conditions matches (under-attack, ratelimit threshold, watch-list).
Return values
boolcreationell_captcha_code_charset()
Returns the active charset string for the configured option.
creationell_captcha_code_charset(string $charset_key) : string
Parameters
- $charset_key : string
-
One of: digits / alphanumeric / alphanumeric-no-confusing.
Return values
stringcreationell_captcha_generate_code()
Generates a fresh random code from the configured charset.
creationell_captcha_generate_code() : string
Return values
stringcreationell_captcha_code_token_issue()
Issues a token backed by a server-side WP transient that stores the expected code for at most $expiry_seconds. Returns the opaque ID that `/code-image` and `/code-verify` use to look the code up again.
creationell_captcha_code_token_issue(string $code, int $expiry_seconds) : string
The code is intentionally NOT encoded into the token itself — a base64 round-trip would leak the code to anyone who can read the network response (defeats the OCR-resistant captcha goal). Server state via WP transients is the accepted trade-off.
Parameters
- $code : string
-
The expected code (already from generator).
- $expiry_seconds : int
-
Seconds until the token expires.
Return values
stringcreationell_captcha_code_token_verify()
Looks up the code for a token and returns it, or null on: - malformed token (not 32 hex chars) - missing transient (expired or unknown)
creationell_captcha_code_token_verify(string $token[, bool $consume = false ]) : string|null
Parameters
- $token : string
-
The 32-hex-char ID from
code_token_issue. - $consume : bool = false
-
Delete the transient after successful lookup (single-use semantics). The /code-image handler passes false; /code-verify passes true ONLY after a successful code match so retries on wrong input still work.
Return values
string|nullcreationell_captcha_rest_code_image()
Handles GET /code-image?t=<token>. Looks up the code from the token (server-side transient), renders the PNG, returns 410 on token failure.
creationell_captcha_rest_code_image(WP_REST_Request $request) : WP_REST_Response
Idempotent — the transient is NOT consumed here so the browser may reload the image.
Parameters
- $request : WP_REST_Request
-
The REST request. Required query parameter
t(opaque server-issued token).
Return values
WP_REST_Response —200 with image/png body on success; 410 when the
token is unknown/expired or PHP-GD is unavailable.
creationell_captcha_rest_code_verify()
Handles POST /code-verify. Two body shapes:
creationell_captcha_rest_code_verify(WP_REST_Request $request) : WP_REST_Response
-
Code-Challenge mode: { "code": "
", "payload": " " } The widget rendered a code-image because the /challenge response embedded data.ccode. Token lookup → case-insensitive match → single-use consume → fresh signed payload. -
Plain server-verify mode: { "payload": "
" } (no code) ALTCHA's widget posts here unconditionally whenever verifyUrl is set (see widget.js logic: verifyUrl ? _e() : verified()). Structural verify on the incoming payload + single-use replay guard on its signature + fresh signed payload back. The replay guard matters: without it a single solved PoW could be amplified into N fresh payloads, undercutting Engine::verify()'s per-form single-use protection.
Parameters
- $request : WP_REST_Request
-
The REST request with JSON body
{payload: string, code?: string}.
Return values
WP_REST_Response —200 on success ({payload, verified: true}); 400 on malformed body; 401 on wrong code; 410 on missing/expired/replayed payload or token; 500 on internal error.
creationell_captcha_register_code_challenge_routes()
Registers the two code-challenge REST routes. The /challenge handler itself stays in includes/rest.php; Task 11 extends it with the codeChallenge field and the data.ccode embed.
creationell_captcha_register_code_challenge_routes() : void