From f0b62c138f866e5d148df4e9129b7a5e5732d653 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Tue, 28 Sep 2021 18:05:12 +0200 Subject: [PATCH 01/15] wip --- .../Components/Modules/FileBrowsers/ShareModal.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index 7b7bc01bc5..9ab2cd92c1 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -14,6 +14,7 @@ import { useFileBrowser } from "../../../Contexts/FileBrowserContext" import clsx from "clsx" import { useEffect } from "react" import { nameValidator } from "../../../Utils/validationSchema" +import { useFilesApi } from "../../../Contexts/FilesApiContext" const useStyles = makeStyles( ({ breakpoints, constants, palette, typography, zIndex }: CSFTheme) => { @@ -198,6 +199,8 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { const { profile } = useUser() const [nameError, setNameError] = useState("") const inSharedBucket = useMemo(() => bucket?.type === "share", [bucket]) + const { filesApiClient } = useFilesApi() + const isReader = useMemo(() => { if (!bucket) return false @@ -301,6 +304,14 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { transferFileBetweenBuckets ]) + useEffect(() => { + filesApiClient.getAllNonces().then(n => console.log("nonces", n)).catch(console.error) + }, [filesApiClient]) + + const onSharingLink = useCallback(() => { + bucket?.id && filesApiClient.createNonce({ bucket_id: bucket.id, permission: "read" }).catch(console.error) + }, [bucket, filesApiClient]) + return ( {
+ {isUsingCurrentBucket ? (
From b07a4c27dbdb405b7033ce1d89a23e91c8d6d8e9 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Thu, 30 Sep 2021 14:56:53 +0200 Subject: [PATCH 02/15] add jose and some any on error --- packages/files-ui/package.json | 1 + packages/files-ui/src/Contexts/ThresholdKeyContext.tsx | 4 ++-- packages/files-ui/src/serviceWorker.ts | 2 +- packages/gaming-ui/src/serviceWorker.ts | 2 +- packages/storage-ui/src/serviceWorker.ts | 2 +- yarn.lock | 5 +++++ 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 1d9af5079a..763c1c5f1d 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -31,6 +31,7 @@ "ethers": "^5.4.3", "fflate": "^0.7.1", "formik": "^2.2.5", + "jose": "^3.19.0", "mime-matcher": "^1.0.5", "posthog-js": "^1.13.10", "react": "^16.14.0", diff --git a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx index 9ee4afe2fb..9259fe6413 100644 --- a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx +++ b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx @@ -246,7 +246,7 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f } else { setPrivateKey(privKeyString) } - } catch (error) { + } catch (error: any) { // Under certain circumstances (approval of login on another device) the metadata // cached may be stale, resulting in a failure to reconstruct the key. This is // identified through the nonce. Manually refreshing the metadata cache solves this problem @@ -781,7 +781,7 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f const newKeyDetails = await TKeySdk.getKeyDetails() setKeyDetails(newKeyDetails) return - } catch (error) { + } catch (error: any) { if (error.message.includes("nonce")) { await TKeySdk.updateMetadata() await TKeySdk.syncShareMetadata() diff --git a/packages/files-ui/src/serviceWorker.ts b/packages/files-ui/src/serviceWorker.ts index 8e951fbfee..8e879f512e 100644 --- a/packages/files-ui/src/serviceWorker.ts +++ b/packages/files-ui/src/serviceWorker.ts @@ -139,7 +139,7 @@ export function unregister() { .then(registration => { registration.unregister() }) - .catch(error => { + .catch((error: any) => { console.error(error.message) }) } diff --git a/packages/gaming-ui/src/serviceWorker.ts b/packages/gaming-ui/src/serviceWorker.ts index 8e951fbfee..8e879f512e 100644 --- a/packages/gaming-ui/src/serviceWorker.ts +++ b/packages/gaming-ui/src/serviceWorker.ts @@ -139,7 +139,7 @@ export function unregister() { .then(registration => { registration.unregister() }) - .catch(error => { + .catch((error: any) => { console.error(error.message) }) } diff --git a/packages/storage-ui/src/serviceWorker.ts b/packages/storage-ui/src/serviceWorker.ts index 8e951fbfee..8e879f512e 100644 --- a/packages/storage-ui/src/serviceWorker.ts +++ b/packages/storage-ui/src/serviceWorker.ts @@ -139,7 +139,7 @@ export function unregister() { .then(registration => { registration.unregister() }) - .catch(error => { + .catch((error: any) => { console.error(error.message) }) } diff --git a/yarn.lock b/yarn.lock index 5cad93d39a..02660d87d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15983,6 +15983,11 @@ jest@24.9.0: import-local "^2.0.0" jest-cli "^24.9.0" +jose@^3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/jose/-/jose-3.19.0.tgz#4b64c89b619d6256268865ed223c5228203d50df" + integrity sha512-G5imz/7oSe8Ohg4EMEhGhMhN+yzACMw7NC7ZrEYSoJekQXHPf+TPQNc/XJkYRm6TFWIbf3HA4OHZhdRv8KsskA== + js-levenshtein@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" From 8e8fcac38762acf7e40f537e419d0e0e2540c7c3 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Fri, 1 Oct 2021 14:29:19 +0200 Subject: [PATCH 03/15] with jsrsasign --- packages/files-ui/package.json | 3 +- .../Modules/FileBrowsers/ShareModal.tsx | 81 ++++++++++++++++++- .../src/Contexts/ThresholdKeyContext.tsx | 7 +- yarn.lock | 15 ++-- 4 files changed, 97 insertions(+), 9 deletions(-) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 763c1c5f1d..9c031c80df 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -31,7 +31,7 @@ "ethers": "^5.4.3", "fflate": "^0.7.1", "formik": "^2.2.5", - "jose": "^3.19.0", + "jsrsasign": "^10.4.1", "mime-matcher": "^1.0.5", "posthog-js": "^1.13.10", "react": "^16.14.0", @@ -62,6 +62,7 @@ "@testing-library/react": "^11.2.2", "@testing-library/user-event": "^12.5.0", "@types/jest": "^26.0.16", + "@types/jsrsasign": "^8.0.13", "@types/node": "^14.14.10", "@types/react": "^17.0.0", "@types/react-beforeunload": "^2.1.0", diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index 9ab2cd92c1..b65caf5687 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -15,6 +15,8 @@ import clsx from "clsx" import { useEffect } from "react" import { nameValidator } from "../../../Utils/validationSchema" import { useFilesApi } from "../../../Contexts/FilesApiContext" +import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" +import { KJUR } from "jsrsasign" const useStyles = makeStyles( ({ breakpoints, constants, palette, typography, zIndex }: CSFTheme) => { @@ -200,6 +202,7 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { const [nameError, setNameError] = useState("") const inSharedBucket = useMemo(() => bucket?.type === "share", [bucket]) const { filesApiClient } = useFilesApi() + const { privateKey } = useThresholdKey() const isReader = useMemo(() => { if (!bucket) return false @@ -308,10 +311,82 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { filesApiClient.getAllNonces().then(n => console.log("nonces", n)).catch(console.error) }, [filesApiClient]) - const onSharingLink = useCallback(() => { + const onCreateNonce = useCallback(() => { bucket?.id && filesApiClient.createNonce({ bucket_id: bucket.id, permission: "read" }).catch(console.error) }, [bucket, filesApiClient]) + const onCreateJWT = useCallback(async () => { + if(!privateKey) { + console.log("no private key found") + return + } + + // function arrayBufferToBase64(arrayBuffer: any) { + // const byteArray = new Uint8Array(arrayBuffer) + // let byteString = "" + // for(let i = 0; i < byteArray.byteLength; i++) { + // byteString += String.fromCharCode(byteArray[i]) + // } + // const b64 = window.btoa(byteString) + + // return b64 + // } + + function addNewLines(str: any) { + let finalString = "" + while(str.length > 0) { + finalString += str.substring(0, 64) + "\n" + str = str.substring(64) + } + + return finalString + } + + function toPem(privateKey: any) { + const b64 = addNewLines(window.btoa((privateKey))) + const pem = "-----BEGIN PRIVATE KEY-----\n" + b64 + "-----END PRIVATE KEY-----" + + return pem + } + + const pem = toPem(privateKey) + console.log("pem", pem) + + // using JOSE + // const algorithm = "ES256" + // const ecPrivateKey = await importPKCS8(pkcs8, algorithm) + // const jwt = await new SignJWT({ "urn:example:claim": true }) + // .setProtectedHeader({ alg: "ES256" }) + // .setIssuedAt() + // .setIssuer("urn:example:issuer") + // .setAudience("urn:example:audience") + // .setExpirationTime("2h") + // .sign(ecPrivateKey) + + // console.log("jwt", jwt) + + // Header + const oHeader = { alg: "ES256", typ: "JWT" } + // Payload + const oPayload: any = {} + const tNow = KJUR.jws.IntDate.get("now") + const tEnd = KJUR.jws.IntDate.get("now + 1day") + oPayload.iss = "http://foo.com" + oPayload.sub = "mailto:mike@foo.com" + oPayload.nbf = tNow + oPayload.iat = tNow + oPayload.exp = tEnd + oPayload.jti = "id123456" + oPayload.aud = "http://foo.com/employee" + // Sign JWT, password=616161 + const sHeader = JSON.stringify(oHeader) + const sPayload = JSON.stringify(oPayload) + // const prvKey = KEYUTIL.getKey(pkcs8) + + const sJWT = KJUR.jws.JWS.sign("ES256", sHeader, sPayload, pem) + console.log("sJWT", sJWT) + }, [privateKey]) + return ( {
- + + {isUsingCurrentBucket ? (
@@ -477,3 +553,4 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { } export default ShareModal + diff --git a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx index 9259fe6413..bf63c57a05 100644 --- a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx +++ b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx @@ -68,6 +68,8 @@ export type TThresholdKeyContext = { getAvailableShareIndices(): string[] | undefined refreshTKeyMeta(): Promise loggedinAs: string + //remove that privateKey + privateKey?: string } type ThresholdKeyProviderProps = { @@ -133,6 +135,8 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f () => TKeySdk?.modules[SECURITY_QUESTIONS_MODULE_NAME] as SecurityQuestionsModule | undefined , [TKeySdk] ) + + console.log("privateKey", privateKey) // `shares` object contains security question and local device shares // The service provider share as well as backup mnemonic do not appear in this share // array. Note: Files accounts have one service provider by default. @@ -828,7 +832,8 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f resetStatus: () => setStatus("initialized"), getAvailableShareIndices, refreshTKeyMeta, - loggedinAs + loggedinAs, + privateKey }} > {!isNewDevice && pendingShareTransferRequests.length > 0 && process.env.REACT_APP_TEST !== "true" && ( diff --git a/yarn.lock b/yarn.lock index 02660d87d1..e55c97b335 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5967,6 +5967,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/jsrsasign@^8.0.13": + version "8.0.13" + resolved "https://registry.yarnpkg.com/@types/jsrsasign/-/jsrsasign-8.0.13.tgz#770c1e429107dfb0cc4f5b78b472584511a55a28" + integrity sha512-+0Ij59D6NXP48KkeLhPXeQKOyLjvA9CD7zacc0Svy2IWHdl62BmDeTvGSIwKaGZSoamLJOo+on1AG/wPRLsd7A== + "@types/lodash@^4.14.165": version "4.14.165" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.165.tgz#74d55d947452e2de0742bad65270433b63a8c30f" @@ -15983,11 +15988,6 @@ jest@24.9.0: import-local "^2.0.0" jest-cli "^24.9.0" -jose@^3.19.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/jose/-/jose-3.19.0.tgz#4b64c89b619d6256268865ed223c5228203d50df" - integrity sha512-G5imz/7oSe8Ohg4EMEhGhMhN+yzACMw7NC7ZrEYSoJekQXHPf+TPQNc/XJkYRm6TFWIbf3HA4OHZhdRv8KsskA== - js-levenshtein@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" @@ -16273,6 +16273,11 @@ jsqr@^1.2.0: resolved "https://registry.yarnpkg.com/jsqr/-/jsqr-1.4.0.tgz#8efb8d0a7cc6863cb6d95116b9069123ce9eb2d1" integrity sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A== +jsrsasign@^10.4.1: + version "10.4.1" + resolved "https://registry.yarnpkg.com/jsrsasign/-/jsrsasign-10.4.1.tgz#3aec10b6201e3c321d4ee2b1e010bc2f808ed4d0" + integrity sha512-g2CP2nb8xKdmfZhuHaJEz1zVYTsZc+lUjLFvgbMX35/cUALK0G15sQfCbCpDg/UivkjCNlq0lV6FxCfPhv0shw== + jss-plugin-camel-case@^10.0.3: version "10.4.0" resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.4.0.tgz#46c75ff7fd61c304984c21af5817823f0f501ceb" From f73ece733ad65325c2b1cdf2274dcd26d9b29665 Mon Sep 17 00:00:00 2001 From: Michael Yankelev Date: Mon, 4 Oct 2021 15:27:50 +0200 Subject: [PATCH 04/15] convert raw to PEM --- packages/files-ui/package.json | 1 + .../Modules/FileBrowsers/ShareModal.tsx | 32 ++---------------- yarn.lock | 33 ++++++++++++++----- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 9c031c80df..84926e1e6a 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -32,6 +32,7 @@ "fflate": "^0.7.1", "formik": "^2.2.5", "jsrsasign": "^10.4.1", + "key-encoder": "^2.0.3", "mime-matcher": "^1.0.5", "posthog-js": "^1.13.10", "react": "^16.14.0", diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index b65caf5687..b54eb59fca 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -17,6 +17,7 @@ import { nameValidator } from "../../../Utils/validationSchema" import { useFilesApi } from "../../../Contexts/FilesApiContext" import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" import { KJUR } from "jsrsasign" +import keyEncoder from 'key-encoder' const useStyles = makeStyles( ({ breakpoints, constants, palette, typography, zIndex }: CSFTheme) => { @@ -321,35 +322,8 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { return } - // function arrayBufferToBase64(arrayBuffer: any) { - // const byteArray = new Uint8Array(arrayBuffer) - // let byteString = "" - // for(let i = 0; i < byteArray.byteLength; i++) { - // byteString += String.fromCharCode(byteArray[i]) - // } - // const b64 = window.btoa(byteString) - - // return b64 - // } - - function addNewLines(str: any) { - let finalString = "" - while(str.length > 0) { - finalString += str.substring(0, 64) + "\n" - str = str.substring(64) - } - - return finalString - } - - function toPem(privateKey: any) { - const b64 = addNewLines(window.btoa((privateKey))) - const pem = "-----BEGIN PRIVATE KEY-----\n" + b64 + "-----END PRIVATE KEY-----" - - return pem - } - - const pem = toPem(privateKey) + const ke = new keyEncoder('secp256k1') + const pem = ke.encodePrivate(privateKey, 'raw', 'pem') console.log("pem", pem) // using JOSE diff --git a/yarn.lock b/yarn.lock index e55c97b335..d0d02917be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5824,6 +5824,13 @@ dependencies: "@babel/types" "^7.3.0" +"@types/bn.js@*", "@types/bn.js@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" + integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== + dependencies: + "@types/node" "*" + "@types/bn.js@4.11.6", "@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" @@ -5831,13 +5838,6 @@ dependencies: "@types/node" "*" -"@types/bn.js@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -5850,6 +5850,13 @@ dependencies: "@types/node" "*" +"@types/elliptic@^6.4.9": + version "6.4.13" + resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.13.tgz#7e8ac814f748deb01a712e5147b128caf9dffa2d" + integrity sha512-e8iyLJ8vMLpWxXpVWrIt0ujqsfHWgVe5XAz9IMhBYoDirK6th7J+mHjzp797OLc62ZX419nrlwwzsNAA0a0mKg== + dependencies: + "@types/bn.js" "*" + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -7425,7 +7432,7 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= -asn1.js@^5.2.0: +asn1.js@^5.0.1, asn1.js@^5.2.0: version "5.4.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== @@ -16465,6 +16472,16 @@ keccak@^3.0.0: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" +key-encoder@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/key-encoder/-/key-encoder-2.0.3.tgz#77073bb48ff1fe2173bb2088b83b91152c8fa4ba" + integrity sha512-fgBtpAGIr/Fy5/+ZLQZIPPhsZEcbSlYu/Wu96tNDFNSjSACw5lEIOFeaVdQ/iwrb8oxjlWi6wmWdH76hV6GZjg== + dependencies: + "@types/elliptic" "^6.4.9" + asn1.js "^5.0.1" + bn.js "^4.11.8" + elliptic "^6.4.1" + keyvaluestorage-interface@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" From 1a5a3bf1d20cf0debfbe3bf3756508d207aceadf Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Tue, 5 Oct 2021 17:10:22 +0200 Subject: [PATCH 05/15] valid JWT --- .../Modules/FileBrowsers/ShareModal.tsx | 97 ++++++++++++------- 1 file changed, 64 insertions(+), 33 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index b54eb59fca..28c7f89849 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -17,7 +17,8 @@ import { nameValidator } from "../../../Utils/validationSchema" import { useFilesApi } from "../../../Contexts/FilesApiContext" import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" import { KJUR } from "jsrsasign" -import keyEncoder from 'key-encoder' +import keyEncoder from "key-encoder" +import { NonceResponse } from "@chainsafe/files-api-client" const useStyles = makeStyles( ({ breakpoints, constants, palette, typography, zIndex }: CSFTheme) => { @@ -204,6 +205,7 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { const inSharedBucket = useMemo(() => bucket?.type === "share", [bucket]) const { filesApiClient } = useFilesApi() const { privateKey } = useThresholdKey() + const [nonces, setNonces] = useState([]) const isReader = useMemo(() => { if (!bucket) return false @@ -309,11 +311,20 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { ]) useEffect(() => { - filesApiClient.getAllNonces().then(n => console.log("nonces", n)).catch(console.error) + filesApiClient.getAllNonces().then(setNonces).catch(console.error) }, [filesApiClient]) const onCreateNonce = useCallback(() => { - bucket?.id && filesApiClient.createNonce({ bucket_id: bucket.id, permission: "read" }).catch(console.error) + if(!bucket || bucket.type === "csf") { + console.log("no current bucket, or it's your home, which you can't share...") + return + } + + filesApiClient + .createNonce({ bucket_id: bucket.id, permission: "read" }) + // dirty hack + .then((n) => setNonces([n])) + .catch(console.error) }, [bucket, filesApiClient]) const onCreateJWT = useCallback(async () => { @@ -322,44 +333,63 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { return } - const ke = new keyEncoder('secp256k1') - const pem = ke.encodePrivate(privateKey, 'raw', 'pem') - console.log("pem", pem) + if(!nonces.length) { + console.log("no nonce created") + return + } - // using JOSE - // const algorithm = "ES256" - // const ecPrivateKey = await importPKCS8(pkcs8, algorithm) - // const jwt = await new SignJWT({ "urn:example:claim": true }) - // .setProtectedHeader({ alg: "ES256" }) - // .setIssuedAt() - // .setIssuer("urn:example:issuer") - // .setAudience("urn:example:audience") - // .setExpirationTime("2h") - // .sign(ecPrivateKey) + if(!bucket || bucket.type === "csf") { + console.log("no current bucket, or it's your home, which you can't share...") + return + } - // console.log("jwt", jwt) + const ke = new keyEncoder("secp256k1") + const pem = ke.encodePrivate(privateKey, "raw", "pem") // Header - const oHeader = { alg: "ES256", typ: "JWT" } + const header = { alg: "ES256", typ: "JWT" } // Payload - const oPayload: any = {} - const tNow = KJUR.jws.IntDate.get("now") - const tEnd = KJUR.jws.IntDate.get("now + 1day") - oPayload.iss = "http://foo.com" - oPayload.sub = "mailto:mike@foo.com" - oPayload.nbf = tNow - oPayload.iat = tNow - oPayload.exp = tEnd - oPayload.jti = "id123456" - oPayload.aud = "http://foo.com/employee" - // Sign JWT, password=616161 - const sHeader = JSON.stringify(oHeader) - const sPayload = JSON.stringify(oPayload) - // const prvKey = KEYUTIL.getKey(pkcs8) + const payload = { + type: "link_sharing", + permission: nonces[0].permission, + // oPayload.nbf = tNow, + iat: KJUR.jws.IntDate.get("now"), + // oPayload.exp = tEnd, + bucket_id: bucket.id, + nonce_id: nonces[0].id + } + // const tNow = KJUR.jws.IntDate.get("now") + // const tEnd = KJUR.jws.IntDate.get("now + 1day") + // oPayload.type = "link_sharing" + // oPayload.permission = nonces[0].permission + // // oPayload.nbf = tNow + // // oPayload.iat = tNow + // // oPayload.exp = tEnd + // oPayload.bucket_id = bucket.id + // oPayload.nonce_id = nonces[0].id + const sHeader = JSON.stringify(header) + const sPayload = JSON.stringify(payload) const sJWT = KJUR.jws.JWS.sign("ES256", sHeader, sPayload, pem) console.log("sJWT", sJWT) - }, [privateKey]) + }, [bucket, nonces, privateKey]) + + const onVerifyJWT = useCallback(() => { + if(!bucket || bucket.type === "csf") { + console.log("no current bucket, or it's your home, which you can't share...") + return + } + + filesApiClient + .verifyNonce({ + // eslint-disable-next-line max-len + jwt: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoibGlua19zaGFyaW5nIiwicGVybWlzc2lvbiI6InJlYWQiLCJpYXQiOjE2MzMzNjM1MjksImJ1Y2tldF9pZCI6ImU1YTk3ODJkLTI1ZTUtNDM4NS05NTcwLTlkYTJlZTZkNDY2MiIsIm5vbmNlX2lkIjoiNTkxYTZmNzEtZjQ5Yi00Mzg2LThlMTYtOTRiY2JiMDAyYWNmIn0.SC_0SzGEihJYJZKZT3AqrOiWEn5NXAJaI3446CgaNC-ZSAB3p3OpJIWe56_TjclKD9db-wvWBFkh1coVtI26xw", + encryption_key: "someEncryptedEncryptionKey" + }) + // dirty hack + .then(console.log) + .catch(console.error) + }, [bucket, filesApiClient]) return ( {
+ {isUsingCurrentBucket ? (
From f50bd0a91c74d2f25326c83315eb8e6bd534eb28 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Thu, 7 Oct 2021 11:04:11 +0200 Subject: [PATCH 06/15] wrap up link overview --- packages/files-ui/package.json | 2 +- .../CreateOrEditSharedFolderModal.tsx | 18 ++ .../FileBrowsers/LinkSharing/LinkList.tsx | 180 ++++++++++++++++++ .../FileBrowsers/LinkSharing/SharingLink.tsx | 148 ++++++++++++++ .../Modules/FileBrowsers/ShareModal.tsx | 93 --------- .../src/Contexts/ThresholdKeyContext.tsx | 37 +++- packages/gaming-ui/package.json | 2 +- packages/storage-ui/package.json | 2 +- yarn.lock | 17 +- 9 files changed, 386 insertions(+), 113 deletions(-) create mode 100644 packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx create mode 100644 packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 287b9927ab..03156f78fc 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.11", + "@chainsafe/files-api-client": "^1.18.12", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx index ebbcd313d0..29f679c855 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx @@ -12,6 +12,8 @@ import { useCreateOrEditSharedFolder } from "./hooks/useCreateOrEditSharedFolder import { useLookupSharedFolderUser } from "./hooks/useLookupUser" import { nameValidator } from "../../../Utils/validationSchema" import { getUserDisplayName } from "../../../Utils/getUserDisplayName" +import LinkList from "./LinkSharing/LinkList" +import clsx from "clsx" const useStyles = makeStyles( ({ breakpoints, constants, typography, zIndex, palette }: CSFTheme) => { @@ -102,6 +104,9 @@ const useStyles = makeStyles( errorText: { marginLeft: constants.generalUnit * 1.5, color: palette.error.main + }, + sharingLink: { + padding: 10 } }) } @@ -186,6 +191,8 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi .finally(handleClose) }, [handleEditSharedFolder, sharedFolderWriters, sharedFolderReaders, handleClose, bucketToEdit]) + if (!bucketToEdit) return null + return (
+ {mode === "edit" && ( +
+ + Sharing link + + +
+ )} { + return createStyles({ + root: { + + }, + options: { + backgroundColor: constants.header.optionsBackground, + color: constants.header.optionsTextColor, + border: `1px solid ${constants.header.optionsBorder}`, + minWidth: 145 + }, + menuItem: { + width: "100%", + display: "flex", + flexDirection: "row", + alignItems: "center", + color: constants.header.menuItemTextColor, + "& svg": { + width: constants.generalUnit * 2, + height: constants.generalUnit * 2, + marginRight: constants.generalUnit, + fill: palette.additional["gray"][7], + stroke: palette.additional["gray"][7] + } + }, + icon: { + "& svg": { + fill: constants.header.iconColor + } + }, + menuIcon: { + display: "flex", + justifyContent: "center", + alignItems: "center", + width: 20, + marginRight: constants.generalUnit * 1.5, + fill: constants.fileSystemItemRow.menuIcon + }, + permissionDropdown: { + padding: `0px ${constants.generalUnit}px`, + backgroundColor: palette.additional["gray"][5], + marginLeft: constants.generalUnit + }, + createLink: { + display: "flex", + alignItems: "center", + margin: `${constants.generalUnit * 2.5}px 0` + }, + createLinkButton: { + marginRight: constants.generalUnit + }, + dropdownTitle: { + padding: "6px 8px" + } + }) + } +) + +interface Props { + bucketId: string + bucketEncryptionKey: string +} + +export const readMenu = t`read rights` +export const editMenu = t`edit rights` + + +const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { + const classes = useStyles() + const { filesApiClient } = useFilesApi() + const [nonces, setNonces] = useState([]) + const [isLoading, setIsLoading] = useState(false) + const [newLinkPermission, setNewLinkPermission] = useState("read") + + const refreshNonces = useCallback(() => { + setIsLoading(true) + filesApiClient.getAllNonces() + .then((res) => { + const noncesForCurrentBucket = res.filter(n => n.bucket_id === bucketId) + setNonces(noncesForCurrentBucket) + }) + .catch(console.error) + .finally(() => setIsLoading(false)) + }, [bucketId, filesApiClient]) + + useEffect(() => { + refreshNonces() + }, [filesApiClient, refreshNonces]) + + const onCreateNonce = useCallback(() => { + + setIsLoading(true) + + return filesApiClient + .createNonce({ bucket_id: bucketId, permission: newLinkPermission }) + .then((n) => { + setNonces((olderNonces) => [...olderNonces, n]) + }) + .catch(console.error) + .finally(() => setIsLoading(false)) + }, [bucketId, filesApiClient, newLinkPermission]) + + return ( +
+
+ + with + setNewLinkPermission("read"), + contents: ( +
+ {readMenu} +
+ ) + }, + { + onClick: () => setNewLinkPermission("write"), + contents: ( +
+ {editMenu} +
+ ) + } + ]} + /> +
+ { + nonces.length > 0 && nonces.map((nonce) => + + ) + } + +
+ ) +} + +export default LinkList diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx new file mode 100644 index 0000000000..6ee1e0a9a9 --- /dev/null +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx @@ -0,0 +1,148 @@ + +import { Button, DeleteSvg, Typography } from "@chainsafe/common-components" +import { createStyles, debounce, makeStyles } from "@chainsafe/common-theme" +import { NonceResponse } from "@chainsafe/files-api-client" +import { Trans } from "@lingui/macro" +import React, { useCallback, useEffect, useMemo, useState } from "react" +import { useFilesApi } from "../../../../Contexts/FilesApiContext" +import { useThresholdKey } from "../../../../Contexts/ThresholdKeyContext" +import { CSFTheme } from "../../../../Themes/types" +import { editMenu, readMenu } from "./LinkList" + +const useStyles = makeStyles( + ({ constants }: CSFTheme) => { + return createStyles({ + root: { + display: "flex", + marginBottom: constants.generalUnit * 0.5 + }, + linkWrapper: { + whiteSpace: "nowrap", + marginRight: constants.generalUnit * 2, + display: "flex", + alignItems: "center", + overflow: "hidden" + }, + permissionWrapper: { + display: "flex", + alignItems: "center", + marginRight: constants.generalUnit, + flex: 1, + whiteSpace: "nowrap" + }, + copyButton: { + flex: 1, + whiteSpace: "nowrap", + marginRight: constants.generalUnit + }, + link: { + textOverflow: "ellipsis", + overflow: "hidden" + }, + menuIcon: { + display: "flex", + justifyContent: "center", + alignItems: "center", + width: 20, + marginRight: constants.generalUnit * 1.5, + fill: constants.fileSystemItemRow.menuIcon + } + }) + } +) + +interface Props { + nonce: NonceResponse + bucketEncryptionKey: string + refreshNonces: () => void +} + +const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { + const classes = useStyles() + const { filesApiClient } = useFilesApi() + const [link, setLink] = useState("") + const [jwt, setJwt] = useState("") + const { createJWT } = useThresholdKey() + const [copied, setCopied] = useState(false) + const linkPermission = useMemo(() => nonce.permission === "read" ? "read" : "edit", [nonce.permission]) + const [isLoading, setIsLoading] = useState(true) + + useEffect(() => { + if(!nonce?.bucket_id || !nonce?.id) { + return + } + + const newJwt = createJWT(nonce.bucket_id, nonce.id, nonce.permission) + newJwt && setJwt(newJwt) + setIsLoading(false) + }, [createJWT, nonce]) + + useEffect(() => { + if(!jwt) { + return + } + + // eslint-disable-next-line max-len + setLink(`${window.location.origin}/sharing-link/${linkPermission}/${encodeURIComponent(jwt)}#${encodeURIComponent(bucketEncryptionKey)}`) + }, [jwt, bucketEncryptionKey, linkPermission]) + + + + const debouncedSwitchCopied = debounce(() => setCopied(false), 3000) + + const onCopyInfo = useCallback(() => { + navigator.clipboard.writeText(link) + .then(() => { + setCopied(true) + debouncedSwitchCopied() + }) + .catch(console.error) + }, [debouncedSwitchCopied, link]) + + const onDeleteNonce = useCallback(() => { + setIsLoading(true) + filesApiClient.revokeNonce(nonce.id) + .catch(console.error) + .finally(() => { + refreshNonces() + setIsLoading(true) + }) + }, [filesApiClient, nonce, refreshNonces]) + + return ( +
+
+ + {link} + +
+
+ + {nonce.permission === "read" ? readMenu : editMenu} + +
+ + +
+ ) +} + +export default SharingLink diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index 28c7f89849..018bab640b 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -14,11 +14,6 @@ import { useFileBrowser } from "../../../Contexts/FileBrowserContext" import clsx from "clsx" import { useEffect } from "react" import { nameValidator } from "../../../Utils/validationSchema" -import { useFilesApi } from "../../../Contexts/FilesApiContext" -import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" -import { KJUR } from "jsrsasign" -import keyEncoder from "key-encoder" -import { NonceResponse } from "@chainsafe/files-api-client" const useStyles = makeStyles( ({ breakpoints, constants, palette, typography, zIndex }: CSFTheme) => { @@ -203,9 +198,6 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { const { profile } = useUser() const [nameError, setNameError] = useState("") const inSharedBucket = useMemo(() => bucket?.type === "share", [bucket]) - const { filesApiClient } = useFilesApi() - const { privateKey } = useThresholdKey() - const [nonces, setNonces] = useState([]) const isReader = useMemo(() => { if (!bucket) return false @@ -310,87 +302,6 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { transferFileBetweenBuckets ]) - useEffect(() => { - filesApiClient.getAllNonces().then(setNonces).catch(console.error) - }, [filesApiClient]) - - const onCreateNonce = useCallback(() => { - if(!bucket || bucket.type === "csf") { - console.log("no current bucket, or it's your home, which you can't share...") - return - } - - filesApiClient - .createNonce({ bucket_id: bucket.id, permission: "read" }) - // dirty hack - .then((n) => setNonces([n])) - .catch(console.error) - }, [bucket, filesApiClient]) - - const onCreateJWT = useCallback(async () => { - if(!privateKey) { - console.log("no private key found") - return - } - - if(!nonces.length) { - console.log("no nonce created") - return - } - - if(!bucket || bucket.type === "csf") { - console.log("no current bucket, or it's your home, which you can't share...") - return - } - - const ke = new keyEncoder("secp256k1") - const pem = ke.encodePrivate(privateKey, "raw", "pem") - - // Header - const header = { alg: "ES256", typ: "JWT" } - // Payload - const payload = { - type: "link_sharing", - permission: nonces[0].permission, - // oPayload.nbf = tNow, - iat: KJUR.jws.IntDate.get("now"), - // oPayload.exp = tEnd, - bucket_id: bucket.id, - nonce_id: nonces[0].id - } - // const tNow = KJUR.jws.IntDate.get("now") - // const tEnd = KJUR.jws.IntDate.get("now + 1day") - // oPayload.type = "link_sharing" - // oPayload.permission = nonces[0].permission - // // oPayload.nbf = tNow - // // oPayload.iat = tNow - // // oPayload.exp = tEnd - // oPayload.bucket_id = bucket.id - // oPayload.nonce_id = nonces[0].id - const sHeader = JSON.stringify(header) - const sPayload = JSON.stringify(payload) - - const sJWT = KJUR.jws.JWS.sign("ES256", sHeader, sPayload, pem) - console.log("sJWT", sJWT) - }, [bucket, nonces, privateKey]) - - const onVerifyJWT = useCallback(() => { - if(!bucket || bucket.type === "csf") { - console.log("no current bucket, or it's your home, which you can't share...") - return - } - - filesApiClient - .verifyNonce({ - // eslint-disable-next-line max-len - jwt: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoibGlua19zaGFyaW5nIiwicGVybWlzc2lvbiI6InJlYWQiLCJpYXQiOjE2MzMzNjM1MjksImJ1Y2tldF9pZCI6ImU1YTk3ODJkLTI1ZTUtNDM4NS05NTcwLTlkYTJlZTZkNDY2MiIsIm5vbmNlX2lkIjoiNTkxYTZmNzEtZjQ5Yi00Mzg2LThlMTYtOTRiY2JiMDAyYWNmIn0.SC_0SzGEihJYJZKZT3AqrOiWEn5NXAJaI3446CgaNC-ZSAB3p3OpJIWe56_TjclKD9db-wvWBFkh1coVtI26xw", - encryption_key: "someEncryptedEncryptionKey" - }) - // dirty hack - .then(console.log) - .catch(console.error) - }, [bucket, filesApiClient]) - return ( { }
-
- - - {isUsingCurrentBucket ? (
diff --git a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx index bf63c57a05..cec8ae68ae 100644 --- a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx +++ b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx @@ -15,12 +15,14 @@ import EthCrypto from "eth-crypto" import { useWeb3 } from "@chainsafe/web3-context" import ShareTransferRequestModal from "../Components/Elements/ShareTransferRequestModal" import BN from "bn.js" -import { IdentityProvider } from "@chainsafe/files-api-client" +import { IdentityProvider, NonceResponsePermission } from "@chainsafe/files-api-client" import { capitalize, centerEllipsis } from "../Utils/Helpers" import { t } from "@lingui/macro" import jwtDecode from "jwt-decode" import { IdentityToken } from "@chainsafe/files-api-client" import dayjs from "dayjs" +import keyEncoder from "key-encoder" +import { KJUR } from "jsrsasign" const TORUS_POSTBOX_KEY = "csf.postboxKey" const TKEY_STORE_KEY = "csf.tkeyStore" @@ -68,8 +70,7 @@ export type TThresholdKeyContext = { getAvailableShareIndices(): string[] | undefined refreshTKeyMeta(): Promise loggedinAs: string - //remove that privateKey - privateKey?: string + createJWT: (bucketId: string, nonceId: string, nonce: NonceResponsePermission) => string | undefined } type ThresholdKeyProviderProps = { @@ -400,6 +401,34 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f } }, [userInfo, address]) + const createJWT = useCallback((bucketId: string, nonceId: string, permission: NonceResponsePermission) => { + + if(!privateKey) { + console.log("no private key found") + return + } + + const ke = new keyEncoder("secp256k1") + const pem = ke.encodePrivate(privateKey, "raw", "pem") + + + const header = { alg: "ES256", typ: "JWT" } + + const payload = { + type: "link_sharing", + permission, + iat: KJUR.jws.IntDate.get("now"), + bucket_id: bucketId, + nonce_id: nonceId + } + + const sHeader = JSON.stringify(header) + const sPayload = JSON.stringify(payload) + + const sJWT = KJUR.jws.JWS.sign("ES256", sHeader, sPayload, pem) + return sJWT + }, [privateKey]) + const login = async (loginType: IdentityProvider, tokenInfo?: {token: string; email: string}) => { if (!TKeySdk || maintenanceMode) return try { @@ -833,7 +862,7 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f getAvailableShareIndices, refreshTKeyMeta, loggedinAs, - privateKey + createJWT }} > {!isNewDevice && pendingShareTransferRequests.length > 0 && process.env.REACT_APP_TEST !== "true" && ( diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json index 3ed9f2799d..e20a33991c 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.10", + "@chainsafe/files-api-client": "^1.18.12", "@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 9c5e863db4..59009b7207 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.10", + "@chainsafe/files-api-client": "^1.18.12", "@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 3bd05ee3ac..e46f901d58 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1925,19 +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.10": - version "1.18.10" - resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.10.tgz#a359f0d40916afec41ea7ffc8aa4ffc505c25c17" - integrity sha512-Rpuk7jDF0cFg53xIrfHsp20aA37QwYd/WDv28JjlhpBI9egbk6oTgVuB9LEiR9mYWb65CIXxfxGvc6WmE3DWTw== - dependencies: - "@redocly/openapi-cli" "^1.0.0-beta.58" - "@redocly/openapi-core" "^1.0.0-beta.58" - redoc-cli "^0.12.3" - -"@chainsafe/files-api-client@^1.18.11": - version "1.18.11" - resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.11.tgz#82f0d0b6848833680e5c6b6721b602f963d9c4d4" - integrity sha512-hH5B0hh3E7Ot1+uXwrId3ofsSOC8OQKcHTDkmhlVsSOG0etJLBV13w615LKGK3enabHbWV/xBhhP5rym9Hma+g== +"@chainsafe/files-api-client@^1.18.12": + version "1.18.12" + resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.12.tgz#cd5d1d6921b7a2ffdd22c2700f77e68eb926e4df" + integrity sha512-EdwUnc4FT/1QdYzOnf2KyFV5I2iOP034HwuPDDLqXoiUidZYpkaEpFEBiIbjh6tX1iUHq551egfxXJQIp73KAg== dependencies: "@redocly/openapi-cli" "^1.0.0-beta.58" "@redocly/openapi-core" "^1.0.0-beta.58" From 8a1f07190c5c93b085b9cd326c8b0c4ec40a00b1 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 7 Oct 2021 09:09:27 +0000 Subject: [PATCH 07/15] lingui extract --- packages/files-ui/src/locales/de/messages.po | 18 ++++++++++++++++++ packages/files-ui/src/locales/en/messages.po | 18 ++++++++++++++++++ packages/files-ui/src/locales/es/messages.po | 18 ++++++++++++++++++ packages/files-ui/src/locales/fr/messages.po | 18 ++++++++++++++++++ packages/files-ui/src/locales/no/messages.po | 18 ++++++++++++++++++ 5 files changed, 90 insertions(+) diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index 970092fccb..44d2db3f08 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -136,6 +136,9 @@ msgstr "" msgid "Copy info" msgstr "" +msgid "Copy link" +msgstr "" + msgid "Copy over" msgstr "" @@ -160,6 +163,9 @@ msgstr "" msgid "Create folder" msgstr "Ordner erstellen" +msgid "Create new link" +msgstr "" + msgid "Create your public username in <0>Settings!" msgstr "" @@ -634,6 +640,9 @@ msgstr "" msgid "Sharing cancelled" msgstr "" +msgid "Sharing link" +msgstr "" + msgid "Sharing your file (Downloading)" msgstr "" @@ -844,15 +853,24 @@ msgstr "" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Ihr Wiederherstellungsschlüssel kann zur Wiederherstellung Ihres Kontos anstelle Ihres Sicherungsgeheimsatz verwendet werden." +msgid "edit rights" +msgstr "" + msgid "me" msgstr "ich" msgid "on" msgstr "am" +msgid "read rights" +msgstr "" + msgid "unknown" msgstr "unbekannt" +msgid "with" +msgstr "" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "{0, plural, one {{1} Datei wird heruntergeladen} other {{2} Dateien werden heruntergeladen}}" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index 75382d9e7c..b658c868ca 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -136,6 +136,9 @@ msgstr "Copy file" msgid "Copy info" msgstr "Copy info" +msgid "Copy link" +msgstr "Copy link" + msgid "Copy over" msgstr "Copy over" @@ -160,6 +163,9 @@ msgstr "Create a new shared folder" msgid "Create folder" msgstr "Create folder" +msgid "Create new link" +msgstr "Create new link" + msgid "Create your public username in <0>Settings!" msgstr "Create your public username in <0>Settings!" @@ -637,6 +643,9 @@ msgstr "Shared with" msgid "Sharing cancelled" msgstr "Sharing cancelled" +msgid "Sharing link" +msgstr "Sharing link" + msgid "Sharing your file (Downloading)" msgstr "Sharing your file (Downloading)" @@ -847,15 +856,24 @@ msgstr "You will need to sign a message in your wallet to complete sign in." msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Your recovery key can be used to restore your account in place of your backup secret phrase." +msgid "edit rights" +msgstr "edit rights" + msgid "me" msgstr "me" msgid "on" msgstr "on" +msgid "read rights" +msgstr "read rights" + msgid "unknown" msgstr "unknown" +msgid "with" +msgstr "with" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index 7ab4a55118..694c51a71a 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -137,6 +137,9 @@ msgstr "" msgid "Copy info" msgstr "" +msgid "Copy link" +msgstr "" + msgid "Copy over" msgstr "" @@ -161,6 +164,9 @@ msgstr "" msgid "Create folder" msgstr "Crear Carpeta" +msgid "Create new link" +msgstr "" + msgid "Create your public username in <0>Settings!" msgstr "" @@ -638,6 +644,9 @@ msgstr "" msgid "Sharing cancelled" msgstr "" +msgid "Sharing link" +msgstr "" + msgid "Sharing your file (Downloading)" msgstr "" @@ -848,15 +857,24 @@ msgstr "Deberá firmar un mensaje en su billetera para completar el inicio de se msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "" +msgid "edit rights" +msgstr "" + msgid "me" msgstr "" msgid "on" msgstr "en" +msgid "read rights" +msgstr "" + msgid "unknown" msgstr "" +msgid "with" +msgstr "" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index 093efb96eb..cf5216a1be 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -137,6 +137,9 @@ msgstr "Copier le fichier" msgid "Copy info" msgstr "Copier les infos" +msgid "Copy link" +msgstr "" + msgid "Copy over" msgstr "Copier" @@ -161,6 +164,9 @@ msgstr "Créer un nouveau dossier partagé" msgid "Create folder" msgstr "Créer un dossier" +msgid "Create new link" +msgstr "" + msgid "Create your public username in <0>Settings!" msgstr "Créez votre nom d'utilisateur public dans <0>Paramètres !" @@ -638,6 +644,9 @@ msgstr "Partagé avec" msgid "Sharing cancelled" msgstr "Partage annulé" +msgid "Sharing link" +msgstr "" + msgid "Sharing your file (Downloading)" msgstr "Partager votre fichier (Téléchargement)" @@ -848,15 +857,24 @@ msgstr "Vous devrez signer un message avec votre wallet pour terminer la procéd msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Votre clé de récupération peut être utilisée pour restaurer votre compte à la place de votre phrase de sauvegarde secrète." +msgid "edit rights" +msgstr "" + msgid "me" msgstr "moi" msgid "on" msgstr "le" +msgid "read rights" +msgstr "" + msgid "unknown" msgstr "inconnu" +msgid "with" +msgstr "" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "{0, plural, one {Téléchargement de {1} fichier} other {Téléchargement de {2} fichiers}}" diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index ccea7566f2..f59e518022 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -136,6 +136,9 @@ msgstr "" msgid "Copy info" msgstr "" +msgid "Copy link" +msgstr "" + msgid "Copy over" msgstr "" @@ -160,6 +163,9 @@ msgstr "" msgid "Create folder" msgstr "Opprett mappe" +msgid "Create new link" +msgstr "" + msgid "Create your public username in <0>Settings!" msgstr "" @@ -634,6 +640,9 @@ msgstr "" msgid "Sharing cancelled" msgstr "" +msgid "Sharing link" +msgstr "" + msgid "Sharing your file (Downloading)" msgstr "" @@ -844,15 +853,24 @@ msgstr "" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "" +msgid "edit rights" +msgstr "" + msgid "me" msgstr "" msgid "on" msgstr "" +msgid "read rights" +msgstr "" + msgid "unknown" msgstr "" +msgid "with" +msgstr "" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "" From 7c8fec857cfcb1d2dbb614e76f8dbd698b5c8adb Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Thu, 7 Oct 2021 11:16:59 +0200 Subject: [PATCH 08/15] Apply suggestions from code review --- .../src/Components/Modules/FileBrowsers/ShareModal.tsx | 1 - packages/files-ui/src/Contexts/ThresholdKeyContext.tsx | 5 ----- 2 files changed, 6 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index 018bab640b..701e5880a4 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -198,7 +198,6 @@ const ShareModal = ({ close, file, filePath }: IShareFileProps) => { const { profile } = useUser() const [nameError, setNameError] = useState("") const inSharedBucket = useMemo(() => bucket?.type === "share", [bucket]) - const isReader = useMemo(() => { if (!bucket) return false diff --git a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx index cec8ae68ae..7bf9776a38 100644 --- a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx +++ b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx @@ -136,8 +136,6 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f () => TKeySdk?.modules[SECURITY_QUESTIONS_MODULE_NAME] as SecurityQuestionsModule | undefined , [TKeySdk] ) - - console.log("privateKey", privateKey) // `shares` object contains security question and local device shares // The service provider share as well as backup mnemonic do not appear in this share // array. Note: Files accounts have one service provider by default. @@ -410,10 +408,7 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f const ke = new keyEncoder("secp256k1") const pem = ke.encodePrivate(privateKey, "raw", "pem") - - const header = { alg: "ES256", typ: "JWT" } - const payload = { type: "link_sharing", permission, From 47360dbf2c0bd0bfb21f5acfc80f7869d119736d Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Thu, 7 Oct 2021 11:29:16 +0200 Subject: [PATCH 09/15] generic link --- packages/files-ui/src/Components/FilesRoutes.tsx | 5 +++++ .../Modules/FileBrowsers/LinkSharing/SharingLink.tsx | 9 ++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/files-ui/src/Components/FilesRoutes.tsx b/packages/files-ui/src/Components/FilesRoutes.tsx index 74b404c6fa..e98356933c 100644 --- a/packages/files-ui/src/Components/FilesRoutes.tsx +++ b/packages/files-ui/src/Components/FilesRoutes.tsx @@ -10,6 +10,7 @@ import PurchasePlanPage from "./Pages/PurchasePlanPage" import { useThresholdKey } from "../Contexts/ThresholdKeyContext" import ShareFilesPage from "./Pages/SharedFilesPage" import SharedFoldersOverview from "./Modules/FileBrowsers/SharedFoldersOverview" +import { NonceResponsePermission } from "@chainsafe/files-api-client" export const SETTINGS_BASE = "/settings" export const ROUTE_LINKS = { @@ -27,6 +28,9 @@ export const ROUTE_LINKS = { UserSurvey: "https://calendly.com/colinschwarz/chainsafe-files-chat", SharedFolders: "/shared-overview", SharedFolderBrowserRoot: "/shared", + SharingLink: (permission: NonceResponsePermission, jwt: string, bucketEncryptionKey: string) => + // eslint-disable-next-line max-len + `${window.location.origin}/sharing-link/${permissionPath(permission)}/${encodeURIComponent(jwt)}#${encodeURIComponent(bucketEncryptionKey)}`, SharedFolderExplorer: (bucketId: string, rawCurrentPath: string) => { // bucketId should not have a / at the end // rawCurrentPath can be empty, or / @@ -37,6 +41,7 @@ export const ROUTE_LINKS = { TeamSignup: "https://shrl.ink/cgQy" } +export const permissionPath = (permission: NonceResponsePermission) => permission === "read" ? "read" : "edit" export const SETTINGS_PATHS = ["profile", "plan", "security"] as const export type SettingsPath = typeof SETTINGS_PATHS[number] diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx index 6ee1e0a9a9..a1f5bde137 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx @@ -3,10 +3,11 @@ import { Button, DeleteSvg, Typography } from "@chainsafe/common-components" import { createStyles, debounce, makeStyles } from "@chainsafe/common-theme" import { NonceResponse } from "@chainsafe/files-api-client" import { Trans } from "@lingui/macro" -import React, { useCallback, useEffect, useMemo, useState } from "react" +import React, { useCallback, useEffect, useState } from "react" import { useFilesApi } from "../../../../Contexts/FilesApiContext" import { useThresholdKey } from "../../../../Contexts/ThresholdKeyContext" import { CSFTheme } from "../../../../Themes/types" +import { ROUTE_LINKS } from "../../../FilesRoutes" import { editMenu, readMenu } from "./LinkList" const useStyles = makeStyles( @@ -64,7 +65,6 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { const [jwt, setJwt] = useState("") const { createJWT } = useThresholdKey() const [copied, setCopied] = useState(false) - const linkPermission = useMemo(() => nonce.permission === "read" ? "read" : "edit", [nonce.permission]) const [isLoading, setIsLoading] = useState(true) useEffect(() => { @@ -82,9 +82,8 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { return } - // eslint-disable-next-line max-len - setLink(`${window.location.origin}/sharing-link/${linkPermission}/${encodeURIComponent(jwt)}#${encodeURIComponent(bucketEncryptionKey)}`) - }, [jwt, bucketEncryptionKey, linkPermission]) + setLink(ROUTE_LINKS.SharingLink(nonce.permission, jwt, bucketEncryptionKey)) + }, [jwt, bucketEncryptionKey, nonce]) From 5ba3be50ce676a0f5aaa67b62c6eeeb13a862e7a Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Fri, 8 Oct 2021 17:00:10 +0200 Subject: [PATCH 10/15] git add fix shared folder creation --- .../Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx | 4 +--- .../Components/Modules/FileBrowsers/SharedFoldersOverview.tsx | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx index 29f679c855..c7ceacaf7b 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx @@ -191,8 +191,6 @@ const CreateOrEditSharedFolderModal = ({ mode, isModalOpen, onClose, bucketToEdi .finally(handleClose) }, [handleEditSharedFolder, sharedFolderWriters, sharedFolderReaders, handleClose, bucketToEdit]) - if (!bucketToEdit) return null - return (
- {mode === "edit" && ( + {mode === "edit" && !!bucketToEdit && (
Sharing link diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx index 3e6f46d8b9..6e2d473f88 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx @@ -160,6 +160,7 @@ const SharedFolderOverview = () => { const openSharedFolder = useCallback((bucketId: string) => { redirect(ROUTE_LINKS.SharedFolderExplorer(bucketId, "/")) }, [redirect]) + return ( <>
Date: Mon, 11 Oct 2021 14:50:56 +0200 Subject: [PATCH 11/15] Apply suggestions from code review Co-authored-by: Tanmoy Basak Anjan --- .../Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx | 2 +- .../Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx | 5 +---- .../Modules/FileBrowsers/LinkSharing/SharingLink.tsx | 4 +--- packages/files-ui/src/Contexts/ThresholdKeyContext.tsx | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx index c7ceacaf7b..11f0295159 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/CreateOrEditSharedFolderModal.tsx @@ -106,7 +106,7 @@ const useStyles = makeStyles( color: palette.error.main }, sharingLink: { - padding: 10 + padding: constants.generalUnit * 1.25 } }) } diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx index 2ac605da79..e4d929fddd 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx @@ -1,4 +1,3 @@ - import { Button, MenuDropdown } from "@chainsafe/common-components" import { createStyles, makeStyles } from "@chainsafe/common-theme" import { NonceResponse, NonceResponsePermission } from "@chainsafe/files-api-client" @@ -12,7 +11,6 @@ const useStyles = makeStyles( ({ constants, palette }: CSFTheme) => { return createStyles({ root: { - }, options: { backgroundColor: constants.header.optionsBackground, @@ -61,7 +59,7 @@ const useStyles = makeStyles( marginRight: constants.generalUnit }, dropdownTitle: { - padding: "6px 8px" + padding: `${constants.generalUnit * 0.75}px ${constants.generalUnit}px` } }) } @@ -172,7 +170,6 @@ const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { /> ) } -
) } diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx index a1f5bde137..6c611b7c79 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx @@ -85,8 +85,6 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { setLink(ROUTE_LINKS.SharingLink(nonce.permission, jwt, bucketEncryptionKey)) }, [jwt, bucketEncryptionKey, nonce]) - - const debouncedSwitchCopied = debounce(() => setCopied(false), 3000) const onCopyInfo = useCallback(() => { @@ -104,7 +102,7 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { .catch(console.error) .finally(() => { refreshNonces() - setIsLoading(true) + setIsLoading(false) }) }, [filesApiClient, nonce, refreshNonces]) diff --git a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx index 7bf9776a38..b9788d080c 100644 --- a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx +++ b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx @@ -402,7 +402,7 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f const createJWT = useCallback((bucketId: string, nonceId: string, permission: NonceResponsePermission) => { if(!privateKey) { - console.log("no private key found") + console.error("no private key found") return } From 45515915573597ad90f69d2ebd41660761ee4f2e Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Tue, 12 Oct 2021 16:18:54 +0200 Subject: [PATCH 12/15] no more hack :D --- .../FileBrowsers/LinkSharing/LinkList.tsx | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx index e4d929fddd..7be0c8fff8 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx @@ -1,4 +1,4 @@ -import { Button, MenuDropdown } from "@chainsafe/common-components" +import { Button, Loading, MenuDropdown } from "@chainsafe/common-components" import { createStyles, makeStyles } from "@chainsafe/common-theme" import { NonceResponse, NonceResponsePermission } from "@chainsafe/files-api-client" import { t, Trans } from "@lingui/macro" @@ -102,12 +102,12 @@ const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { return filesApiClient .createNonce({ bucket_id: bucketId, permission: newLinkPermission }) - .then((n) => { - setNonces((olderNonces) => [...olderNonces, n]) - }) .catch(console.error) - .finally(() => setIsLoading(false)) - }, [bucketId, filesApiClient, newLinkPermission]) + .finally(() => { + setIsLoading(false) + refreshNonces() + }) + }, [bucketId, filesApiClient, newLinkPermission, refreshNonces]) return (
@@ -115,13 +115,9 @@ const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { with { />
{ - nonces.length > 0 && nonces.map((nonce) => + isLoading && + } + { + !isLoading && nonces.length > 0 && nonces.map((nonce) => Date: Wed, 13 Oct 2021 10:52:37 +0200 Subject: [PATCH 13/15] Link-sharing landing page (#1620) * link-sharing route and verification * login message * nicer messages * nits * onBrowseBucket * Apply suggestions from code review Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * fix comments * try-catch * cleanup * Update packages/files-ui/src/Components/Modules/LinkSharingModule.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> --- .../src/Router/ConditionalRoute.tsx | 5 +- packages/files-ui/package.json | 2 +- .../files-ui/src/Components/FilesRoutes.tsx | 14 +- .../FileBrowsers/LinkSharing/LinkList.tsx | 12 +- .../FileBrowsers/LinkSharing/SharingLink.tsx | 6 +- .../Components/Modules/LinkSharingModule.tsx | 158 ++++++++++++++++++ .../Modules/LoginModule/InitialScreen.tsx | 18 +- .../Components/Pages/LinkSharingLanding.tsx | 11 ++ .../src/Components/Pages/LoginPage.tsx | 3 - packages/files-ui/src/Utils/pathUtils.ts | 23 +++ packages/files-ui/src/locales/de/messages.po | 12 ++ packages/files-ui/src/locales/en/messages.po | 12 ++ packages/files-ui/src/locales/es/messages.po | 12 ++ packages/files-ui/src/locales/fr/messages.po | 12 ++ packages/files-ui/src/locales/no/messages.po | 12 ++ packages/gaming-ui/package.json | 2 +- packages/storage-ui/package.json | 2 +- yarn.lock | 8 +- 18 files changed, 294 insertions(+), 30 deletions(-) create mode 100644 packages/files-ui/src/Components/Modules/LinkSharingModule.tsx create mode 100644 packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx diff --git a/packages/common-components/src/Router/ConditionalRoute.tsx b/packages/common-components/src/Router/ConditionalRoute.tsx index 004c2131a4..5237a38d92 100644 --- a/packages/common-components/src/Router/ConditionalRoute.tsx +++ b/packages/common-components/src/Router/ConditionalRoute.tsx @@ -21,7 +21,7 @@ const ConditionalRoute: React.FC = ({ exact, ...rest }) => { - const { state, pathname } = useLocation<{from?: string} | undefined>() + const { state, pathname, hash } = useLocation<{from?: string} | undefined>() const from = (state as any)?.from return = ({ ? // this may be converted into loading diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index 03156f78fc..9b16b6fcc4 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.12", + "@chainsafe/files-api-client": "^1.18.14", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", diff --git a/packages/files-ui/src/Components/FilesRoutes.tsx b/packages/files-ui/src/Components/FilesRoutes.tsx index e98356933c..70ae37185a 100644 --- a/packages/files-ui/src/Components/FilesRoutes.tsx +++ b/packages/files-ui/src/Components/FilesRoutes.tsx @@ -11,8 +11,11 @@ import { useThresholdKey } from "../Contexts/ThresholdKeyContext" import ShareFilesPage from "./Pages/SharedFilesPage" import SharedFoldersOverview from "./Modules/FileBrowsers/SharedFoldersOverview" import { NonceResponsePermission } from "@chainsafe/files-api-client" +import LinkSharingLanding from "./Pages/LinkSharingLanding" export const SETTINGS_BASE = "/settings" +export const LINK_SHARING_BASE = "/link-sharing" + export const ROUTE_LINKS = { Landing: "/", PrivacyPolicy: "https://files.chainsafe.io/privacy-policy", @@ -29,8 +32,7 @@ export const ROUTE_LINKS = { SharedFolders: "/shared-overview", SharedFolderBrowserRoot: "/shared", SharingLink: (permission: NonceResponsePermission, jwt: string, bucketEncryptionKey: string) => - // eslint-disable-next-line max-len - `${window.location.origin}/sharing-link/${permissionPath(permission)}/${encodeURIComponent(jwt)}#${encodeURIComponent(bucketEncryptionKey)}`, + `${LINK_SHARING_BASE}/${permissionPath(permission)}/${encodeURIComponent(jwt)}#${encodeURIComponent(bucketEncryptionKey)}`, SharedFolderExplorer: (bucketId: string, rawCurrentPath: string) => { // bucketId should not have a / at the end // rawCurrentPath can be empty, or / @@ -53,6 +55,12 @@ const FilesRoutes = () => { [isLoggedIn, isNewDevice, publicKey, secured, shouldInitializeAccount]) return ( + { redirectPath={ROUTE_LINKS.Landing} /> permission === "read" ? readRights : editRights const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { const classes = useStyles() @@ -121,7 +121,7 @@ const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { with { data-cy="menu-read" className={classes.menuItem} > - {readMenu} + {readRights}
) }, @@ -149,7 +149,7 @@ const LinkList = ({ bucketId, bucketEncryptionKey }: Props) => { data-cy="menu-write" className={classes.menuItem} > - {editMenu} + {editRights}
) } diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx index 6c611b7c79..882f8c64fd 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx @@ -8,7 +8,7 @@ import { useFilesApi } from "../../../../Contexts/FilesApiContext" import { useThresholdKey } from "../../../../Contexts/ThresholdKeyContext" import { CSFTheme } from "../../../../Themes/types" import { ROUTE_LINKS } from "../../../FilesRoutes" -import { editMenu, readMenu } from "./LinkList" +import { translatedPermission } from "./LinkList" const useStyles = makeStyles( ({ constants }: CSFTheme) => { @@ -82,7 +82,7 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { return } - setLink(ROUTE_LINKS.SharingLink(nonce.permission, jwt, bucketEncryptionKey)) + setLink(`${window.location.origin}${ROUTE_LINKS.SharingLink(nonce.permission, jwt, bucketEncryptionKey)}`) }, [jwt, bucketEncryptionKey, nonce]) const debouncedSwitchCopied = debounce(() => setCopied(false), 3000) @@ -115,7 +115,7 @@ const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => {
- {nonce.permission === "read" ? readMenu : editMenu} + {translatedPermission(nonce.permission)}
+ + )} +
+ {!!error && ( + + {error} + + )} + + + ) +} + +export default LinkSharingModule diff --git a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx index 0da2e6c486..5e2c27b009 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, useState } from "react" +import React, { useCallback, useMemo, useState } from "react" import { Button, GithubLogoIcon, @@ -7,7 +7,8 @@ import { Loading, Typography, FormikTextInput, - EthereumLogoIcon + EthereumLogoIcon, + useLocation } from "@chainsafe/common-components" import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" import { CSFTheme } from "../../../Themes/types" @@ -16,7 +17,7 @@ import { useFilesApi } from "../../../Contexts/FilesApiContext" import { useWeb3 } from "@chainsafe/web3-context" import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" import { LOGIN_TYPE } from "@toruslabs/torus-direct-web-sdk" -import { ROUTE_LINKS } from "../../FilesRoutes" +import { LINK_SHARING_BASE, ROUTE_LINKS } from "../../FilesRoutes" import clsx from "clsx" import { IdentityProvider } from "@chainsafe/files-api-client" import PasswordlessEmail from "./PasswordlessEmail" @@ -91,14 +92,14 @@ const useStyles = makeStyles( maxWidth: 240 }, headerText: { + textAlign: "center", [breakpoints.up("md")]: { paddingTop: constants.generalUnit * 4, paddingBottom: constants.generalUnit * 8 }, [breakpoints.down("md")]: { paddingTop: constants.generalUnit * 3, - paddingBottom: constants.generalUnit * 3, - textAlign: "center" + paddingBottom: constants.generalUnit * 3 } }, footer: { @@ -173,6 +174,8 @@ const InitialScreen = ({ className }: IInitialScreen) => { const [isConnecting, setIsConnecting] = useState(false) const { filesApiClient } = useFilesApi() const [email, setEmail] = useState("") + const { state } = useLocation<{from?: string}>() + const isSharing = useMemo(() => state?.from?.includes(LINK_SHARING_BASE), [state]) const handleSelectWalletAndConnect = async () => { setError(undefined) @@ -379,7 +382,10 @@ const InitialScreen = ({ className }: IInitialScreen) => { component="h1" className={classes.headerText} > - Get Started + {isSharing + ? Sign in/up to access the shared folder + : Get Started + } )} {!error && ( diff --git a/packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx b/packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx new file mode 100644 index 0000000000..17a5f585b0 --- /dev/null +++ b/packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx @@ -0,0 +1,11 @@ +import React from "react" +import { usePageTrack } from "../../Contexts/PosthogContext" +import LinkSharingModule from "../Modules/LinkSharingModule" + +const LinkSharingLanding = () => { + usePageTrack() + + return +} + +export default LinkSharingLanding diff --git a/packages/files-ui/src/Components/Pages/LoginPage.tsx b/packages/files-ui/src/Components/Pages/LoginPage.tsx index 8b32ef849e..0a5f26bb13 100644 --- a/packages/files-ui/src/Components/Pages/LoginPage.tsx +++ b/packages/files-ui/src/Components/Pages/LoginPage.tsx @@ -12,7 +12,6 @@ import BottomDarkSVG from "../../Media/landing/layers/dark/Bottom.dark.svg" import TopDarkSVG from "../../Media/landing/layers/dark/Top.dark.svg" import BottomLightSVG from "../../Media/landing/layers/light/Bottom.light.svg" import TopLightSVG from "../../Media/landing/layers/light/Top.light.svg" -// import { ForegroundSVG } from "../../Media/landing/layers/ForegroundSVG" import MigrateAccount from "../Modules/LoginModule/MigrateAccount" import InitializeAccount from "../Modules/LoginModule/InitializeAccount" import { useFilesApi } from "../../Contexts/FilesApiContext" @@ -167,8 +166,6 @@ const LoginPage = () => { ChainSafe Files - <> - { themeKey === "dark" ? <> diff --git a/packages/files-ui/src/Utils/pathUtils.ts b/packages/files-ui/src/Utils/pathUtils.ts index ee3cf3a5f6..25b7412165 100644 --- a/packages/files-ui/src/Utils/pathUtils.ts +++ b/packages/files-ui/src/Utils/pathUtils.ts @@ -103,6 +103,29 @@ export const isSubFolder = (fold1: string, fold2: string) => { return result } +// get the jwt from /link-sharing/permision/jwt +export const getJWT = (pathname: string) => { + const arrayOfPaths = getArrayOfPaths(pathname) + + if(arrayOfPaths.length !== 3){ + console.error("JWT extractione error, unexpected path", pathname) + return + } + + return decodeURIComponent(arrayOfPaths[2]) +} + +// return the hash from #hash +export const getBucketDecryptionFromHash = (hash: string) => { + + if(!hash.startsWith("#")){ + console.error("Bucket encryption key extraction error, unexpected hash", hash) + return + } + + return decodeURIComponent(hash.substr(1)) +} + export const getUrlSafePathWithFile = (path: string, fileName: string) => { let urlSafePath = getURISafePathFromArray(getArrayOfPaths(path)) if (urlSafePath === "/") { diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index 44d2db3f08..9f751fa38d 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -43,6 +43,9 @@ msgstr "Weitere Dateien hinzufügen" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "" +msgid "Adding you to the shared folder..." +msgstr "" + msgid "An error occurred while downloading the file" msgstr "Beim Herunterladen der Datei ist ein Fehler aufgetreten" @@ -61,6 +64,9 @@ msgstr "Der Sicherungsgeheimsatz stimmt nicht mit dem Benutzerkonto überein, bi msgid "Bin" msgstr "Papierkorb" +msgid "Browse {0}" +msgstr "" + msgid "Browser:" msgstr "Browser:" @@ -655,6 +661,9 @@ msgstr "Anmelden" msgid "Sign in with a different account" msgstr "Mit einem anderen Konto anmelden" +msgid "Sign in/up to access the shared folder" +msgstr "" + msgid "Sign me up!" msgstr "" @@ -847,6 +856,9 @@ msgstr "Sie können keine Ordner in diesen Pfad verschieben" msgid "You haven't set a username yet." msgstr "Sie haben noch keinen Benutzernamen festgelegt." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index b658c868ca..12621f80d6 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -43,6 +43,9 @@ msgstr "Add more files" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "Add viewers and editors by username, sharing id or Ethereum address." +msgid "Adding you to the shared folder..." +msgstr "Adding you to the shared folder..." + msgid "An error occurred while downloading the file" msgstr "An error occurred while downloading the file" @@ -61,6 +64,9 @@ msgstr "Backup secret phrase does not match user account, please double-check an msgid "Bin" msgstr "Bin" +msgid "Browse {0}" +msgstr "Browse {0}" + msgid "Browser:" msgstr "Browser:" @@ -658,6 +664,9 @@ msgstr "Sign in" msgid "Sign in with a different account" msgstr "Sign in with a different account" +msgid "Sign in/up to access the shared folder" +msgstr "Sign in/up to access the shared folder" + msgid "Sign me up!" msgstr "Sign me up!" @@ -850,6 +859,9 @@ msgstr "You can't move folders to this path" msgid "You haven't set a username yet." msgstr "You haven't set a username yet." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "You were added to the shared folder ({0}): {1}" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "You will need to sign a message in your wallet to complete sign in." diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index 694c51a71a..56e0839e89 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -44,6 +44,9 @@ msgstr "Agrega mas archivos" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "" +msgid "Adding you to the shared folder..." +msgstr "" + msgid "An error occurred while downloading the file" msgstr "" @@ -62,6 +65,9 @@ msgstr "" msgid "Bin" msgstr "Papelera" +msgid "Browse {0}" +msgstr "" + msgid "Browser:" msgstr "Navegador:" @@ -659,6 +665,9 @@ msgstr "Registrarse" msgid "Sign in with a different account" msgstr "Inicie sesión con una cuenta diferente" +msgid "Sign in/up to access the shared folder" +msgstr "" + msgid "Sign me up!" msgstr "" @@ -851,6 +860,9 @@ msgstr "" msgid "You haven't set a username yet." msgstr "" +msgid "You were added to the shared folder ({0}): {1}" +msgstr "" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "Deberá firmar un mensaje en su billetera para completar el inicio de sesión." diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index cf5216a1be..1f4a346118 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -44,6 +44,9 @@ msgstr "Ajouter d’autres fichiers" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "Ajoutez des personnes pouvant visualiser ou afficher par nom d'utilisateur, identifiant de partage ou adresse Ethereum." +msgid "Adding you to the shared folder..." +msgstr "" + msgid "An error occurred while downloading the file" msgstr "Une erreur s'est produite lors du téléchargement du fichier" @@ -62,6 +65,9 @@ msgstr "La phrase secrète de sauvegarde est incorrecte, merci de vérifier et r msgid "Bin" msgstr "Corbeille" +msgid "Browse {0}" +msgstr "" + msgid "Browser:" msgstr "Explorateur :" @@ -659,6 +665,9 @@ msgstr "Se connecter" msgid "Sign in with a different account" msgstr "Se connecter avec un autre compte" +msgid "Sign in/up to access the shared folder" +msgstr "" + msgid "Sign me up!" msgstr "S'inscrire !" @@ -851,6 +860,9 @@ msgstr "Vous ne pouvez pas déplacer les dossiers vers ce chemin" msgid "You haven't set a username yet." msgstr "Vous n’avez pas encore défini de nom d’utilisateur." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "Vous devrez signer un message avec votre wallet pour terminer la procédure connexion." diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index f59e518022..cadadd2695 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -43,6 +43,9 @@ msgstr "Legg til flere filer" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "" +msgid "Adding you to the shared folder..." +msgstr "" + msgid "An error occurred while downloading the file" msgstr "" @@ -61,6 +64,9 @@ msgstr "" msgid "Bin" msgstr "" +msgid "Browse {0}" +msgstr "" + msgid "Browser:" msgstr "" @@ -655,6 +661,9 @@ msgstr "Logg inn" msgid "Sign in with a different account" msgstr "Logg inn med en annen konto" +msgid "Sign in/up to access the shared folder" +msgstr "" + msgid "Sign me up!" msgstr "" @@ -847,6 +856,9 @@ msgstr "" msgid "You haven't set a username yet." msgstr "Du har ikke satt noe brukernavn enda." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "" diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json index e20a33991c..1288d5c29b 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.12", + "@chainsafe/files-api-client": "^1.18.14", "@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 59009b7207..886e2a234f 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.12", + "@chainsafe/files-api-client": "^1.18.14", "@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 e46f901d58..3bf2c61174 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.12": - version "1.18.12" - resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.12.tgz#cd5d1d6921b7a2ffdd22c2700f77e68eb926e4df" - integrity sha512-EdwUnc4FT/1QdYzOnf2KyFV5I2iOP034HwuPDDLqXoiUidZYpkaEpFEBiIbjh6tX1iUHq551egfxXJQIp73KAg== +"@chainsafe/files-api-client@^1.18.14": + version "1.18.14" + resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.14.tgz#5ec9aba082e884974448e395b7fbbdbfb28b68eb" + integrity sha512-4WDvVOvWxhquAzVzKyGaGqyA13ijWK0jKT5cwgS4cwPGXjPoAB95pjGe6Eo4MWN//p/dSX3qLIPAsMo2n0ZTqQ== dependencies: "@redocly/openapi-cli" "^1.0.0-beta.58" "@redocly/openapi-core" "^1.0.0-beta.58" From 2581d2aeec2f3cfa6c27db0c7981e9ec2a4464b0 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Wed, 13 Oct 2021 15:17:26 +0200 Subject: [PATCH 14/15] nit color --- packages/files-ui/src/Components/Modules/LinkSharingModule.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx b/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx index ce9b83e114..03053ac52e 100644 --- a/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx +++ b/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx @@ -37,7 +37,8 @@ const useStyles = makeStyles( alignItems: "center", fontSize: constants.generalUnit * 6, "& svg": { - marginRight: constants.generalUnit + marginRight: constants.generalUnit, + fill: palette.additional["gray"][7] } }, error: { From d1086ef8e8d9f5cc484acccf4b250299f17ec94b Mon Sep 17 00:00:00 2001 From: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Date: Thu, 14 Oct 2021 14:29:11 +0200 Subject: [PATCH 15/15] Update packages/files-ui/src/Utils/pathUtils.ts Co-authored-by: Ryan Noble --- packages/files-ui/src/Utils/pathUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/files-ui/src/Utils/pathUtils.ts b/packages/files-ui/src/Utils/pathUtils.ts index 25b7412165..5f96cf6bae 100644 --- a/packages/files-ui/src/Utils/pathUtils.ts +++ b/packages/files-ui/src/Utils/pathUtils.ts @@ -108,7 +108,7 @@ export const getJWT = (pathname: string) => { const arrayOfPaths = getArrayOfPaths(pathname) if(arrayOfPaths.length !== 3){ - console.error("JWT extractione error, unexpected path", pathname) + console.error("JWT extraction error, unexpected path", pathname) return }