Skip to content

Commit

Permalink
Merge pull request #122 from hCaptcha/#120-Expose_public_methods_thro…
Browse files Browse the repository at this point in the history
…ugh_component

Methods exposed
  • Loading branch information
adekay authored Apr 26, 2022
2 parents eacb0ab + 392e14d commit a2225e3
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 1 deletion.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ return <HCaptcha ref={captchaRef} onLoad={onLoad} sitekey={sitekey} {...props} /
|Method|Description|
|---|---|
|`execute()`|Programmatically trigger a challenge request. Additionally, this method can be run asynchronously and returns a promise with the `token` and `eKey` when the challenge is completed.|
|`getRespKey()`|Get the current challenge reference ID|
|`getResponse()`|Get the current challenge response token from completed challenge|
|`resetCaptcha()`|Reset the current challenge|
|`setData()`|See enterprise docs.|


**NOTE**: Make sure to reset the hCaptcha state when you submit your form by calling the method `.resetCaptcha` on your hCaptcha React Component! Passcodes are one-time use, so if your user submits the same passcode twice then it will be rejected by the server the second time.
Expand Down
22 changes: 22 additions & 0 deletions examples/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,26 @@ const AsyncDemo = () => {
}
};

const getResponse = () => {
try {
const res = captchaRef.current.getResponse();
console.log("Response: ", res);

} catch (error) {
console.log(error);
}
};

const getRespKey = () => {
try {
const res = captchaRef.current.getRespKey();
console.log("Response Key: ", res);

} catch (error) {
console.log(error);
}
};

const handleOpen = () => {
console.log("HCaptcha [onOpen]: The user display of a challenge starts.");
};
Expand All @@ -40,6 +60,8 @@ const AsyncDemo = () => {
onChalExpired={handleChallengeExpired}
/>
<button onClick={executeCaptcha}>Execute asynchronously</button>
<button onClick={getRespKey}>Get Response Key</button>
<button onClick={getResponse}>Get Response</button>
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hcaptcha/react-hcaptcha",
"version": "1.1.1",
"version": "1.2.0",
"types": "types/index.d.ts",
"main": "dist/index.js",
"files": [
Expand Down
22 changes: 22 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,28 @@ class HCaptcha extends React.Component {
return hcaptcha.execute(captchaId, opts);
}

setData (data) {
const { captchaId } = this.state;

if (!this.isReady()) {
return;
}

if (data && typeof data !== "object") {
data = null;
}

hcaptcha.setData(captchaId, data);
}

getResponse() {
return hcaptcha.getResponse(this.state.captchaId);
}

getRespKey() {
return hcaptcha.getRespKey(this.state.captchaId)
}

render () {
const { elementId } = this.state;
return <div ref={this.ref} id={elementId}></div>
Expand Down
31 changes: 31 additions & 0 deletions tests/hcaptcha.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,14 @@ describe("hCaptcha", () => {
it("has functions", () => {
expect(typeof instance.execute).toBe("function");
expect(typeof instance.resetCaptcha).toBe("function");
expect(typeof instance.getResponse).toBe("function");
expect(typeof instance.getRespKey).toBe("function");
expect(typeof instance.setData).toBe("function");
expect(instance.execute).toBeDefined();
expect(instance.resetCaptcha).toBeDefined();
expect(instance.getResponse).toBeDefined();
expect(instance.getRespKey).toBeDefined();
expect(instance.setData).toBeDefined();
});

it("can execute synchronously without arguments", () => {
Expand Down Expand Up @@ -120,6 +126,31 @@ describe("hCaptcha", () => {
expect(window.hcaptcha.remove.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
});

it("can get Response", () => {
expect(window.hcaptcha.getResponse.mock.calls.length).toBe(0);
const res = instance.getResponse();
expect(window.hcaptcha.getResponse.mock.calls.length).toBe(1);
expect(window.hcaptcha.getResponse.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
expect(res).toBe(MOCK_TOKEN);
});

it("can get RespKey", () => {
expect(window.hcaptcha.getRespKey.mock.calls.length).toBe(0);
const res = instance.getRespKey();
expect(window.hcaptcha.getRespKey.mock.calls.length).toBe(1);
expect(window.hcaptcha.getRespKey.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
expect(res).toBe(MOCK_EKEY);
});

it("can set Data", () => {
expect(window.hcaptcha.setData.mock.calls.length).toBe(0);
const dataObj = { data: { nested: 1 } };
instance.setData(dataObj);
expect(window.hcaptcha.setData.mock.calls.length).toBe(1);
expect(window.hcaptcha.setData.mock.calls[0][0]).toBe(MOCK_WIDGET_ID);
expect(window.hcaptcha.setData.mock.calls[0][1]).toBe(dataObj);
});

it("emits onLoad event", () => {
expect(mockFns.onLoad.mock.calls.length).toBe(0);
instance.handleOnLoad();
Expand Down
3 changes: 3 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ declare class HCaptcha extends React.Component<HCaptchaProps, HCaptchaState> {
resetCaptcha(): void;
renderCaptcha(): void;
removeCaptcha(): void;
getRespKey(): string;
getResponse(): string;
setData(data: object): void;
execute(opts: { async: true }): Promise<ExecuteResponse>;
execute(opts?: { async: false }): void;
execute(opts?: { async: boolean }): Promise<ExecuteResponse> | void;
Expand Down

0 comments on commit a2225e3

Please sign in to comment.