diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 47de55c414..0de1624f5a 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "1.18.15", + "@chainsafe/files-api-client": "^1.18.19", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", @@ -31,9 +31,9 @@ "ethers": "^5.4.3", "fflate": "^0.7.1", "formik": "^2.2.5", + "heic-convert": "^1.2.4", "jsrsasign": "^10.4.1", "key-encoder": "^2.0.3", - "heic-convert": "^1.2.4", "mime-matcher": "^1.0.5", "posthog-js": "^1.13.10", "react": "^16.14.0", diff --git a/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx b/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx index 8866079327..db09dd02e6 100644 --- a/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx +++ b/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx @@ -1,9 +1,9 @@ import React, { useCallback, useEffect, useMemo, useState } from "react" -import { Button, CheckCircleIcon, Loading, Typography, useHistory, useLocation } from "@chainsafe/common-components" +import { Button, CheckCircleIcon, ExclamationCircleIcon, Loading, Typography, useHistory, useLocation } from "@chainsafe/common-components" import { getBucketDecryptionFromHash, getJWT } from "../../Utils/pathUtils" import { useFilesApi } from "../../Contexts/FilesApiContext" import { useThresholdKey } from "../../Contexts/ThresholdKeyContext" -import { Trans } from "@lingui/macro" +import { t, Trans } from "@lingui/macro" import { useFiles } from "../../Contexts/FilesContext" import jwtDecode from "jwt-decode" import { createStyles, makeStyles } from "@chainsafe/common-theme" @@ -37,12 +37,11 @@ const useStyles = makeStyles( alignItems: "center", fontSize: constants.generalUnit * 6, "& svg": { - marginRight: constants.generalUnit, fill: palette.additional["gray"][7] } }, - error: { - color: palette.error.main + errorMessage: { + textAlign: "center" }, messageWrapper: { display: "flex", @@ -56,10 +55,12 @@ const useStyles = makeStyles( }) ) -interface DecodedJwt { +export interface DecodedNonceJwt { bucket_id?: string permission?: NonceResponsePermission + nonce_id?: string } + const LinkSharingModule = () => { const { pathname, hash } = useLocation() const { redirect } = useHistory() @@ -71,15 +72,27 @@ const LinkSharingModule = () => { const [encryptedEncryptionKey, setEncryptedEncryptionKey] = useState("") const [error, setError] = useState("") const classes = useStyles() - const { bucket_id: bucketId, permission } = useMemo(() => { + const { bucket_id: bucketId, permission, nonce_id } = useMemo(() => { try { - return (jwt && jwtDecode(jwt)) || {} + return (jwt && jwtDecode(jwt)) || {} }catch (e) { console.error(e) + setError(t`This link is marlformed. Please verify that you copy/pasted it correctly.`) return {} } }, [jwt]) const newBucket = useMemo(() => buckets.find((b) => b.id === bucketId), [bucketId, buckets]) + const [isValidNonce, setIsValidNonce] = useState() + + useEffect(() => { + if(!nonce_id) return + + filesApiClient.isNonceValid(nonce_id) + .then((res) => { + setIsValidNonce(res.is_valid) + }) + .catch(console.error) + }, [filesApiClient, nonce_id]) useEffect(() => { if(!publicKey || !bucketDecryptionKey) return @@ -91,7 +104,7 @@ const LinkSharingModule = () => { }, [bucketDecryptionKey, encryptForPublicKey, publicKey]) useEffect(() => { - if(!jwt || !encryptedEncryptionKey || !!newBucket) return + if(!jwt || !encryptedEncryptionKey || !!newBucket || !isValidNonce) return filesApiClient.verifyNonce({ jwt, encryption_key: encryptedEncryptionKey }) .catch((e:any) => { @@ -101,7 +114,7 @@ const LinkSharingModule = () => { .finally(() => { refreshBuckets() }) - }, [encryptedEncryptionKey, error, filesApiClient, jwt, newBucket, refreshBuckets]) + }, [encryptedEncryptionKey, error, filesApiClient, isValidNonce, jwt, newBucket, refreshBuckets]) const onBrowseBucket = useCallback(() => { newBucket && redirect(ROUTE_LINKS.SharedFolderExplorer(newBucket.id, "/")) @@ -111,25 +124,29 @@ const LinkSharingModule = () => {
- {!error && !newBucket && ( + {!error && !newBucket && isValidNonce !== false && ( <> - - Adding you to the shared folder... + + {isValidNonce === undefined + ? Verifying the link... + : Adding you to the shared folder... + } + )} - {!error && newBucket && permission && ( + {!error && newBucket && permission && isValidNonce && ( <> - + You were added to the shared folder ({translatedPermission(permission)}): {newBucket.name} @@ -142,15 +159,24 @@ const LinkSharingModule = () => { )} + {(!!error || isValidNonce === false) && ( + <> + + + { isValidNonce === false + ? This link is not valid any more. + : error + } + + + )}
- {!!error && ( - - {error} - - )}
) diff --git a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx index 5f012e2cdd..d8f8a5747b 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useState } from "react" +import React, { useCallback, useEffect, useMemo, useState } from "react" import { Button, GithubLogoIcon, @@ -8,7 +8,9 @@ import { Typography, FormikTextInput, EthereumLogoIcon, - useLocation + useLocation, + ExclamationCircleIcon, + useHistory } from "@chainsafe/common-components" import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" import { CSFTheme } from "../../../Themes/types" @@ -23,6 +25,9 @@ import { IdentityProvider } from "@chainsafe/files-api-client" import PasswordlessEmail from "./PasswordlessEmail" import { Form, FormikProvider, useFormik } from "formik" import { emailValidation } from "../../../Utils/validationSchema" +import { getJWT } from "../../../Utils/pathUtils" +import jwtDecode from "jwt-decode" +import { DecodedNonceJwt } from "../LinkSharingModule" import dayjs from "dayjs" const useStyles = makeStyles( @@ -148,6 +153,13 @@ const useStyles = makeStyles( secondaryLoginText: { paddingTop: constants.generalUnit * 2 }, + exclamationIcon: { + fontSize: 48, + "& svg": { + marginRight: constants.generalUnit, + fill: palette.additional["gray"][7] + } + }, maintenanceMessage: { display: "block", textAlign: "justify", @@ -184,6 +196,30 @@ const InitialScreen = ({ className }: IInitialScreen) => { const [email, setEmail] = useState("") const { state } = useLocation<{from?: string}>() const isSharing = useMemo(() => state?.from?.includes(LINK_SHARING_BASE), [state]) + const [isValidNonce, setIsValidNonce] = useState() + const { redirect } = useHistory() + + useEffect(() => { + if (!isSharing) return + + const jwt = getJWT(state?.from) + let nonce = "" + + try { + nonce = (jwt && jwtDecode(jwt).nonce_id) || "" + }catch (e) { + setError(t`The link you typed in looks malformed. Please verify it.`) + console.error(e) + } + + if (!nonce) return + + filesApiClient.isNonceValid(nonce) + .then((res) => { + setIsValidNonce(res.is_valid) + }) + .catch(console.error) + }, [filesApiClient, isSharing, state]) const handleSelectWalletAndConnect = async () => { setError(undefined) @@ -208,6 +244,7 @@ const InitialScreen = ({ className }: IInitialScreen) => { setErrorEmail("") setLoginMode(undefined) resetStatus() + setIsValidNonce(undefined) } const handleLogin = async (loginType: IdentityProvider) => { @@ -380,19 +417,21 @@ const InitialScreen = ({ className }: IInitialScreen) => { return (
- {loginMode !== "email" && ((desktop && !isConnecting && !error) || (isConnecting && loginMode !== "web3")) && ( + {isValidNonce !== false && + loginMode !== "email" && + ((desktop && !isConnecting && !error) || (isConnecting && loginMode !== "web3")) && ( - {isSharing + {isSharing && status !== "logging in" ? Sign in/up to access the shared folder : Get Started } )} - {!error && ( + {!error && isValidNonce !== false && ( loginMode !== "web3" && loginMode !== "email" ? <>
@@ -517,22 +556,40 @@ const InitialScreen = ({ className }: IInitialScreen) => { : )} {!!error && ( - <> -
- - Connection failed - - - {error} - - -
- +
+ + Connection failed + + + {error} + + +
+ )} + {isValidNonce === false && status !== "logging in" && ( +
+ + + This link is not valid any more. + + +
)}
) diff --git a/packages/files-ui/src/Utils/pathUtils.ts b/packages/files-ui/src/Utils/pathUtils.ts index 5f96cf6bae..0d01539479 100644 --- a/packages/files-ui/src/Utils/pathUtils.ts +++ b/packages/files-ui/src/Utils/pathUtils.ts @@ -104,7 +104,10 @@ export const isSubFolder = (fold1: string, fold2: string) => { } // get the jwt from /link-sharing/permision/jwt -export const getJWT = (pathname: string) => { +export const getJWT = (pathname?: string) => { + + if(!pathname) return + const arrayOfPaths = getArrayOfPaths(pathname) if(arrayOfPaths.length !== 3){ diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index 210107c5c1..ae8d0a5572 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -331,6 +331,9 @@ msgstr "" msgid "Go back" msgstr "Zurück" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "" @@ -721,6 +724,9 @@ msgstr "" msgid "The files are already in this folder" msgstr "" +msgid "The link you typed in looks malformed. Please verify it." +msgstr "" + msgid "The username is too long" msgstr "" @@ -754,6 +760,12 @@ msgstr "" msgid "There was an error when setting username." msgstr "" +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." +msgstr "" + msgid "This username is already taken" msgstr "" @@ -817,6 +829,9 @@ msgstr "Verifizierungscode nicht korrekt!" msgid "Verification code sent!" msgstr "Verifizierungscode gesendet!" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Ordner anzeigen" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index 9bcfa08156..f3418f7b1e 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -334,6 +334,9 @@ msgstr "Give view-only permission to:" msgid "Go back" msgstr "Go back" +msgid "Go to login" +msgstr "Go to login" + msgid "Got it" msgstr "Got it" @@ -724,6 +727,9 @@ msgstr "The authentication popup was closed" msgid "The files are already in this folder" msgstr "The files are already in this folder" +msgid "The link you typed in looks malformed. Please verify it." +msgstr "The link you typed in looks malformed. Please verify it." + msgid "The username is too long" msgstr "The username is too long" @@ -757,6 +763,12 @@ msgstr "There was an error restoring your data" msgid "There was an error when setting username." msgstr "There was an error when setting username." +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "This link is marlformed. Please verify that you copy/pasted it correctly." + +msgid "This link is not valid any more." +msgstr "This link is not valid any more." + msgid "This username is already taken" msgstr "This username is already taken" @@ -820,6 +832,9 @@ msgstr "Verification code not correct!" msgid "Verification code sent!" msgstr "Verification code sent!" +msgid "Verifying the link..." +msgstr "Verifying the link..." + msgid "View folder" msgstr "View folder" diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index 8cdcef38df..af6400960d 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -335,6 +335,9 @@ msgstr "" msgid "Go back" msgstr "Regresar" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "" @@ -725,6 +728,9 @@ msgstr "Se cerró la ventana emergente de autenticación" msgid "The files are already in this folder" msgstr "" +msgid "The link you typed in looks malformed. Please verify it." +msgstr "" + msgid "The username is too long" msgstr "" @@ -758,6 +764,12 @@ msgstr "" msgid "There was an error when setting username." msgstr "" +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." +msgstr "" + msgid "This username is already taken" msgstr "" @@ -821,6 +833,9 @@ msgstr "" msgid "Verification code sent!" msgstr "" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Utilice un navegador guardado" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index 48ae8ca63d..b6534b6db0 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -335,6 +335,9 @@ msgstr "Donner l’accès en lecture seule à :" msgid "Go back" msgstr "Retour" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "Compris" @@ -725,6 +728,9 @@ msgstr "Le popup d’authentification a été fermé" msgid "The files are already in this folder" msgstr "Les fichiers sont déjà dans ce dossier" +msgid "The link you typed in looks malformed. Please verify it." +msgstr "" + msgid "The username is too long" msgstr "Le nom d'utilisateur est trop long" @@ -758,6 +764,12 @@ msgstr "Une erreur s'est produite lors de la restauration de vos données" msgid "There was an error when setting username." msgstr "Une erreur s'est produite lors de la définition du nom d'utilisateur." +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." +msgstr "" + msgid "This username is already taken" msgstr "Ce nom d’utilisateur est déjà pris" @@ -821,6 +833,9 @@ msgstr "Code de vérification incorrect !" msgid "Verification code sent!" msgstr "Code de vérification envoyé !" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Voir le dossier" diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index f6be9aa5bc..c8fa17ce94 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -331,6 +331,9 @@ msgstr "" msgid "Go back" msgstr "Tilbake" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "" @@ -721,6 +724,9 @@ msgstr "" msgid "The files are already in this folder" msgstr "" +msgid "The link you typed in looks malformed. Please verify it." +msgstr "" + msgid "The username is too long" msgstr "" @@ -754,6 +760,12 @@ msgstr "" msgid "There was an error when setting username." msgstr "" +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." +msgstr "" + msgid "This username is already taken" msgstr "" @@ -817,6 +829,9 @@ msgstr "" msgid "Verification code sent!" msgstr "" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Vis mappe" diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json index 275518b256..bc30f7d52c 100644 --- a/packages/gaming-ui/package.json +++ b/packages/gaming-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "1.18.15", + "@chainsafe/files-api-client": "^1.18.19", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", diff --git a/packages/storage-ui/package.json b/packages/storage-ui/package.json index d55c71882d..a912064d6b 100644 --- a/packages/storage-ui/package.json +++ b/packages/storage-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "1.18.15", + "@chainsafe/files-api-client": "^1.18.19", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", diff --git a/yarn.lock b/yarn.lock index ab35e87884..e606cb7a0a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1925,10 +1925,10 @@ resolved "https://registry.yarnpkg.com/@chainsafe/browser-storage-hooks/-/browser-storage-hooks-1.0.1.tgz#26d32cde1999914db755a631e2643823c54959f7" integrity sha512-Q4b5gQAZnsRXKeADspd5isqfwwhhXjDk70y++YadufA6EZ3tf340oW0OVszp74KaGEw+CAYFGQR4X7bzpZ3x9Q== -"@chainsafe/files-api-client@1.18.15": - version "1.18.15" - resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.15.tgz#452572eb0ecb8178617d9faa37b7866bcfeeb4ec" - integrity sha512-W7MkZnK44dV1JixPavKKppi8KVhBk60uHoaDv/zRH0WVXT5QsWjQuCLpeWv9NcytHezsOv+5AAbovnjaZFwjpA== +"@chainsafe/files-api-client@^1.18.19": + version "1.18.19" + resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.19.tgz#2093d508d55b71abb3ec9cfb9c219fa62a4494c4" + integrity sha512-fFIGJg3XcS3hrNq4+UxjOEYYYiOtrYLTKxn0c/jXrlDFxA+Zjsn6G6d5O+KHJVfqoinRIyrRrMPXBHpBlFHpZg== dependencies: "@redocly/openapi-cli" "^1.0.0-beta.58" "@redocly/openapi-core" "^1.0.0-beta.58"