Add submission key to frontend to prevent duplicate signups
This commit is contained in:
Generated
+31
-11
@@ -34,7 +34,8 @@
|
|||||||
"sharp": "^0.30.3",
|
"sharp": "^0.30.3",
|
||||||
"shortid": "^2.2.16",
|
"shortid": "^2.2.16",
|
||||||
"styled-components": "^5.3.5",
|
"styled-components": "^5.3.5",
|
||||||
"swr": "^1.2.2"
|
"swr": "^1.2.2",
|
||||||
|
"uuid": "^13.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^27.4.1",
|
||||||
@@ -13610,6 +13611,17 @@
|
|||||||
"semver": "bin/semver"
|
"semver": "bin/semver"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/testcafe-reporter-dashboard/node_modules/uuid": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
|
||||||
|
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/testcafe-reporter-json": {
|
"node_modules/testcafe-reporter-json": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/testcafe-reporter-json/-/testcafe-reporter-json-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/testcafe-reporter-json/-/testcafe-reporter-json-2.2.0.tgz",
|
||||||
@@ -14510,13 +14522,16 @@
|
|||||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
"version": "3.3.3",
|
"version": "13.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
|
||||||
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
|
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
|
||||||
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
"funding": [
|
||||||
"dev": true,
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uuid": "bin/uuid"
|
"uuid": "dist-node/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/uvu": {
|
"node_modules/uvu": {
|
||||||
@@ -25397,6 +25412,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -25859,10 +25880,9 @@
|
|||||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "3.3.3",
|
"version": "13.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
|
||||||
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
|
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"uvu": {
|
"uvu": {
|
||||||
"version": "0.5.3",
|
"version": "0.5.3",
|
||||||
|
|||||||
+2
-1
@@ -89,7 +89,8 @@
|
|||||||
"sharp": "^0.30.3",
|
"sharp": "^0.30.3",
|
||||||
"shortid": "^2.2.16",
|
"shortid": "^2.2.16",
|
||||||
"styled-components": "^5.3.5",
|
"styled-components": "^5.3.5",
|
||||||
"swr": "^1.2.2"
|
"swr": "^1.2.2",
|
||||||
|
"uuid": "^13.0.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"react-mde": {
|
"react-mde": {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { OptionTypes } from "@components/Widgets/SignupQuestionsWidget/common";
|
import { OptionTypes } from "@components/Widgets/SignupQuestionsWidget/common";
|
||||||
|
|
||||||
export interface Signup {
|
export interface Signup {
|
||||||
id?: number;
|
id?: number; // Database id for completed signup
|
||||||
|
submitKey?: string; // Signup request idempotency key
|
||||||
signupForm_id: number;
|
signupForm_id: number;
|
||||||
answer: string;
|
answer: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import PageWrapper from "@views/common/PageWrapper";
|
|||||||
import LoadingView from "@views/common/LoadingView";
|
import LoadingView from "@views/common/LoadingView";
|
||||||
import noop from "@utils/noop";
|
import noop from "@utils/noop";
|
||||||
import NotFoundPage from "@pages/404";
|
import NotFoundPage from "@pages/404";
|
||||||
|
import { v4 as uuid } from "uuid";
|
||||||
|
|
||||||
type InitialProps = {
|
type InitialProps = {
|
||||||
initialForm: SignupForm;
|
initialForm: SignupForm;
|
||||||
@@ -23,6 +24,7 @@ const FORM_URL = `${process.env.NEXT_PUBLIC_API_URL}/signupForm/`;
|
|||||||
const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const id = String(initialForm?.id ?? "");
|
const id = String(initialForm?.id ?? "");
|
||||||
|
const submitKey = uuid(); // Submission key, generated on page refresh
|
||||||
const URL = `${FORM_URL}${id}/`;
|
const URL = `${FORM_URL}${id}/`;
|
||||||
const { data: signupForm, error } = useSWR<SignupForm>(URL, (url) => axios.get(url).then((res) => res.data), { fallbackData: initialForm });
|
const { data: signupForm, error } = useSWR<SignupForm>(URL, (url) => axios.get(url).then((res) => res.data), { fallbackData: initialForm });
|
||||||
|
|
||||||
@@ -43,6 +45,7 @@ const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
|
|||||||
|
|
||||||
const onSubmit = async ({ formData }: ISubmitEvent<string>) => {
|
const onSubmit = async ({ formData }: ISubmitEvent<string>) => {
|
||||||
const payload: Signup = {
|
const payload: Signup = {
|
||||||
|
submitKey, // This is for preventing duplicate requests; NOT RELATED TO THE SIGNUP ID IN DATABASE
|
||||||
signupForm_id: signupForm.id,
|
signupForm_id: signupForm.id,
|
||||||
answer: formData,
|
answer: formData,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user