Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-turnstile

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-turnstile - npm Package Compare versions

Comparing version 1.1.0 to 1.1.1

26

dist/index.d.ts
import React from "react";
import { SupportedLanguages } from "turnstile-types";
export default function Turnstile({ id, className, style, sitekey, action, cData, theme, language, tabIndex, responseField, responseFieldName, size, retry, retryInterval, refreshExpired, appearance, execution, userRef, onVerify, onLoad, onError, onExpire, onTimeout, }: TurnstileProps): JSX.Element;
interface TurnstileProps extends TurnstileCallbacks {
import { TurnstileObject, TurnstileOptions, SupportedLanguages } from "turnstile-types";
export default function Turnstile({ id, className, style, sitekey, action, cData, theme, language, tabIndex, responseField, responseFieldName, size, fixedSize, retry, retryInterval, refreshExpired, appearance, execution, userRef, onVerify, onLoad, onError, onExpire, onTimeout, }: TurnstileProps): JSX.Element;
export interface TurnstileProps extends TurnstileCallbacks {
sitekey: string;

@@ -14,2 +14,3 @@ action?: string;

size?: "normal" | "invisible" | "compact";
fixedSize?: boolean;
retry?: "auto" | "never";

@@ -25,9 +26,14 @@ retryInterval?: number;

}
interface TurnstileCallbacks {
onVerify: (token: string) => void;
onLoad?: (widgetId: string) => void;
onError?: (error?: Error | any) => void;
onExpire?: () => void;
onTimeout?: () => void;
export interface TurnstileCallbacks {
onVerify: (token: string, boundTurnstile: BoundTurnstileObject) => void;
onLoad?: (widgetId: string, boundTurnstile: BoundTurnstileObject) => void;
onError?: (error?: Error | any, boundTurnstile?: BoundTurnstileObject) => void;
onExpire?: (token: string, boundTurnstile: BoundTurnstileObject) => void;
onTimeout?: (boundTurnstile: BoundTurnstileObject) => void;
}
export {};
export interface BoundTurnstileObject {
execute: (options?: TurnstileOptions) => void;
reset: () => void;
getResponse: () => void;
}
export declare function useTurnstile(): TurnstileObject;

@@ -26,24 +26,25 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.useTurnstile = void 0;
const react_1 = __importStar(require("react"));
const global = (typeof globalThis !== "undefined" ? globalThis : window);
let turnstileState = typeof global.turnstile !== "undefined" ? "ready" : "unloaded";
const globalNamespace = (typeof globalThis !== "undefined" ? globalThis : window);
let turnstileState = typeof globalNamespace.turnstile !== "undefined" ? "ready" : "unloaded";
let ensureTurnstile;
// Functions responsible for loading the turnstile api, while also making sure
// to only load it once
let turnstileLoad;
const turnstileLoadPromise = new Promise((resolve, reject) => {
turnstileLoad = { resolve, reject };
if (turnstileState === "ready")
resolve(undefined);
});
{
const TURNSTILE_LOAD_FUNCTION = "cf__reactTurnstileOnLoad";
const TURNSTILE_SRC = "https://challenges.cloudflare.com/turnstile/v0/api.js";
let turnstileLoad;
const turnstileLoadPromise = new Promise((resolve, reject) => {
turnstileLoad = { resolve, reject };
if (turnstileState === "ready")
resolve(undefined);
});
ensureTurnstile = () => {
if (turnstileState === "unloaded") {
turnstileState = "loading";
global[TURNSTILE_LOAD_FUNCTION] = () => {
globalNamespace[TURNSTILE_LOAD_FUNCTION] = () => {
turnstileLoad.resolve();
turnstileState = "ready";
delete global[TURNSTILE_LOAD_FUNCTION];
delete globalNamespace[TURNSTILE_LOAD_FUNCTION];
};

@@ -56,3 +57,3 @@ const url = `${TURNSTILE_SRC}?onload=${TURNSTILE_LOAD_FUNCTION}&render=explicit`;

turnstileLoad.reject("Failed to load Turnstile.");
delete global[TURNSTILE_LOAD_FUNCTION];
delete globalNamespace[TURNSTILE_LOAD_FUNCTION];
});

@@ -64,3 +65,3 @@ document.head.appendChild(script);

}
function Turnstile({ id, className, style, sitekey, action, cData, theme, language, tabIndex, responseField, responseFieldName, size, retry, retryInterval, refreshExpired, appearance, execution, userRef, onVerify, onLoad, onError, onExpire, onTimeout, }) {
function Turnstile({ id, className, style, sitekey, action, cData, theme, language, tabIndex, responseField, responseFieldName, size, fixedSize, retry, retryInterval, refreshExpired, appearance, execution, userRef, onVerify, onLoad, onError, onExpire, onTimeout, }) {
const ownRef = (0, react_1.useRef)(null);

@@ -73,3 +74,3 @@ const inplaceState = (0, react_1.useState)({ onVerify })[0];

let cancelled = false;
let widgetId = "";
let widgetId = "", timeoutId = 0;
(async () => {

@@ -89,2 +90,3 @@ var _a, _b;

return;
let boundTurnstileObject;
const turnstileOptions = {

@@ -100,3 +102,3 @@ sitekey,

size,
retry,
retry: "never",
"retry-interval": retryInterval,

@@ -106,9 +108,29 @@ "refresh-expired": refreshExpired,

execution,
callback: (token) => inplaceState.onVerify(token),
"error-callback": () => { var _a; return (_a = inplaceState.onError) === null || _a === void 0 ? void 0 : _a.call(inplaceState); },
"expired-callback": () => { var _a; return (_a = inplaceState.onExpire) === null || _a === void 0 ? void 0 : _a.call(inplaceState); },
"timeout-callback": () => { var _a; return (_a = inplaceState.onTimeout) === null || _a === void 0 ? void 0 : _a.call(inplaceState); },
callback: (token) => inplaceState.onVerify(token, boundTurnstileObject),
"error-callback": (error) => {
var _a;
// we handle retry ourselves because turnstile does not properly
// reset its timeout when calling turnstile.remove, logging the
// following in the console:
// > [Cloudflare Turnstile] Nothing to reset found for provided container.
// refs:
// - https://github.com/Le0Developer/react-turnstile/issues/14
// - https://discord.com/channels/595317990191398933/1025131875397812224/1122137855368646717
// TODO: remove when fixed
if (!retry || retry === "auto") {
timeoutId = setTimeout(() => {
boundTurnstileObject.reset();
timeoutId = 0;
// no need to do bounds checks, turnstile already does them for us
// even though we have retry=never
}, 2000 + (retryInterval !== null && retryInterval !== void 0 ? retryInterval : 8000));
}
(_a = inplaceState.onError) === null || _a === void 0 ? void 0 : _a.call(inplaceState, error, boundTurnstileObject);
},
"expired-callback": (token) => { var _a; return (_a = inplaceState.onExpire) === null || _a === void 0 ? void 0 : _a.call(inplaceState, token, boundTurnstileObject); },
"timeout-callback": () => { var _a; return (_a = inplaceState.onTimeout) === null || _a === void 0 ? void 0 : _a.call(inplaceState, boundTurnstileObject); },
};
widgetId = window.turnstile.render(ref.current, turnstileOptions);
(_b = inplaceState.onLoad) === null || _b === void 0 ? void 0 : _b.call(inplaceState, widgetId);
boundTurnstileObject = createBoundTurnstileObject(widgetId);
(_b = inplaceState.onLoad) === null || _b === void 0 ? void 0 : _b.call(inplaceState, widgetId, boundTurnstileObject);
})();

@@ -119,2 +141,4 @@ return () => {

window.turnstile.remove(widgetId);
if (timeoutId)
clearTimeout(timeoutId);
};

@@ -144,5 +168,30 @@ }, [

}, [onVerify, onLoad, onError, onExpire, onTimeout]);
return react_1.default.createElement("div", { ref: ref, id: id, className: className, style: style });
return (react_1.default.createElement("div", { ref: ref, id: id, className: className, style: fixedSize
? {
...(style !== null && style !== void 0 ? style : {}),
width: size === "compact" ? "130px" : "300px",
height: size === "compact" ? "120px" : "65px",
}
: style }));
}
exports.default = Turnstile;
function createBoundTurnstileObject(widgetId) {
return {
execute: (options) => window.turnstile.execute(widgetId, options),
reset: () => window.turnstile.reset(widgetId),
getResponse: () => window.turnstile.getResponse(widgetId),
};
}
function useTurnstile() {
// we are using state here to trigger a component re-render once turnstile
// loads, so the component using this hook gets the object once its loaded
const [_, setState] = (0, react_1.useState)(turnstileState);
(0, react_1.useEffect)(() => {
if (turnstileState === "ready")
return;
turnstileLoadPromise.then(() => setState(turnstileState));
}, []);
return globalNamespace.turnstile;
}
exports.useTurnstile = useTurnstile;
//# sourceMappingURL=index.js.map

@@ -10,2 +10,17 @@ # Changelog

## [1.1.1] - 2023-06-25
### Added
- `useTurnstile` hook
- `fixedSize` option to reduce layout shift
- Missing argument for `onExpire`
- `BoundTurnstileObject` argument to callbacks
### Fixed
- `global` -> `globalNamespace` (name conflict) (#10)
- Implement `retry` logic ourselves (#14)
- Missing `onError` error argument passthrough
## [1.1.0] - 2023-03-09

@@ -91,3 +106,4 @@

[unreleased]: https://github.com/Le0Developer/react-turnstile/compare/v1.1.0...HEAD
[unreleased]: https://github.com/Le0Developer/react-turnstile/compare/v1.1.1...HEAD
[1.1.1]: https://github.com/le0developer/react-turnstile/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/le0developer/react-turnstile/compare/v1.0.6...v1.1.0

@@ -94,0 +110,0 @@ [1.0.6]: https://github.com/le0developer/react-turnstile/compare/v1.0.5...v1.0.6

{
"name": "react-turnstile",
"version": "1.1.0",
"version": "1.1.1",
"description": "React library for Cloudflare's Turnstile CAPTCHA alternative",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -14,3 +14,3 @@ # react-turnstile

```jsx
import Turnstile from "react-turnstile";
import Turnstile, { useTurnstile } from "react-turnstile";

@@ -20,6 +20,14 @@ // ...

function TurnstileWidget() {
const turnstile = useTurnstile();
return (
<Turnstile
sitekey="1x00000000000000000000AA"
onVerify={(token) => alert(token)}
onVerify={(token) => {
fetch("/login", {
method: "POST",
body: JSON.stringify({ token }),
}).then((response) => {
if (!response.ok) turnstile.reset();
});
}}
/>

@@ -33,2 +41,34 @@ );

### Reducing Layout Shift
The turnstile iframe initially loads as invisible before becoming visible and
expanding to the expected widget size.
This causes Layout Shift and reduces your Cumulative Layout Shift score and UX.
This can be fixed with the `fixedSize={true}` option, which will force the
wrapper div to be the specific size of turnstile.
### Bound Turnstile Object
The Bound Turnstile Object is given as argument to all callbacks and allows you
to call certain `window.turnstile` functions without having to store the `widgetId`
yourself.
```js
function Component() {
return (
<Turnstile
executution="execute"
onLoad={(widgetId, bound) => {
// before:
window.turnstile.execute(widgetId);
// now:
bound.execute();
}}
/>
);
}
```
## Documentation

@@ -38,18 +78,22 @@

| name | type | description |
| ----------------- | ------- | ----------------------------------------------------- |
| sitekey | string | sitekey of your website (REQUIRED) |
| action | string | - |
| cData | string | - |
| theme | string | one of "light", "dark", "auto" |
| tabIndex | number | - |
| responseField | boolean | controls generation of `<input />` element |
| responseFieldName | string | changes the name of `<input />` element |
| retry | string | one of "auto", "never" |
| retryInterval | number | interval of retries in ms |
| autoResetOnExpire | boolean | automatically reset the widget when the token expires |
| id | string | id of the div |
| ref | Ref | custom react ref for the div |
| className | string | passed to the div |
| style | object | passed to the div |
| name | type | description |
| ----------------- | ------- | ---------------------------------------------------- |
| sitekey | string | sitekey of your website (REQUIRED) |
| action | string | - |
| cData | string | - |
| theme | string | one of "light", "dark", "auto" |
| language | string | override the language used by turnstile |
| tabIndex | number | - |
| responseField | boolean | controls generation of `<input />` element |
| responseFieldName | string | changes the name of `<input />` element |
| size | string | one of "normal", "compact" |
| fixedSize | boolean | fix the size of the `<div />` to reduce layout shift |
| retry | string | one of "auto", "never" |
| retryInterval | number | interval of retries in ms |
| appearance | string | one of "always", "execute", "interaction-only" |
| execution | string | one of "render", "execute" |
| id | string | id of the div |
| ref | Ref | custom react ref for the div |
| className | string | passed to the div |
| style | object | passed to the div |

@@ -64,4 +108,8 @@ And the following callbacks:

| onExpire | - | called when the token expires |
| onTimeout | - | called when the challenge expires |
| onTimeout | token | called when the challenge expires |
The callbacks also take an additional `BoundTurnstileObject` which exposes
certain functions of `window.turnstile` which are already bound to the
current widget, so you don't need track the `widgetId` yourself.
For more details on what each argument does, see the [Cloudflare Documentation](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations).

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc