Upgrading from 0.0.x to 1.0
Most apps upgrade by bumping the version. The module, the decorator and their options keep their names. Read the list below if you handle errors, run without a secret in some environments, or still use Node.js 18.
Requirements
- Node.js 20 or later.
- NestJS 10, 11 or 12.
@nestjs/common,@nestjs/coreandreflect-metadataare now peer dependencies, so the package uses your app's copies instead of installing its own. This fixes the 500 responses that NestJS 10 and 12 apps got instead of 400s, which came from a second copy of NestJS inside the package. - axios,
@nestjs/axiosand rxjs are no longer installed. The package calls Cloudflare with thefetchbuilt into Node.js. - Behind an outbound proxy, check your setup before upgrading. axios read
HTTP_PROXYandHTTPS_PROXYon its own, but Node.jsfetchignores them unless you opt in, and every guarded route would answer 500. See Outbound proxies.
Behavior changes
- The app refuses to start without a
secretKey, unlessskipIfistrue. Before, every request failed at runtime instead. onErrorreceives aTurnstileErrorinstead of anAxiosError. It carrieserrorCodesand acause, and never the secret key, which theAxiosErrorexposed inconfig.data.- Cloudflare's
internal-errornow gets one retry and then a 500. Before, it could reach visitors as a 400 invalid-token response. Wrong or missing secrets still answer 500. - siteverify calls time out after 5 seconds and are retried once. Set
timeoutto change the limit. - Tokens that are not strings or are longer than 2048 characters are rejected without a call to Cloudflare.
exceptionFactorygets a second argument,{ errorCodes }. Factories that take only the reason keep working.tokenResponseis optional. Without it, the guard reads thecf-turnstile-responsebody field or header. Its second argument is now theExecutionContext.
New features
expectedHostnameandexpectedAction, plus per-route actions with@TurnstileCaptcha({ action })@TurnstileCaptcha()on controller classes@TurnstileResult()to read the verification resultTurnstileServiceexported from the package rootremoteIp, as a module option and as an argument tovalidateTokenskipIfas a functionuseClass,useExistingandisGlobalfor module setup- GraphQL resolvers on Apollo and Mercurius
A note on header examples
Older versions of the README read the token with req.headers.turnstileToken. Node.js lowercases header names, so that value was always undefined. Use req.headers['turnstiletoken'], or drop tokenResponse and send the cf-turnstile-response header.