[web] Remove node buffer dependency from base 58 conversion and cleanup (#4438)
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
"@ente/shared": "*",
|
||||
"@stripe/stripe-js": "^1.13.2",
|
||||
"bip39": "^3.0.4",
|
||||
"bs58": "^5.0.0",
|
||||
"chrono-node": "^2.7.6",
|
||||
"debounce": "^2.1.1",
|
||||
"exifreader": "^4",
|
||||
@@ -36,8 +35,8 @@
|
||||
"devDependencies": {
|
||||
"@/build-config": "*",
|
||||
"@next/bundle-analyzer": "^14.1",
|
||||
"@types/bs58": "^4.0.1",
|
||||
"@types/leaflet": "^1.9",
|
||||
"@types/node": "^20",
|
||||
"@types/photoswipe": "^4.1.1",
|
||||
"@types/react-virtualized-auto-sizer": "^1.0",
|
||||
"@types/react-window": "^1.8.8"
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Titlebar } from "@/base/components/Titlebar";
|
||||
import { useModalVisibility } from "@/base/components/utils/modal";
|
||||
import { sharedCryptoWorker } from "@/base/crypto";
|
||||
import log from "@/base/log";
|
||||
import { appendCollectionKeyToShareURL } from "@/gallery/services/share";
|
||||
import type {
|
||||
Collection,
|
||||
PublicURL,
|
||||
@@ -65,10 +66,7 @@ import {
|
||||
unshareCollection,
|
||||
updateShareableURL,
|
||||
} from "services/collectionService";
|
||||
import {
|
||||
appendCollectionKeyToShareURL,
|
||||
getDeviceLimitOptions,
|
||||
} from "utils/collection";
|
||||
import { getDeviceLimitOptions } from "utils/collection";
|
||||
import * as Yup from "yup";
|
||||
|
||||
interface CollectionShareProps {
|
||||
@@ -1224,12 +1222,11 @@ const PublicShare: React.FC<PublicShareProps> = ({
|
||||
}, [collection]);
|
||||
|
||||
useEffect(() => {
|
||||
if (publicShareProp) {
|
||||
const url = appendCollectionKeyToShareURL(
|
||||
if (publicShareProp?.url) {
|
||||
appendCollectionKeyToShareURL(
|
||||
publicShareProp.url,
|
||||
collection.key,
|
||||
);
|
||||
setPublicShareUrl(url);
|
||||
).then((url) => setPublicShareUrl(url));
|
||||
} else {
|
||||
setPublicShareUrl(null);
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
useIsSmallWidth,
|
||||
useIsTouchscreen,
|
||||
} from "@/base/components/utils/hooks";
|
||||
import { sharedCryptoWorker } from "@/base/crypto";
|
||||
import { isHTTP401Error, PublicAlbumsCredentials } from "@/base/http";
|
||||
import log from "@/base/log";
|
||||
import { downloadManager } from "@/gallery/services/download";
|
||||
import { extractCollectionKeyFromShareURL } from "@/gallery/services/share";
|
||||
import { updateShouldDisableCFUploadProxy } from "@/gallery/services/upload";
|
||||
import type { Collection } from "@/media/collection";
|
||||
import { type EnteFile, mergeMetadata } from "@/media/file";
|
||||
@@ -47,7 +47,6 @@ import FileDownloadOutlinedIcon from "@mui/icons-material/FileDownloadOutlined";
|
||||
import type { ButtonProps, IconButtonProps } from "@mui/material";
|
||||
import { Box, Button, IconButton, Stack, styled, Tooltip } from "@mui/material";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import bs58 from "bs58";
|
||||
import {
|
||||
FilesDownloadProgress,
|
||||
FilesDownloadProgressAttributes,
|
||||
@@ -222,12 +221,10 @@ export default function PublicCollectionGallery() {
|
||||
const main = async () => {
|
||||
let redirectingToWebsite = false;
|
||||
try {
|
||||
const cryptoWorker = await sharedCryptoWorker();
|
||||
|
||||
url.current = window.location.href;
|
||||
const currentURL = new URL(url.current);
|
||||
const t = currentURL.searchParams.get("t");
|
||||
const ck = currentURL.hash.slice(1);
|
||||
const ck = await extractCollectionKeyFromShareURL(currentURL);
|
||||
if (!t && !ck) {
|
||||
window.location.href = "https://ente.io";
|
||||
redirectingToWebsite = true;
|
||||
@@ -235,11 +232,7 @@ export default function PublicCollectionGallery() {
|
||||
if (!t || !ck) {
|
||||
return;
|
||||
}
|
||||
const dck =
|
||||
ck.length < 50
|
||||
? await cryptoWorker.toB64(bs58.decode(ck))
|
||||
: await cryptoWorker.fromHex(ck);
|
||||
collectionKey.current = dck;
|
||||
collectionKey.current = ck;
|
||||
url.current = window.location.href;
|
||||
const localCollection = await getLocalPublicCollection(
|
||||
collectionKey.current,
|
||||
|
||||
@@ -22,7 +22,6 @@ import { updateMagicMetadata } from "@/new/photos/services/magic-metadata";
|
||||
import { safeDirectoryName } from "@/new/photos/utils/native-fs";
|
||||
import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
|
||||
import type { User } from "@ente/shared/user/types";
|
||||
import bs58 from "bs58";
|
||||
import { t } from "i18next";
|
||||
import {
|
||||
addToCollection,
|
||||
@@ -177,21 +176,6 @@ async function createCollectionDownloadFolder(
|
||||
return collectionDownloadPath;
|
||||
}
|
||||
|
||||
export function appendCollectionKeyToShareURL(
|
||||
url: string,
|
||||
collectionKey: string,
|
||||
) {
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const sharableURL = new URL(url);
|
||||
|
||||
const bytes = Buffer.from(collectionKey, "base64");
|
||||
sharableURL.hash = bs58.encode(bytes);
|
||||
return sharableURL.href;
|
||||
}
|
||||
|
||||
const _intSelectOption = (i: number) => {
|
||||
const label = i === 0 ? t("NO_DEVICE_LIMIT") : i.toString();
|
||||
return { label, value: i };
|
||||
|
||||
@@ -160,6 +160,9 @@ For more details, see [translations.md](translations.md).
|
||||
identifiers. For one particular use case, we also need
|
||||
[uuid](https://github.com/uuidjs/uuid) for UUID v4 generation.
|
||||
|
||||
- [bs58](https://github.com/cryptocoinjs/bs58) is used for base-58 conversion
|
||||
(used for encoding the collection key to use as the hash in the share URL).
|
||||
|
||||
- [debounce](https://github.com/sindresorhus/debounce) and its
|
||||
promise-supporting sibling
|
||||
[pDebounce](https://github.com/sindresorhus/p-debounce) are used for
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
import * as libsodium from "./libsodium";
|
||||
import type { BytesOrB64, EncryptedBlob, EncryptedFile } from "./types";
|
||||
|
||||
export const _toB64 = libsodium.toB64;
|
||||
|
||||
export const _toB64URLSafe = libsodium.toB64URLSafe;
|
||||
|
||||
export const _fromB64 = libsodium.fromB64;
|
||||
|
||||
export const _toHex = libsodium.toHex;
|
||||
|
||||
export const _fromHex = libsodium.fromHex;
|
||||
|
||||
export const _generateBoxKey = libsodium.generateBoxKey;
|
||||
|
||||
export const _generateBlobOrStreamKey = libsodium.generateBlobOrStreamKey;
|
||||
|
||||
@@ -98,6 +98,44 @@ const assertInWorker = <T>(x: T): T => {
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert bytes ({@link Uint8Array}) to a base64 string.
|
||||
*/
|
||||
export const toB64 = (bytes: Uint8Array) =>
|
||||
inWorker() ? ei._toB64(bytes) : sharedWorker().then((w) => w.toB64(bytes));
|
||||
|
||||
/**
|
||||
* URL safe variant of {@link toB64}.
|
||||
*/
|
||||
export const toB64URLSafe = (bytes: Uint8Array) =>
|
||||
inWorker()
|
||||
? ei._toB64URLSafe(bytes)
|
||||
: sharedWorker().then((w) => w.toB64URLSafe(bytes));
|
||||
|
||||
/**
|
||||
* Convert a base64 string to bytes ({@link Uint8Array}).
|
||||
*/
|
||||
export const fromB64 = (b64String: string) =>
|
||||
inWorker()
|
||||
? ei._fromB64(b64String)
|
||||
: sharedWorker().then((w) => w.fromB64(b64String));
|
||||
|
||||
/**
|
||||
* Convert a base64 string to the hex representation of the underlying bytes.
|
||||
*/
|
||||
export const toHex = (b64String: string) =>
|
||||
inWorker()
|
||||
? ei._toHex(b64String)
|
||||
: sharedWorker().then((w) => w.toHex(b64String));
|
||||
|
||||
/**
|
||||
* Convert a hex string to the base64 representation of the underlying bytes.
|
||||
*/
|
||||
export const fromHex = (hexString: string) =>
|
||||
inWorker()
|
||||
? ei._fromHex(hexString)
|
||||
: sharedWorker().then((w) => w.fromHex(hexString));
|
||||
|
||||
/**
|
||||
* Return a new randomly generated 256-bit key (as a base64 string) suitable for
|
||||
* use with the *Box encryption functions.
|
||||
|
||||
@@ -100,15 +100,27 @@ export const fromB64URLSafeNoPaddingString = async (input: string) => {
|
||||
return sodium.to_string(await fromB64URLSafeNoPadding(input));
|
||||
};
|
||||
|
||||
export async function toHex(input: string) {
|
||||
/**
|
||||
* Convert a base64 string to the hex representation of the bytes that the base
|
||||
* 64 string encodes.
|
||||
*
|
||||
* Use {@link fromHex} to go back.
|
||||
*/
|
||||
export const toHex = async (input: string) => {
|
||||
await sodium.ready;
|
||||
return sodium.to_hex(await fromB64(input));
|
||||
}
|
||||
};
|
||||
|
||||
export async function fromHex(input: string) {
|
||||
/**
|
||||
* Convert a hex string to the base 64 representation of the bytes that the hex
|
||||
* string encodes.
|
||||
*
|
||||
* This is the inverse of {@link toHex}.
|
||||
*/
|
||||
export const fromHex = async (input: string) => {
|
||||
await sodium.ready;
|
||||
return await toB64(sodium.from_hex(input));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If the provided {@link bob} ("Bytes or B64 string") is already a
|
||||
|
||||
@@ -13,6 +13,11 @@ import * as libsodium from "./libsodium";
|
||||
* Note: Keep these methods logic free. They are meant to be trivial proxies.
|
||||
*/
|
||||
export class CryptoWorker {
|
||||
toB64 = ei._toB64;
|
||||
toB64URLSafe = ei._toB64URLSafe;
|
||||
fromB64 = ei._fromB64;
|
||||
toHex = ei._toHex;
|
||||
fromHex = ei._fromHex;
|
||||
generateBoxKey = ei._generateBoxKey;
|
||||
generateBlobOrStreamKey = ei._generateBlobOrStreamKey;
|
||||
encryptBoxB64 = ei._encryptBoxB64;
|
||||
@@ -90,26 +95,6 @@ export class CryptoWorker {
|
||||
) {
|
||||
return libsodium.generateSubKey(key, subKeyLength, subKeyID, context);
|
||||
}
|
||||
|
||||
async toB64(data: Uint8Array) {
|
||||
return libsodium.toB64(data);
|
||||
}
|
||||
|
||||
async toB64URLSafe(data: Uint8Array) {
|
||||
return libsodium.toB64URLSafe(data);
|
||||
}
|
||||
|
||||
async fromB64(string: string) {
|
||||
return libsodium.fromB64(string);
|
||||
}
|
||||
|
||||
async toHex(string: string) {
|
||||
return libsodium.toHex(string);
|
||||
}
|
||||
|
||||
async fromHex(string: string) {
|
||||
return libsodium.fromHex(string);
|
||||
}
|
||||
}
|
||||
|
||||
expose(CryptoWorker);
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ffmpeg/ffmpeg": "^0.12.10"
|
||||
"@ffmpeg/ffmpeg": "^0.12.10",
|
||||
"bs58": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@/build-config": "*"
|
||||
|
||||
46
web/packages/gallery/services/share.ts
Normal file
46
web/packages/gallery/services/share.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { fromB64, fromHex, toB64 } from "@/base/crypto";
|
||||
import bs58 from "bs58";
|
||||
|
||||
/**
|
||||
* Add the collection key as the hash to the given URL.
|
||||
*
|
||||
* The hash fragment is a client side component and is not accessible to remote
|
||||
* servers. The collection key is base-58 encoded and set as the hash in public
|
||||
* URLs of shared albums.
|
||||
*
|
||||
* Use {@link extractCollectionKeyFromShareURL} to get back the collection key.
|
||||
|
||||
* @param url The base URL for the public album.
|
||||
|
||||
* @param collectionKey The base-64 encoded string representation of the
|
||||
* collection key for the public album.
|
||||
*
|
||||
* @returns A URL that includes the base-58 encoded collection key as the hash
|
||||
* fragment.
|
||||
*/
|
||||
export const appendCollectionKeyToShareURL = async (
|
||||
url: string,
|
||||
collectionKey: string,
|
||||
) => {
|
||||
const sharableURL = new URL(url);
|
||||
|
||||
const bytes = await fromB64(collectionKey);
|
||||
sharableURL.hash = bs58.encode(bytes);
|
||||
return sharableURL.href;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract the collection key from a public URL.
|
||||
*
|
||||
* This is the inverse of {@link appendCollectionKeyToShareURL}, returning the
|
||||
* base 64 string representation of the collection key.
|
||||
*
|
||||
* collection key (bytes)
|
||||
* => appendCollectionKeytoShareURL (base 64 => base 58)
|
||||
* => URL hash => extractCollectionKeyBytesFromShareURL (base 58 => base 64)
|
||||
* => collection key (bytes).
|
||||
*/
|
||||
export const extractCollectionKeyFromShareURL = async (url: URL) => {
|
||||
const ck = url.hash.slice(1);
|
||||
return ck.length < 50 ? await toB64(bs58.decode(ck)) : await fromHex(ck);
|
||||
};
|
||||
@@ -234,7 +234,7 @@
|
||||
source-map "^0.5.7"
|
||||
stylis "4.2.0"
|
||||
|
||||
"@emotion/cache@11.13.1", "@emotion/cache@^11.11.0", "@emotion/cache@^11.13.5", "@emotion/cache@^11.4.0":
|
||||
"@emotion/cache@11.13.1", "@emotion/cache@^11.11.0", "@emotion/cache@^11.14.0", "@emotion/cache@^11.4.0":
|
||||
version "11.13.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.1.tgz#fecfc54d51810beebf05bf2a161271a1a91895d7"
|
||||
integrity sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==
|
||||
@@ -263,15 +263,15 @@
|
||||
integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==
|
||||
|
||||
"@emotion/react@11.13.3", "@emotion/react@^11.13.3", "@emotion/react@^11.8.1":
|
||||
version "11.13.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.13.5.tgz#fc818ff5b13424f86501ba4d0740f343ae20b8d9"
|
||||
integrity sha512-6zeCUxUH+EPF1s+YF/2hPVODeV/7V07YU5x+2tfuRL8MdW6rv5vb2+CBEGTGwBdux0OIERcOS+RzxeK80k2DsQ==
|
||||
version "11.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.14.0.tgz#cfaae35ebc67dd9ef4ea2e9acc6cd29e157dd05d"
|
||||
integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
"@emotion/babel-plugin" "^11.13.5"
|
||||
"@emotion/cache" "^11.13.5"
|
||||
"@emotion/cache" "^11.14.0"
|
||||
"@emotion/serialize" "^1.3.3"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.1.0"
|
||||
"@emotion/use-insertion-effect-with-fallbacks" "^1.2.0"
|
||||
"@emotion/utils" "^1.4.2"
|
||||
"@emotion/weak-memoize" "^0.4.0"
|
||||
hoist-non-react-statics "^3.3.1"
|
||||
@@ -325,6 +325,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz#1a818a0b2c481efba0cf34e5ab1e0cb2dcb9dfaf"
|
||||
integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==
|
||||
|
||||
"@emotion/use-insertion-effect-with-fallbacks@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz#8a8cb77b590e09affb960f4ff1e9a89e532738bf"
|
||||
integrity sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==
|
||||
|
||||
"@emotion/utils@^1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.0.tgz#262f1d02aaedb2ec91c83a0955dd47822ad5fbdd"
|
||||
@@ -947,14 +952,6 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.20.7"
|
||||
|
||||
"@types/bs58@^4.0.1":
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.4.tgz#49fbcb0c7db5f7cea26f0e0f61dc4a41a2445aab"
|
||||
integrity sha512-0IEpMFXXQi2zXaXl9GJ3sRwQo0uEkD+yFOv+FnAU5lkPtcu6h61xb7jc2CFPEZ5BUOaiP13ThuGc9HD4R8lR5g==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
base-x "^3.0.6"
|
||||
|
||||
"@types/chromecast-caf-receiver@^6.0.17":
|
||||
version "6.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/chromecast-caf-receiver/-/chromecast-caf-receiver-6.0.17.tgz#c54bb6416ed07b78694db6e953be7ca966d09f06"
|
||||
@@ -1012,10 +1009,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.14.tgz#f688f8d44e46ed61c401f82ff757581655fbcc42"
|
||||
integrity sha512-5Kv68fXuXK0iDuUir1WPGw2R9fOZUlYlSAa0ztMcL0s0BfIDTqg9GXz8K30VJpPP3sxWhbolnQma2x+/TfkzDQ==
|
||||
|
||||
"@types/node@*":
|
||||
version "22.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.4.tgz#83f7d1f65bc2ed223bdbf57c7884f1d5a4fa84e8"
|
||||
integrity sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==
|
||||
"@types/node@^20":
|
||||
version "20.17.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.10.tgz#3f7166190aece19a0d1d364d75c8b0b5778c1e18"
|
||||
integrity sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==
|
||||
dependencies:
|
||||
undici-types "~6.19.2"
|
||||
|
||||
@@ -1345,17 +1342,10 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base-x@^3.0.6:
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.10.tgz#62de58653f8762b5d6f8d9fe30fa75f7b2585a75"
|
||||
integrity sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
base-x@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a"
|
||||
integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==
|
||||
base-x@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/base-x/-/base-x-5.0.0.tgz#6d835ceae379130e1a4cb846a70ac4746f28ea9b"
|
||||
integrity sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==
|
||||
|
||||
bip39@^3.0.4:
|
||||
version "3.1.0"
|
||||
@@ -1396,12 +1386,12 @@ browserslist@^4.23.1:
|
||||
node-releases "^2.0.18"
|
||||
update-browserslist-db "^1.1.0"
|
||||
|
||||
bs58@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279"
|
||||
integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==
|
||||
bs58@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bs58/-/bs58-6.0.0.tgz#a2cda0130558535dd281a2f8697df79caaf425d8"
|
||||
integrity sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==
|
||||
dependencies:
|
||||
base-x "^4.0.0"
|
||||
base-x "^5.0.0"
|
||||
|
||||
busboy@1.6.0:
|
||||
version "1.6.0"
|
||||
@@ -3470,16 +3460,16 @@ safe-array-concat@^1.1.2:
|
||||
has-symbols "^1.0.3"
|
||||
isarray "^2.0.5"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-regex-test@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377"
|
||||
|
||||
Reference in New Issue
Block a user