From b4c99310057c048d662d5537cb489e5f2985b7fc Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 8 Aug 2024 12:05:09 +0530 Subject: [PATCH 1/5] Add beehiiv widget for email verification --- src/App.tsx | 4 ++++ src/constants.ts | 2 ++ src/pages/RedirectEmail.tsx | 31 +++++++++++++++++++++++++++++++ src/pages/TermsAndConditions.tsx | 2 +- src/pages/VerifyEmail.tsx | 24 ++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/pages/RedirectEmail.tsx create mode 100644 src/pages/VerifyEmail.tsx diff --git a/src/App.tsx b/src/App.tsx index 596a474..128a1e8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,8 @@ import UserVerification from "./pages/UserVerification"; import TermsAndConditions from "./pages/TermsAndConditions"; import Header from "./components/Header"; import { WalletConnectProvider } from "./context/WalletConnectContext"; +import VerifyEmail from "./pages/VerifyEmail"; +import RedirectEmail from "./pages/RedirectEmail"; function App() { return ( @@ -19,6 +21,8 @@ function App() { } /> + } /> + } /> } /> }> } /> diff --git a/src/constants.ts b/src/constants.ts index 9443af8..477dba9 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -30,4 +30,6 @@ export const TNC_PARTICIPANT_CONTENT = `Lorem ipsum dolor sit amet, consectetur export const WALLET_DISCLAIMER_MSG = 'You are connecting to an experimental wallet! It is not secure. Do not use it elsewhere and/or for managing real assets.' +export const REDIRECT_EMAIL_MSG = 'Please check your inbox and click the link to verify your email address.' + export const ENABLE_KYC = false; diff --git a/src/pages/RedirectEmail.tsx b/src/pages/RedirectEmail.tsx new file mode 100644 index 0000000..1e1ad01 --- /dev/null +++ b/src/pages/RedirectEmail.tsx @@ -0,0 +1,31 @@ +import { Box, Typography } from '@mui/material' +import React from 'react' +import { REDIRECT_EMAIL_MSG } from '../constants' + +const RedirectEmail = () => { + return ( + + + Thank you for registering! + + + {REDIRECT_EMAIL_MSG} + + + ) +} + +export default RedirectEmail diff --git a/src/pages/TermsAndConditions.tsx b/src/pages/TermsAndConditions.tsx index 25a9879..a0f8112 100644 --- a/src/pages/TermsAndConditions.tsx +++ b/src/pages/TermsAndConditions.tsx @@ -9,7 +9,7 @@ const TermsAndConditions = () => { const navigate = useNavigate(); const handleAccept = () => { - navigate('/connect-wallet'); + navigate('/verify-email'); }; return ( diff --git a/src/pages/VerifyEmail.tsx b/src/pages/VerifyEmail.tsx new file mode 100644 index 0000000..4c8f053 --- /dev/null +++ b/src/pages/VerifyEmail.tsx @@ -0,0 +1,24 @@ +import React from 'react' + +const VerifyEmail = () => { + return ( +
+ +
+ ) +} + +export default VerifyEmail -- 2.45.2 From 052fd62c155c3fe0c27a4ee55be99381399e38f4 Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 8 Aug 2024 13:13:29 +0530 Subject: [PATCH 2/5] Extract subscriber ID from verified JWT --- package.json | 2 + src/pages/ConnectWallet.tsx | 14 +++- src/pages/SignWithNitroKey.tsx | 8 ++- src/pages/VerifyJWT.tsx | 47 +++++++++++++ yarn.lock | 119 +++++++++++++++++++++++++-------- 5 files changed, 156 insertions(+), 34 deletions(-) create mode 100644 src/pages/VerifyJWT.tsx diff --git a/package.json b/package.json index f821887..1fb02b4 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@mui/material": "^5.15.14", "@sumsub/websdk": "^2.3.1", "@sumsub/websdk-react": "^2.3.1", + "@types/jsonwebtoken": "^9.0.6", "@walletconnect/encoding": "^1.0.2", "@walletconnect/modal": "^2.6.2", "@walletconnect/sign-client": "^2.11.3", @@ -23,6 +24,7 @@ "crypto-browserify": "^3.12.0", "ethers": "5.7.2", "https-browserify": "^1.0.0", + "jsonwebtoken": "^9.0.2", "notistack": "^3.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/pages/ConnectWallet.tsx b/src/pages/ConnectWallet.tsx index aaa90f9..061dc33 100644 --- a/src/pages/ConnectWallet.tsx +++ b/src/pages/ConnectWallet.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from "react"; -import {useNavigate } from "react-router-dom"; +import {useLocation, useNavigate } from "react-router-dom"; import { Button, Box, Container, Typography, colors } from "@mui/material"; @@ -10,14 +10,22 @@ const ConnectWallet = () => { const { connect, session } = useWalletConnectContext(); const navigate = useNavigate(); + const location = useLocation(); + const {kycIdHash} = location.state as { + kycIdHash?: string + } useEffect(() => { if (session) { - navigate("/sign-with-nitro-key"); + navigate("/sign-with-nitro-key", { + state: { + kycIdHash + } + }); } - }, [session, navigate,]); + }, [session, navigate, kycIdHash]); const handler = async () => { await connect(); diff --git a/src/pages/SignWithNitroKey.tsx b/src/pages/SignWithNitroKey.tsx index 3580ee3..9d48e1e 100644 --- a/src/pages/SignWithNitroKey.tsx +++ b/src/pages/SignWithNitroKey.tsx @@ -1,8 +1,7 @@ import React, { useState, useMemo, useEffect } from "react"; -import { useNavigate } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import { enqueueSnackbar } from "notistack"; import canonicalStringify from "canonical-json"; -import { ethers } from "ethers"; import { Select, @@ -28,6 +27,7 @@ const SignWithNitroKey = () => { }, [session, signClient, checkPersistedState]); const navigate = useNavigate(); + const location = useLocation(); const [ethAddress, setEthAddress] = useState(""); const [ethSignature, setEthSignature] = useState(""); @@ -68,7 +68,9 @@ const SignWithNitroKey = () => { }, }); } else { - const kycIdHash = ethers.utils.sha256(ethers.utils.toUtf8Bytes(cosmosAddress)); + const {kycIdHash} = location.state as { + kycIdHash?: string + } navigate("/sign-with-cosmos", { state: { diff --git a/src/pages/VerifyJWT.tsx b/src/pages/VerifyJWT.tsx new file mode 100644 index 0000000..94f01e9 --- /dev/null +++ b/src/pages/VerifyJWT.tsx @@ -0,0 +1,47 @@ +import React, { useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +import jwt from 'jsonwebtoken'; +import { sha256 } from 'ethers/lib/utils'; + +interface JwtPayload { + subscriber_id: string; + exp: number; + iss: string; + iat: number; +} +const VerifyJWTToken: React.FC = () => { + const location = useLocation(); + const navigate = useNavigate(); + + const [err, setErr] = useState(); + + useEffect(() => { + const queryParams = new URLSearchParams(location.search); + const token = queryParams.get('jwt_token'); + + if (token) { + try { + const decoded = jwt.decode(token) as JwtPayload; + const currentTime = Math.floor(Date.now() / 1000); + + if (decoded.exp < currentTime) { + throw new Error("Token has expired"); + } + + const kycIdHash = sha256(decoded.subscriber_id); + + navigate('/connect-wallet', { + state:{ + kycIdHash + } + }); + } catch (error) { + setErr(String(error)); + } + } + }, [location.search, navigate]); + + return (
{err ? err : "Loading..."}
); +}; + +export default VerifyJWTToken; diff --git a/yarn.lock b/yarn.lock index 6cdf7e1..ea08ace 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3453,6 +3453,13 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/jsonwebtoken@^9.0.6": + version "9.0.6" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz#d1af3544d99ad992fb6681bbe60676e06b032bd3" + integrity sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw== + dependencies: + "@types/node" "*" + "@types/long@^4.0.1": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" @@ -5040,6 +5047,11 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -6208,6 +6220,13 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -9017,6 +9036,22 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -9032,6 +9067,23 @@ junk@3.1.0: resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + keccak@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" @@ -9250,11 +9302,41 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + lodash.isequal@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -9265,6 +9347,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -11985,16 +12072,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12078,14 +12156,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -13338,7 +13409,8 @@ workbox-window@6.6.1: "@types/trusted-types" "^2.0.2" workbox-core "6.6.1" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -13356,15 +13428,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" -- 2.45.2 From 76e9f996a30008fdd9264adad94e578df724ceae Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 8 Aug 2024 14:11:36 +0530 Subject: [PATCH 3/5] Check for KYC ID on connect wallet page --- src/pages/ConnectWallet.tsx | 58 ++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/pages/ConnectWallet.tsx b/src/pages/ConnectWallet.tsx index 061dc33..fed158a 100644 --- a/src/pages/ConnectWallet.tsx +++ b/src/pages/ConnectWallet.tsx @@ -17,6 +17,9 @@ const ConnectWallet = () => { } useEffect(() => { + if (!kycIdHash) { + return; + } if (session) { navigate("/sign-with-nitro-key", { @@ -33,7 +36,41 @@ const ConnectWallet = () => { return ( - + + + Disclaimer + + + {WALLET_DISCLAIMER_MSG} + + + + + + : { padding={5} > - Disclaimer + Error - {WALLET_DISCLAIMER_MSG} + KYC ID not found. Please verify your email and try again - - - + } ); }; -- 2.45.2 From 04b2eeb77a845c85d1677222a7e169e642ebf80e Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 8 Aug 2024 15:04:13 +0530 Subject: [PATCH 4/5] Handle subscriber ID check in nitro key signature page --- package.json | 3 +- src/App.tsx | 6 +- src/pages/ConnectWallet.tsx | 68 +++++----------- src/pages/{RedirectEmail.tsx => Email.tsx} | 8 +- src/pages/SignWithCosmos.tsx | 8 +- src/pages/SignWithNitroKey.tsx | 10 ++- src/pages/Thanks.tsx | 73 ++++++++++++++++++ src/pages/UserVerification.tsx | 2 +- src/pages/VerifyJWT.tsx | 47 ----------- yarn.lock | 90 +--------------------- 10 files changed, 118 insertions(+), 197 deletions(-) rename src/pages/{RedirectEmail.tsx => Email.tsx} (91%) create mode 100644 src/pages/Thanks.tsx delete mode 100644 src/pages/VerifyJWT.tsx diff --git a/package.json b/package.json index 1fb02b4..7a76c72 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "@mui/material": "^5.15.14", "@sumsub/websdk": "^2.3.1", "@sumsub/websdk-react": "^2.3.1", - "@types/jsonwebtoken": "^9.0.6", "@walletconnect/encoding": "^1.0.2", "@walletconnect/modal": "^2.6.2", "@walletconnect/sign-client": "^2.11.3", @@ -24,7 +23,7 @@ "crypto-browserify": "^3.12.0", "ethers": "5.7.2", "https-browserify": "^1.0.0", - "jsonwebtoken": "^9.0.2", + "jwt-decode": "^4.0.0", "notistack": "^3.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/App.tsx b/src/App.tsx index 128a1e8..4737a39 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,7 +12,8 @@ import TermsAndConditions from "./pages/TermsAndConditions"; import Header from "./components/Header"; import { WalletConnectProvider } from "./context/WalletConnectContext"; import VerifyEmail from "./pages/VerifyEmail"; -import RedirectEmail from "./pages/RedirectEmail"; +import Email from "./pages/Email"; +import Thanks from "./pages/Thanks"; function App() { return ( @@ -22,8 +23,9 @@ function App() { } /> } /> - } /> + } /> } /> + } /> }> } /> { const navigate = useNavigate(); const location = useLocation(); - const {kycIdHash} = location.state as { - kycIdHash?: string - } - useEffect(() => { - if (!kycIdHash) { - return; - } if (session) { navigate("/sign-with-nitro-key", { - state: { - kycIdHash - } + state: location.state }); } - }, [session, navigate, kycIdHash]); + }, [session, navigate, location]); const handler = async () => { await connect(); @@ -36,41 +27,7 @@ const ConnectWallet = () => { return ( - {kycIdHash ? <> - - - Disclaimer - - - {WALLET_DISCLAIMER_MSG} - - - - - - : { padding={5} > - Error + Disclaimer - KYC ID not found. Please verify your email and try again + {WALLET_DISCLAIMER_MSG} - } + + + ); }; diff --git a/src/pages/RedirectEmail.tsx b/src/pages/Email.tsx similarity index 91% rename from src/pages/RedirectEmail.tsx rename to src/pages/Email.tsx index 1e1ad01..039b74c 100644 --- a/src/pages/RedirectEmail.tsx +++ b/src/pages/Email.tsx @@ -1,8 +1,10 @@ -import { Box, Typography } from '@mui/material' import React from 'react' + +import { Box, Typography } from '@mui/material' + import { REDIRECT_EMAIL_MSG } from '../constants' -const RedirectEmail = () => { +const Email = () => { return ( { ) } -export default RedirectEmail +export default Email diff --git a/src/pages/SignWithCosmos.tsx b/src/pages/SignWithCosmos.tsx index 144ce76..46a1db8 100644 --- a/src/pages/SignWithCosmos.tsx +++ b/src/pages/SignWithCosmos.tsx @@ -25,14 +25,14 @@ const SignWithCosmos = () => { const navigate = useNavigate(); - const {message: innerMessage, cosmosAddress, receivedEthSig: ethSignature, kycIdHash} = location.state as { + const {message: innerMessage, cosmosAddress, receivedEthSig: ethSignature, subscriberIdHash} = location.state as { message?: { msg: string; address: string; }; cosmosAddress?: string; receivedEthSig?: string; - kycIdHash?: string; + subscriberIdHash?: string; }; const ethAddress = innerMessage!.address; @@ -49,11 +49,11 @@ const SignWithCosmos = () => { participant: cosmosAddress!, ethPayload: innerMessage, ethSignature: ethSignature!, - kycId: kycIdHash!, + kycId: subscriberIdHash!, role }, }; - }, [cosmosAddress, innerMessage, ethSignature, kycIdHash, role]); + }, [cosmosAddress, innerMessage, ethSignature, subscriberIdHash, role]); const handleTokenRequest = async () => { try { diff --git a/src/pages/SignWithNitroKey.tsx b/src/pages/SignWithNitroKey.tsx index 9d48e1e..51b9754 100644 --- a/src/pages/SignWithNitroKey.tsx +++ b/src/pages/SignWithNitroKey.tsx @@ -68,8 +68,12 @@ const SignWithNitroKey = () => { }, }); } else { - const {kycIdHash} = location.state as { - kycIdHash?: string + const state = location.state as { + subscriberIdHash?: string + } + + if (!state.subscriberIdHash) { + throw new Error("Subscriber ID not found. Please verify your email and try again") } navigate("/sign-with-cosmos", { @@ -77,7 +81,7 @@ const SignWithNitroKey = () => { message, cosmosAddress, receivedEthSig, - kycIdHash, + subscriberIdHash: state.subscriberIdHash, }, }); } diff --git a/src/pages/Thanks.tsx b/src/pages/Thanks.tsx new file mode 100644 index 0000000..f8f6c3e --- /dev/null +++ b/src/pages/Thanks.tsx @@ -0,0 +1,73 @@ +import React, { useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { jwtDecode } from "jwt-decode"; +import { ethers } from 'ethers'; + +import { Box, colors, Typography } from '@mui/material'; + +interface JwtPayload { + subscriber_id: string; + exp: number; + iss: string; + iat: number; +} + +const Thanks: React.FC = () => { + const location = useLocation(); + const navigate = useNavigate(); + + const [err, setErr] = useState(); + + useEffect(() => { + const queryParams = new URLSearchParams(location.search); + const token = queryParams.get('jwt_token'); + + try { + if(!token){ + throw new Error("Invalid JWT Token") + } + + const decoded = jwtDecode(token) as JwtPayload; + const currentTime = Math.floor(Date.now() / 1000); + + if (!decoded.subscriber_id) { + throw new Error("Subscriber ID not found") + } + + if (decoded.exp < currentTime) { + throw new Error("Token has expired"); + } + + const uuidBuffer = Buffer.from(decoded.subscriber_id.replace(/-/g, ''), 'hex'); + + const subscriberIdHash = ethers.utils.sha256(uuidBuffer); + + navigate('/connect-wallet', { + state:{ + subscriberIdHash + } + }); + } catch (error) { + setErr(String(error)); + } + + }, [location.search, navigate]); + + return ( + + + {err ? err : "Loading..."} + + + ); +}; + +export default Thanks; diff --git a/src/pages/UserVerification.tsx b/src/pages/UserVerification.tsx index 659824f..31ffac7 100644 --- a/src/pages/UserVerification.tsx +++ b/src/pages/UserVerification.tsx @@ -50,7 +50,7 @@ const UserVerification = () => { message, cosmosAddress, receivedEthSig, - kycIdHash, + subscriberIdHash: kycIdHash, }}) } }, [applicationSubmitted, kycId, navigate, cosmosAddress, message, receivedEthSig]); diff --git a/src/pages/VerifyJWT.tsx b/src/pages/VerifyJWT.tsx deleted file mode 100644 index 94f01e9..0000000 --- a/src/pages/VerifyJWT.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; -import jwt from 'jsonwebtoken'; -import { sha256 } from 'ethers/lib/utils'; - -interface JwtPayload { - subscriber_id: string; - exp: number; - iss: string; - iat: number; -} -const VerifyJWTToken: React.FC = () => { - const location = useLocation(); - const navigate = useNavigate(); - - const [err, setErr] = useState(); - - useEffect(() => { - const queryParams = new URLSearchParams(location.search); - const token = queryParams.get('jwt_token'); - - if (token) { - try { - const decoded = jwt.decode(token) as JwtPayload; - const currentTime = Math.floor(Date.now() / 1000); - - if (decoded.exp < currentTime) { - throw new Error("Token has expired"); - } - - const kycIdHash = sha256(decoded.subscriber_id); - - navigate('/connect-wallet', { - state:{ - kycIdHash - } - }); - } catch (error) { - setErr(String(error)); - } - } - }, [location.search, navigate]); - - return (
{err ? err : "Loading..."}
); -}; - -export default VerifyJWTToken; diff --git a/yarn.lock b/yarn.lock index ea08ace..7733dc9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3453,13 +3453,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/jsonwebtoken@^9.0.6": - version "9.0.6" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz#d1af3544d99ad992fb6681bbe60676e06b032bd3" - integrity sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw== - dependencies: - "@types/node" "*" - "@types/long@^4.0.1": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" @@ -5047,11 +5040,6 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -6220,13 +6208,6 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -9036,22 +9017,6 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== -jsonwebtoken@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" - integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== - dependencies: - jws "^3.2.2" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - semver "^7.5.4" - "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -9067,22 +9032,10 @@ junk@3.1.0: resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" +jwt-decode@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" + integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== keccak@^3.0.0: version "3.0.4" @@ -9302,41 +9255,11 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== -lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== - -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== - lodash.isequal@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -9347,11 +9270,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" -- 2.45.2 From a63bbdd1c36ec49b2d7bd9821a6fa48de45b751a Mon Sep 17 00:00:00 2001 From: Shreerang Kale Date: Thu, 8 Aug 2024 15:31:14 +0530 Subject: [PATCH 5/5] Convert subscriber uuid to bytes --- src/pages/Email.tsx | 2 +- src/pages/Thanks.tsx | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/Email.tsx b/src/pages/Email.tsx index 039b74c..630145d 100644 --- a/src/pages/Email.tsx +++ b/src/pages/Email.tsx @@ -21,7 +21,7 @@ const Email = () => { > - Thank you for registering! + Thank you for registering! {REDIRECT_EMAIL_MSG} diff --git a/src/pages/Thanks.tsx b/src/pages/Thanks.tsx index f8f6c3e..c8a18f0 100644 --- a/src/pages/Thanks.tsx +++ b/src/pages/Thanks.tsx @@ -38,9 +38,8 @@ const Thanks: React.FC = () => { throw new Error("Token has expired"); } - const uuidBuffer = Buffer.from(decoded.subscriber_id.replace(/-/g, ''), 'hex'); - - const subscriberIdHash = ethers.utils.sha256(uuidBuffer); + const subscriberIdBytes = ethers.utils.toUtf8Bytes(decoded.subscriber_id) + const subscriberIdHash = ethers.utils.sha256(subscriberIdBytes); navigate('/connect-wallet', { state:{ -- 2.45.2