diff --git a/package.json b/package.json index 6dcba917..2192ca95 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "cryptr": "^6.2.0", "eslint": "^8.40.0", "eslint-config-next": "13.2.3", + "hibp": "^13.0.0", "next": "13.2.3", "prop-types": ">=15.7.0", "react": "18.2.0", diff --git a/src/components/elements/boxContentCenter/index.tsx b/src/components/elements/boxContentCenter/index.tsx index 0c757934..28ed31c8 100644 --- a/src/components/elements/boxContentCenter/index.tsx +++ b/src/components/elements/boxContentCenter/index.tsx @@ -11,7 +11,7 @@ export default function BoxContentCenter({ children }: any) { alignItems: "center", }} > - + {children} diff --git a/src/pages/api/pwned/[password].ts b/src/pages/api/pwned/[password].ts new file mode 100644 index 00000000..caa5ab18 --- /dev/null +++ b/src/pages/api/pwned/[password].ts @@ -0,0 +1,24 @@ +import { NextApiRequest, NextApiResponse } from 'next/types'; +import { pwnedPassword } from 'hibp'; +import { Crypto } from '@/helpers'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +): Promise { + const { token } = req.cookies; + + if (token !== process.env.NEXT_PUBLIC_COOKIE_KEY) { + return res.status(401).send(); + } + + const { password } = req.query; + + if (typeof password !== 'undefined') { + const passwordKey = Array.isArray(password) ? password[0] : password; + const data = await pwnedPassword(Crypto.decrypt(passwordKey)); + res.status(200).json(data); + } else { + res.status(400); + } +} diff --git a/src/pages/register/index.tsx b/src/pages/register/index.tsx index a29365f7..fbf79b46 100644 --- a/src/pages/register/index.tsx +++ b/src/pages/register/index.tsx @@ -9,7 +9,7 @@ export default function Index() { diff --git a/src/pages/register/stepper/step3.tsx b/src/pages/register/stepper/step3.tsx index 3299042d..0b3854ad 100644 --- a/src/pages/register/stepper/step3.tsx +++ b/src/pages/register/stepper/step3.tsx @@ -5,7 +5,11 @@ import { useState } from 'react'; import * as yup from 'yup'; import axios from 'axios'; -import { AlertError, AlertWarning } from '@/components/elements/alert'; +import { + AlertError, + AlertErrorMessage, + AlertWarning, +} from '@/components/elements/alert'; import { GridContainer, GridItem } from '@/components/elements/grid'; import LoadingBackdrop from '@/components/elements/loadingBackdrop'; import PasswordLevel from '@/components/elements/passwordLevel'; @@ -42,14 +46,16 @@ const schema = yup.object({ }); export default function Step3({ handleNext, infoCedula }: any) { + const [loadingValidatingPassword, setLoadingValidatingPassword] = + useState(false); const [loading, setLoading] = useState(false); const [passwordLevel, setPasswordLevel] = useState({}); + const [isPwned, setIsPwned] = useState(false); const { register, handleSubmit, formState: { errors }, - getValues, setValue, } = useForm({ mode: 'onChange', @@ -60,36 +66,58 @@ export default function Step3({ handleNext, infoCedula }: any) { const level = passwordStrength(password); setPasswordLevel(level); setValue('password', password); + setIsPwned(false); }; const onSubmit = (data: IFormInputs) => { + if (isPwned) return; if (passwordLevel.id !== 3) return; - setLoading(true); + setLoadingValidatingPassword(true); const password = Crypto.encrypt(data.password); - axios - .post('/api/iam', { - email: data.email, - username: infoCedula.id, - password, - }) - .then(() => { - handleNext(); - }) - .catch((err) => { - if (err?.response?.status === 409) { - AlertWarning('El correo electrónico ya está registrado.'); - } else { - AlertError(); - } - }) - .finally(() => setLoading(false)); + if (!isPwned) { + axios + .get(`/api/pwned/${password}`) + .then((res) => { + console.log(res); + const isPwnedIncludes = res.data === 0 ? false : true; + setIsPwned(isPwnedIncludes); + if (!isPwnedIncludes) { + setLoadingValidatingPassword(false); + setLoading(true); + axios + .post('/api/iam', { + email: data.email, + username: infoCedula.id, + password, + }) + .then(() => { + handleNext(); + }) + .catch((err) => { + if (err?.response?.status === 409) { + AlertWarning('El correo electrónico ya está registrado.'); + } else { + AlertError(); + } + }) + .finally(() => setLoading(false)); + } + }) + .catch(() => { + return AlertWarning('No pudimos validar si la contraseña es segura.'); + }) + .finally(() => setLoadingValidatingPassword(false)); + } }; return ( <> - {loading && } + {loadingValidatingPassword && ( + + )} + {loading && }
Para finalizar tu registro completa los siguientes campos: @@ -166,10 +194,6 @@ export default function Step3({ handleNext, infoCedula }: any) { { - e.preventDefault(); - return false; - }} autoComplete="off" {...register('password')} onChange={(e: React.ChangeEvent) => @@ -189,10 +213,6 @@ export default function Step3({ handleNext, infoCedula }: any) { { - e.preventDefault(); - return false; - }} autoComplete="off" {...register('passwordConfirm')} disabled={passwordLevel.id === 3 ? false : true} @@ -200,20 +220,17 @@ export default function Step3({ handleNext, infoCedula }: any) { + {isPwned && ( + + + + )} + - - value !== null && value !== undefined && value !== '' - ) === false - ? true - : false - } - > - ACEPTAR Y CONFIRMAR - + CREAR CUENTA ÚNICA diff --git a/yarn.lock b/yarn.lock index 7a5ee94e..c430adeb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5823,6 +5823,41 @@ resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ== +"@remix-run/web-blob@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@remix-run/web-blob/-/web-blob-3.0.4.tgz#99c67b9d0fb641bd0c07d267fd218ae5aa4ae5ed" + integrity sha512-AfegzZvSSDc+LwnXV+SwROTrDtoLiPxeFW+jxgvtDAnkuCX1rrzmVJ6CzqZ1Ai0bVfmJadkG5GxtAfYclpPmgw== + dependencies: + "@remix-run/web-stream" "^1.0.0" + web-encoding "1.1.5" + +"@remix-run/web-fetch@^4.3.4": + version "4.3.4" + resolved "https://registry.yarnpkg.com/@remix-run/web-fetch/-/web-fetch-4.3.4.tgz#6149582fa2199b8e2a35d4e653ba05772bd0e675" + integrity sha512-AUM1XBa4hcgeNt2CD86OlB5aDLlqdMl0uJ+89R8dPGx07I5BwMXnbopCaPAkvSBIoHeT/IoLWIuZrLi7RvXS+Q== + dependencies: + "@remix-run/web-blob" "^3.0.4" + "@remix-run/web-form-data" "^3.0.3" + "@remix-run/web-stream" "^1.0.3" + "@web3-storage/multipart-parser" "^1.0.0" + abort-controller "^3.0.0" + data-uri-to-buffer "^3.0.1" + mrmime "^1.0.0" + +"@remix-run/web-form-data@^3.0.3": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@remix-run/web-form-data/-/web-form-data-3.0.4.tgz#18c5795edaffbc88c320a311766dc04644125bab" + integrity sha512-UMF1jg9Vu9CLOf8iHBdY74Mm3PUvMW8G/XZRJE56SxKaOFWGSWlfxfG+/a3boAgHFLTkP7K4H1PxlRugy1iQtw== + dependencies: + web-encoding "1.1.5" + +"@remix-run/web-stream@^1.0.0", "@remix-run/web-stream@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@remix-run/web-stream/-/web-stream-1.0.3.tgz#3284a6a45675d1455c4d9c8f31b89225c9006438" + integrity sha512-wlezlJaA5NF6SsNMiwQnnAW6tnPzQ5I8qk0Y0pSohm0eHKa2FQ1QhEKLVVcDDu02TmkfHgnux0igNfeYhDOXiA== + dependencies: + web-streams-polyfill "^3.1.1" + "@rushstack/eslint-patch@^1.1.3": version "1.2.0" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" @@ -6335,6 +6370,11 @@ "@typescript-eslint/types" "5.59.5" eslint-visitor-keys "^3.3.0" +"@web3-storage/multipart-parser@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@web3-storage/multipart-parser/-/multipart-parser-1.0.0.tgz#6b69dc2a32a5b207ba43e556c25cc136a56659c4" + integrity sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw== + "@xstate/react@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@xstate/react/-/react-3.0.0.tgz#888d9a6f128c70b632c18ad55f1f851f6ab092ba" @@ -6351,6 +6391,11 @@ use-isomorphic-layout-effect "^1.0.0" use-sync-external-store "^1.0.0" +"@zxing/text-encoding@0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b" + integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -7314,6 +7359,11 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +data-uri-to-buffer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== + dayjs@^1.8.15: version "1.11.7" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" @@ -8645,6 +8695,14 @@ hermes-profile-transformer@^0.0.6: dependencies: source-map "^0.7.3" +hibp@^13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/hibp/-/hibp-13.0.0.tgz#dd66f3fbccfdd632177c7dc64f7e428a40701e39" + integrity sha512-d3D2W9fqhIu4EJ8Wa85rXKHBxpIB9dEsHDIWNB26bcptlU18VD3PCfDVsVBE8nd/zImJmbNqRgfpzgO6pJ68Sg== + dependencies: + "@remix-run/web-fetch" "^4.3.4" + jssha "^3.3.0" + hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -8772,7 +8830,7 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.1.1: +is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -8912,6 +8970,13 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -9021,7 +9086,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.9: +is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: version "1.1.10" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== @@ -9342,6 +9407,11 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jssha@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/jssha/-/jssha-3.3.0.tgz#44b5531bcf55a12f4a388476c647a9a1cca92839" + integrity sha512-w9OtT4ALL+fbbwG3gw7erAO0jvS5nfvrukGPMWIAoea359B26ALXGpzy4YJSp9yGnpUvuvOw1nSjSoHDfWSr1w== + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" @@ -10022,6 +10092,11 @@ mkdirp@^0.5.1: dependencies: minimist "^1.2.6" +mrmime@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" + integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -12165,6 +12240,17 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util@^0.12.3: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -12213,6 +12299,20 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +web-encoding@1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864" + integrity sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA== + dependencies: + util "^0.12.3" + optionalDependencies: + "@zxing/text-encoding" "0.9.0" + +web-streams-polyfill@^3.1.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -12276,7 +12376,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== -which-typed-array@^1.1.9: +which-typed-array@^1.1.2, which-typed-array@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==