Skip to content

Commit d41edce

Browse files
authored
Merge pull request #1059 from singnet/SM-254_implement-captcha
[SM-254] add captcha functionality for feedback form
2 parents 29dc027 + e416cda commit d41edce

File tree

7 files changed

+126
-5
lines changed

7 files changed

+126
-5
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export const WAF_SCRIPT_ID = "AwsWAFScript";
2+
3+
export function checkWAFEnv() {
4+
const errors = [];
5+
if (!process.env.REACT_APP_CAPTCHA_TOKEN) {
6+
errors.push("REACT_APP_CAPTCHA_TOKEN is not set");
7+
}
8+
if (!process.env.REACT_APP_JSAPI_URL) {
9+
errors.push("REACT_APP_JSAPI_URL is not set");
10+
}
11+
return { isValid: errors.length === 0, errors };
12+
}
13+
14+
export function getWAFEnv() {
15+
return {
16+
JSAPI_URL: process.env.REACT_APP_JSAPI_URL,
17+
CAPTCHA_TOKEN: process.env.REACT_APP_CAPTCHA_TOKEN,
18+
};
19+
}
20+
21+
export function loadCaptchaScript() {
22+
const JSAPI_URL = getWAFEnv().JSAPI_URL;
23+
if (document.getElementById(WAF_SCRIPT_ID) || !JSAPI_URL) return;
24+
const AwsWafScript = document.createElement("script");
25+
AwsWafScript.id = WAF_SCRIPT_ID;
26+
AwsWafScript.async = false;
27+
AwsWafScript.src = JSAPI_URL;
28+
document.head.appendChild(AwsWafScript);
29+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { checkWAFEnv, getWAFEnv } from "./WAFScriptLoad";
2+
3+
export const captchaFetch = (path, init) => {
4+
const { isValid, errors } = checkWAFEnv();
5+
if (!isValid) {
6+
throw Error(errors[0]);
7+
}
8+
9+
const modalOverlay = document.getElementById("modalOverlay");
10+
const modal = document.getElementById("modal");
11+
const captchaForm = document.getElementById("captchaForm");
12+
const API_KEY = getWAFEnv().CAPTCHA_TOKEN;
13+
14+
if (!modalOverlay || !modal || !captchaForm || !API_KEY) {
15+
throw Error("Can't find modal components");
16+
}
17+
18+
modalOverlay.style.display = "block";
19+
modal.style.display = "block";
20+
21+
return new Promise((resolve) => {
22+
window.AwsWafCaptcha.renderCaptcha(captchaForm, {
23+
onSuccess: () => {
24+
modalOverlay.style.display = "none";
25+
modal.style.display = "none";
26+
resolve(window.AwsWafIntegration.fetch(path, init));
27+
},
28+
onLoad: () => {
29+
document.body.style.cursor = "default";
30+
},
31+
apiKey: API_KEY,
32+
});
33+
});
34+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.captcha-modal.overlay {
2+
position: fixed;
3+
top: 0;
4+
left: 0;
5+
width: 100vw;
6+
height: 100vh;
7+
background-color: rgba(128,128,128,0.5);
8+
display: none;
9+
z-index: 1000;
10+
}
11+
12+
.captcha-modal .modal {
13+
position: fixed;
14+
top: 50vh;
15+
left: 50vw;
16+
transform: translate(-50%,-50%);
17+
background-color: white;
18+
border-radius: 8px;
19+
padding: 16px;
20+
}
21+
22+
.captcha-modal .captchaForm {
23+
position: relative;
24+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import './CaptchaModal.css';
2+
3+
const CaptchaModal = () => {
4+
return (
5+
<div className='captcha-modal overlay' id="modalOverlay">
6+
<div className='modal' id="modal">
7+
<div id="captchaForm" className='captchaForm'/>
8+
</div>
9+
</div>
10+
)
11+
}
12+
13+
export default CaptchaModal;

src/components/FeedbackFormModal/index.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
1-
import { Fragment, useState } from "react";
1+
import { Fragment, useEffect, useState } from "react";
22
import OpenFormButton from "./OpenFormButton";
33
import "./styles.css";
44
import FeedbackFormModal from "./FeedbackFormModal";
55
import { sendFeedbackSnetAPI } from "../../config/SupportAPI";
6+
import CaptchaModal from "../Captcha/modal/CaptchaModal";
7+
import { loadCaptchaScript } from "../Captcha/WAFScriptLoad";
68

79
const FeedbackForm = () => {
810
const [isModalVisible, setIsModalVisible] = useState(false);
911

12+
useEffect(() => {
13+
try {
14+
loadCaptchaScript();
15+
} catch (err) {
16+
console.error("CAPTCHA script error: ", err);
17+
}
18+
}, []);
19+
1020
return (
1121
<Fragment>
22+
<CaptchaModal />
1223
<FeedbackFormModal
1324
sendFeedbackAPI={sendFeedbackSnetAPI}
1425
isModalVisible={isModalVisible}

src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/GeneralAccountWallet/PaymentPopup/Purchase/PurchaseAlert.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1-
import React, { useState } from "react";
1+
import React, { useEffect, useState } from "react";
22
import { withStyles } from "@mui/styles";
33

44
import AlertBox from "../../../../../../../../common/AlertBox";
55
import StyledButton from "../../../../../../../../common/StyledButton";
66
import { useStyles } from "./styles";
77
import { sendFeedbackSnetAPI } from "../../../../../../../../../config/SupportAPI";
88
import FeedbackFormModal from "../../../../../../../../FeedbackFormModal/FeedbackFormModal";
9+
import { loadCaptchaScript } from "../../../../../../../../Captcha/WAFScriptLoad";
910

1011
const PurchaseAlert = ({ classes, alert, handleCancel }) => {
1112
const [isModalVisible, setIsModalVisible] = useState(false);
1213

14+
useEffect(() => {
15+
try {
16+
loadCaptchaScript();
17+
} catch (err) {
18+
console.error("CAPTCHA script error: ", err);
19+
}
20+
}, []);
21+
1322
return (
1423
<div className={classes.purchaseErrorContainer}>
1524
<AlertBox type={alert.type} message={alert.message} />

src/config/SupportAPI.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import axios from "axios";
2+
import { captchaFetch } from "../components/Captcha/captchaFetchHandler";
23

34
const source = "MARKETPLACE";
45

5-
export const sendFeedbackSnetAPI = async ({ name, email, category, feedback, attachmentUrls }) => {
6+
export const sendFeedbackSnetAPI = ({ name, email, category, feedback, attachmentUrls }) => {
67
const options = {
78
method: "POST",
89
headers: {
@@ -22,11 +23,11 @@ export const sendFeedbackSnetAPI = async ({ name, email, category, feedback, att
2223
attachment_urls: attachmentUrls,
2324
}),
2425
};
25-
const feedbackUrl = process?.env?.REACT_APP_FEEDBACK_ENDPOINT;
26+
const feedbackUrl = process?.env?.REACT_APP_FEEDBACK_ENDPOINT + "err";
2627
if (!feedbackUrl) {
2728
throw new Error("Cannot start the application! process.env.REACT_APP_FEEDBACK_ENDPOINT is undefined");
2829
}
29-
await fetch(feedbackUrl + "/user/message", options);
30+
captchaFetch(feedbackUrl + "/user/message", options);
3031
};
3132

3233
const ENTER_CODE = "%0D%0A";

0 commit comments

Comments
 (0)