From 294945ccbb2fc74b2fe4bb671102528f23e76c8e Mon Sep 17 00:00:00 2001 From: Emi <emilia.marczyk@rumblefish.pl> Date: Tue, 24 Oct 2023 14:31:39 +0200 Subject: [PATCH] feat: Check if psk in invitation link is base64 encoded #1897 --- packages/backend/package-lock.json | 22 +++++++----- packages/backend/package.json | 4 +-- packages/backend/src/nest/common/utils.ts | 8 +++-- .../connections-manager.service.ts | 29 ++++++++++------ packages/common/package-lock.json | 29 +++++++++++++++- packages/common/package.json | 4 ++- packages/common/src/invitationCode.test.ts | 34 ++++++++++++------- packages/common/src/invitationCode.ts | 15 ++++---- .../PerformCommunityActionComponent.tsx | 4 +-- .../components/Settings/Settings.stories.tsx | 4 +-- .../Tabs/Invite/Invite.component.test.tsx | 6 ++-- .../Settings/Tabs/Invite/Invite.stories.tsx | 4 +-- .../Settings/Tabs/QRCode/QRCode.stories.tsx | 4 +-- .../invitationCode/invitationCode.test.ts | 26 +++++++++----- 14 files changed, 130 insertions(+), 63 deletions(-) diff --git a/packages/backend/package-lock.json b/packages/backend/package-lock.json index e3231dcb13..f31eec94c5 100644 --- a/packages/backend/package-lock.json +++ b/packages/backend/package-lock.json @@ -56,7 +56,7 @@ "socks-proxy-agent": "^5.0.0", "string-replace-loader": "3.1.0", "ts-jest-resolver": "^2.0.0", - "validator": "^13.6.0" + "validator": "^13.11.0" }, "devDependencies": { "@nestjs/cli": "^10.0.0", @@ -72,7 +72,7 @@ "@types/orbit-db": "git+https://github.com/orbitdb/orbit-db-types.git", "@types/supertest": "^2.0.11", "@types/tmp": "^0.2.3", - "@types/validator": "^13.1.4", + "@types/validator": "^13.11.5", "@types/ws": "8.5.3", "babel-jest": "^29.3.1", "cross-env": "^5.2.0", @@ -6580,8 +6580,9 @@ "license": "MIT" }, "node_modules/@types/validator": { - "version": "13.1.4", - "license": "MIT" + "version": "13.11.5", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.5.tgz", + "integrity": "sha512-xW4qsT4UIYILu+7ZrBnfQdBYniZrMLYYK3wN9M/NdeIHgBN5pZI2/8Q7UfdWIcr5RLJv/OGENsx91JIpUUoC7Q==" }, "node_modules/@types/ws": { "version": "8.5.3", @@ -21995,8 +21996,9 @@ } }, "node_modules/validator": { - "version": "13.7.0", - "license": "MIT", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "engines": { "node": ">= 0.10" } @@ -26934,7 +26936,9 @@ "dev": true }, "@types/validator": { - "version": "13.1.4" + "version": "13.11.5", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.5.tgz", + "integrity": "sha512-xW4qsT4UIYILu+7ZrBnfQdBYniZrMLYYK3wN9M/NdeIHgBN5pZI2/8Q7UfdWIcr5RLJv/OGENsx91JIpUUoC7Q==" }, "@types/ws": { "version": "8.5.3", @@ -36673,7 +36677,9 @@ } }, "validator": { - "version": "13.7.0" + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==" }, "varint": { "version": "6.0.0" diff --git a/packages/backend/package.json b/packages/backend/package.json index 43ca6f284b..a1e58e0f34 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -65,7 +65,7 @@ "@types/orbit-db": "git+https://github.com/orbitdb/orbit-db-types.git", "@types/supertest": "^2.0.11", "@types/tmp": "^0.2.3", - "@types/validator": "^13.1.4", + "@types/validator": "^13.11.5", "@types/ws": "8.5.3", "babel-jest": "^29.3.1", "cross-env": "^5.2.0", @@ -134,7 +134,7 @@ "socks-proxy-agent": "^5.0.0", "string-replace-loader": "3.1.0", "ts-jest-resolver": "^2.0.0", - "validator": "^13.6.0" + "validator": "^13.11.0" }, "overrides": { "level": "$level", diff --git a/packages/backend/src/nest/common/utils.ts b/packages/backend/src/nest/common/utils.ts index 23d3735631..4d0de9701a 100644 --- a/packages/backend/src/nest/common/utils.ts +++ b/packages/backend/src/nest/common/utils.ts @@ -13,7 +13,6 @@ import logger from './logger' import { createCertificatesTestHelper } from './client-server' import { Libp2pNodeParams } from '../libp2p/libp2p.types' import { createLibp2pAddress, createLibp2pListenAddress } from '@quiet/common' -import { randomBytes } from '@libp2p/crypto' import { toString as uint8ArrayToString } from 'uint8arrays/to-string' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' @@ -241,8 +240,11 @@ export async function createPeerId(): Promise<PeerId> { const KEY_LENGTH = 32 -export function generateKey(bytes: Uint8Array | NodeJS.WriteStream, key?: Uint8Array) { - const psk = key || randomBytes(KEY_LENGTH) +export function generateLibp2pPSK(bytes: Uint8Array | NodeJS.WriteStream, key?: Uint8Array) { + /** + * Based on 'libp2p/pnet' generateKey + */ + const psk = key || crypto.randomBytes(KEY_LENGTH) const base16StringKey = uint8ArrayToString(psk, 'base16') const fullKey = uint8ArrayFromString('/key/swarm/psk/1.0.0/\n/base16/\n' + base16StringKey) diff --git a/packages/backend/src/nest/connections-manager/connections-manager.service.ts b/packages/backend/src/nest/connections-manager/connections-manager.service.ts index 486e32b573..8ab0b5988d 100644 --- a/packages/backend/src/nest/connections-manager/connections-manager.service.ts +++ b/packages/backend/src/nest/connections-manager/connections-manager.service.ts @@ -8,7 +8,8 @@ import { setEngine, CryptoEngine } from 'pkijs' import { EventEmitter } from 'events' import getPort from 'get-port' import PeerId from 'peer-id' -import { generateKey, removeFilesFromDir } from '../common/utils' +import { generateLibp2pPSK, removeFilesFromDir } from '../common/utils' +import validator from 'validator' import { AskForMessagesPayload, ChannelMessagesIdsResponse, @@ -276,10 +277,18 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI }, network, } - const psk = community.psk // Passed in base64 + const psk = community.psk if (psk) { console.log('createNetwork got psk', psk) - await this.localDbService.put(LocalDBKeys.PSK, psk) // Validate psk before saving? + if (!validator.isBase64(psk)) { + emitError(this.serverIoProvider.io, { + type: SocketActionTypes.NETWORK, + message: ErrorMessages.NETWORK_SETUP_FAILED, + community: community.id, + }) + return + } + await this.localDbService.put(LocalDBKeys.PSK, psk) } this.serverIoProvider.io.emit(SocketActionTypes.NETWORK, payload) @@ -287,11 +296,9 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI private async generatePSK() { const libp2pPSK = new Uint8Array(95) - const psk = generateKey(libp2pPSK) - console.log('Generated new buffer psk', psk) - const pskBase64 = uint8ArrayToString(psk, 'base64') + const psk = generateLibp2pPSK(libp2pPSK) + const pskBase64 = psk.toString('base64') await this.localDbService.put(LocalDBKeys.PSK, pskBase64) - console.log('psk base64 SAVED', pskBase64) this.serverIoProvider.io.emit(SocketActionTypes.PSK, { psk: pskBase64 }) } @@ -367,12 +374,14 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI if (!peers || peers.length === 0) { peers = [this.libp2pService.createLibp2pAddress(onionAddress, _peerId.toString())] } - const pskValue = await this.localDbService.get(LocalDBKeys.PSK) // What if there is no psk in db? + const pskValue = await this.localDbService.get(LocalDBKeys.PSK) + if (!pskValue) { + throw new Error('No psk in local db') + } console.log('psk base64 RETRIEVED', pskValue) const psk = uint8ArrayFromString(pskValue, 'base64') - console.log('psk buffer retrieved', psk) const libp2pPSK = new Uint8Array(95) - generateKey(libp2pPSK, psk) + generateLibp2pPSK(libp2pPSK, psk) const params: Libp2pNodeParams = { peerId: _peerId, diff --git a/packages/common/package-lock.json b/packages/common/package-lock.json index e3ab0a7f16..45a196a5bc 100644 --- a/packages/common/package-lock.json +++ b/packages/common/package-lock.json @@ -10,11 +10,13 @@ "license": "ISC", "dependencies": { "cross-env": "^5.2.0", - "debug": "^4.3.1" + "debug": "^4.3.1", + "validator": "^13.11.0" }, "devDependencies": { "@types/jest": "^26.0.23", "@types/node": "^17.0.21", + "@types/validator": "^13.11.5", "jest": "^26.6.3", "ts-jest": "^26.5.2", "typescript": "^4.9.3" @@ -1116,6 +1118,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/validator": { + "version": "13.11.5", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.5.tgz", + "integrity": "sha512-xW4qsT4UIYILu+7ZrBnfQdBYniZrMLYYK3wN9M/NdeIHgBN5pZI2/8Q7UfdWIcr5RLJv/OGENsx91JIpUUoC7Q==", + "dev": true + }, "node_modules/@types/yargs": { "version": "15.0.15", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz", @@ -5989,6 +5997,14 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -7098,6 +7114,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/validator": { + "version": "13.11.5", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.5.tgz", + "integrity": "sha512-xW4qsT4UIYILu+7ZrBnfQdBYniZrMLYYK3wN9M/NdeIHgBN5pZI2/8Q7UfdWIcr5RLJv/OGENsx91JIpUUoC7Q==", + "dev": true + }, "@types/yargs": { "version": "15.0.15", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz", @@ -10885,6 +10907,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==" + }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", diff --git a/packages/common/package.json b/packages/common/package.json index f9f6eb49f0..b3e8934d16 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -21,6 +21,7 @@ "@quiet/eslint-config": "^2.0.1-alpha.4", "@types/jest": "^26.0.23", "@types/node": "^17.0.21", + "@types/validator": "^13.11.5", "jest": "^26.6.3", "ts-jest": "^26.5.2", "typescript": "^4.9.3" @@ -28,7 +29,8 @@ "dependencies": { "@quiet/types": "^2.0.1-alpha.4", "cross-env": "^5.2.0", - "debug": "^4.3.1" + "debug": "^4.3.1", + "validator": "^13.11.0" }, "jest": { "transform": { diff --git a/packages/common/src/invitationCode.test.ts b/packages/common/src/invitationCode.test.ts index 76cb6320f7..f44588fe1f 100644 --- a/packages/common/src/invitationCode.test.ts +++ b/packages/common/src/invitationCode.test.ts @@ -13,6 +13,8 @@ describe('Invitation code helper', () => { const address1 = 'gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad' const peerId2 = 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE' const address2 = 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdvcbzw5vex2crsr26qd' + const psk = 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw%3D' + const pskDecoded = 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw=' it('retrieves invitation code from argv', () => { const expectedCodes: InvitationData = { @@ -20,7 +22,7 @@ describe('Invitation code helper', () => { { peerId: peerId1, onionAddress: address1 }, { peerId: peerId2, onionAddress: address2 }, ], - psk: '12345', + psk: pskDecoded, } const result = argvInvitationCode([ 'something', @@ -33,16 +35,27 @@ describe('Invitation code helper', () => { expect(result).toEqual(expectedCodes) }) - it('builds proper invitation deep url', () => { + it('returns null if argv do not contain any valid invitation code', () => { + const result = argvInvitationCode([ + 'something', + 'quiet:/invalid', + 'zbay://invalid', + 'quiet://invalid', + 'quiet://?param=invalid', + ]) + expect(result).toBeNull() + }) + + it('composes proper invitation deep url', () => { expect( composeInvitationDeepUrl({ pairs: [ { peerId: 'peerID1', onionAddress: 'address1' }, { peerId: 'peerID2', onionAddress: 'address2' }, ], - psk: '12345', + psk: pskDecoded, }) - ).toEqual(`quiet://?peerID1=address1&peerID2=address2&${Site.PSK_PARAM_KEY}=12345`) + ).toEqual(`quiet://?peerID1=address1&peerID2=address2&${Site.PSK_PARAM_KEY}=${psk}`) }) it('creates invitation share url based on invitation data', () => { @@ -51,9 +64,9 @@ describe('Invitation code helper', () => { { peerId: 'peerID1', onionAddress: 'address1' }, { peerId: 'peerID2', onionAddress: 'address2' }, ], - psk: '12345', + psk: pskDecoded, } - const expected = `${QUIET_JOIN_PAGE}#peerID1=address1&peerID2=address2&${Site.PSK_PARAM_KEY}=${pairs.psk}` + const expected = `${QUIET_JOIN_PAGE}#peerID1=address1&peerID2=address2&${Site.PSK_PARAM_KEY}=${psk}` expect(composeInvitationShareUrl(pairs)).toEqual(expected) }) @@ -63,14 +76,12 @@ describe('Invitation code helper', () => { 'invalidAddress', '/dns4/somethingElse.onion/tcp/443/wss/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSA', ] - const psk = 'L2tleS9zd2FybS9wc2svMS' - expect(invitationShareUrl(peerList, psk)).toEqual( + expect(invitationShareUrl(peerList, pskDecoded)).toEqual( `${QUIET_JOIN_PAGE}#QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE=gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad&QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSA=somethingElse&${Site.PSK_PARAM_KEY}=${psk}` ) }) it('retrieves invitation codes from deep url', () => { - const psk = '12345' const codes = parseInvitationCodeDeepUrl( `quiet://?${peerId1}=${address1}&${peerId2}=${address2}&${Site.PSK_PARAM_KEY}=${psk}` ) @@ -79,17 +90,16 @@ describe('Invitation code helper', () => { { peerId: peerId1, onionAddress: address1 }, { peerId: peerId2, onionAddress: address2 }, ], - psk: psk, + psk: pskDecoded, }) }) it('retrieves invitation codes from deep url with partly invalid codes', () => { - const psk = '12345' const peerId2 = 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLs' const address2 = 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdvcbzw5vex2crsr26qd' const parsed = parseInvitationCodeDeepUrl( `quiet://?${peerId1}=${address1}&${peerId2}=${address2}&${Site.PSK_PARAM_KEY}=${psk}` ) - expect(parsed).toEqual({ pairs: [{ peerId: peerId1, onionAddress: address1 }], psk: psk }) + expect(parsed).toEqual({ pairs: [{ peerId: peerId1, onionAddress: address1 }], psk: pskDecoded }) }) }) diff --git a/packages/common/src/invitationCode.ts b/packages/common/src/invitationCode.ts index d36a5ddc8e..4cc50616b8 100644 --- a/packages/common/src/invitationCode.ts +++ b/packages/common/src/invitationCode.ts @@ -1,12 +1,14 @@ import { InvitationData, InvitationPair } from '@quiet/types' import { ONION_ADDRESS_REGEX, PEER_ID_REGEX, QUIET_JOIN_PAGE, Site } from './static' import { createLibp2pAddress } from './libp2p' +import validator from 'validator' const parseDeepUrl = ({ url, expectedProtocol = `quiet:` }: { url: string; expectedProtocol?: string }) => { let _url = url let validUrl: URL | null = null if (!expectedProtocol) { + // Create a full url to be able to use the same URL parsing mechanism expectedProtocol = `${Site.DEEP_URL_SCHEME}:` _url = `${Site.DEEP_URL_SCHEME}://?${url}` } @@ -14,20 +16,20 @@ const parseDeepUrl = ({ url, expectedProtocol = `quiet:` }: { url: string; expec try { validUrl = new URL(_url) } catch (e) { - console.error(`Could not retrieve invitation code from deep url ${url}. Reason: ${e.message}`) + console.error(`Could not retrieve invitation code from deep url '${url}'. Reason: ${e.message}`) throw e } if (!validUrl || validUrl.protocol !== expectedProtocol) { - console.error(`Could not retrieve invitation code from deep url ${url}`) + console.error(`Could not retrieve invitation code from deep url '${url}'`) throw new Error() } const params = validUrl.searchParams const codes: InvitationPair[] = [] let psk = params.get(Site.PSK_PARAM_KEY) - if (!psk) throw new Error(`No psk found in invitation code ${url}`) + if (!psk) throw new Error(`No psk found in invitation code '${url}'`) psk = decodeURIComponent(psk) - // Validate base64 + if (!validator.isBase64(psk)) throw new Error(`Invalid psk in invitation code '${url}'`) params.delete(Site.PSK_PARAM_KEY) @@ -61,12 +63,11 @@ export const parseInvitationCode = (code: string): InvitationData => { } export const invitationShareUrl = (peers: string[] = [], psk: string): string => { - // TODO: rename to 'composeInvitationShareUrl' + // TODO: rename /** * @arg {string[]} peers - List of peer's p2p addresses * @returns {string} - Complete shareable invitation link, e.g. https://tryquiet.org/join/#<peerid1>=<address1>&<peerid2>=<addresss2>&k=<psk> */ - console.log('Invitation share url, peers:', peers) const pairs: InvitationPair[] = [] for (const peerAddress of peers) { let peerId: string @@ -144,7 +145,7 @@ export const argvInvitationCode = (argv: string[]): InvitationData | null => { return invitationData } -export const peerDataValid = ({ peerId, onionAddress }: { peerId: string; onionAddress: string }): boolean => { +const peerDataValid = ({ peerId, onionAddress }: { peerId: string; onionAddress: string }): boolean => { // TODO: rename to peerDataValid? if (!peerId.match(PEER_ID_REGEX)) { // TODO: test it more properly e.g with PeerId.createFromB58String(peerId.trim()) diff --git a/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx b/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx index e5920095e1..1d094db8b0 100644 --- a/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx +++ b/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx @@ -20,7 +20,7 @@ import { InviteLinkErrors } from '../../forms/fieldsErrors' import { IconButton, InputAdornment } from '@mui/material' import VisibilityOff from '@mui/icons-material/VisibilityOff' import Visibility from '@mui/icons-material/Visibility' -import { ONION_ADDRESS_REGEX, composeToInvitationShareUrl, parseName } from '@quiet/common' +import { ONION_ADDRESS_REGEX, composeInvitationShareUrl, parseName } from '@quiet/common' import { getInvitationCodes } from '@quiet/state-manager' const PREFIX = 'PerformCommunityActionComponent' @@ -221,7 +221,7 @@ export const PerformCommunityActionComponent: React.FC<PerformCommunityActionPro useEffect(() => { if (communityOwnership === CommunityOwnership.User && invitationCode?.length && psk) { setFormSent(true) - setValue('name', composeToInvitationShareUrl({ pairs: invitationCode, psk: psk })) + setValue('name', composeInvitationShareUrl({ pairs: invitationCode, psk: psk })) } }, [communityOwnership, invitationCode]) diff --git a/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx b/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx index 829cfcdffa..80e8663143 100644 --- a/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx +++ b/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx @@ -10,9 +10,9 @@ import { InviteComponent } from './Tabs/Invite/Invite.component' import { LeaveCommunityComponent } from './Tabs/LeaveCommunity/LeaveCommunityComponent' import { Typography } from '@mui/material' import { QRCodeComponent } from './Tabs/QRCode/QRCode.component' -import { composeToInvitationShareUrl } from '@quiet/common' +import { composeInvitationShareUrl } from '@quiet/common' -const invitationLink = composeToInvitationShareUrl({ +const invitationLink = composeInvitationShareUrl({ pairs: [ { peerId: 'QmVTkUad2Gq3MkCa8gf12R1gsWDfk2yiTEqb6YGXDG2iQ3', diff --git a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx index 3e3508c114..62e01e5e9f 100644 --- a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx +++ b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx @@ -2,11 +2,11 @@ import '@testing-library/jest-dom' import React from 'react' import { renderComponent } from '../../../../testUtils/renderComponent' import { InviteComponent } from './Invite.component' -import { composeToInvitationShareUrl } from '@quiet/common' +import { composeInvitationShareUrl } from '@quiet/common' describe('CopyLink', () => { it('renderComponent - hidden long link', () => { - const invitationLink = composeToInvitationShareUrl({ + const invitationLink = composeInvitationShareUrl({ pairs: [ { peerId: 'QmVTkUad2Gq3MkCa8gf12R1gsWDfk2yiTEqb6YGXDG2iQ3', @@ -127,7 +127,7 @@ describe('CopyLink', () => { }) it('renderComponent - revealed short link', () => { - const invitationLink = composeToInvitationShareUrl({ + const invitationLink = composeInvitationShareUrl({ pairs: [ { peerId: 'QmVTkUad2Gq3MkCa8gf12R1gsWDfk2yiTEqb6YGXDG2iQ3', diff --git a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx index 66530189df..95849b7ca6 100644 --- a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx +++ b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx @@ -2,7 +2,7 @@ import React from 'react' import { ComponentStory, ComponentMeta } from '@storybook/react' import { withTheme } from '../../../../storybook/decorators' import { InviteComponent, InviteComponentProps } from './Invite.component' -import { composeToInvitationShareUrl } from '@quiet/common' +import { composeInvitationShareUrl } from '@quiet/common' const Template: ComponentStory<typeof InviteComponent> = args => { return <InviteComponent {...args} /> @@ -10,7 +10,7 @@ const Template: ComponentStory<typeof InviteComponent> = args => { export const Component = Template.bind({}) let revealInputValue = true -const invitationLink = composeToInvitationShareUrl({ +const invitationLink = composeInvitationShareUrl({ pairs: [ { peerId: 'QmVTkUad2Gq3MkCa8gf12R1gsWDfk2yiTEqb6YGXDG2iQ3', diff --git a/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx b/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx index 888340710d..3eee7762eb 100644 --- a/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx +++ b/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx @@ -3,9 +3,9 @@ import { ComponentStory, ComponentMeta } from '@storybook/react' import { withTheme } from '../../../../storybook/decorators' import QRCodeComponent, { QRCodeProps } from './QRCode.component' -import { composeToInvitationShareUrl } from '@quiet/common' +import { composeInvitationShareUrl } from '@quiet/common' -const invitationLink = composeToInvitationShareUrl({ +const invitationLink = composeInvitationShareUrl({ pairs: [ { peerId: 'QmVTkUad2Gq3MkCa8gf12R1gsWDfk2yiTEqb6YGXDG2iQ3', diff --git a/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts b/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts index 90f456d3b1..a87ef32a81 100644 --- a/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts +++ b/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts @@ -1,15 +1,18 @@ import { getInvitationCodes } from './invitationCode' -import { QUIET_JOIN_PAGE } from '@quiet/common' +import { QUIET_JOIN_PAGE, Site } from '@quiet/common' describe('Invitation code helper', () => { const peerId1 = 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSA' const address1 = 'gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad' const peerId2 = 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE' const address2 = 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdvcbzw5vex2crsr26qd' + const psk = 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw=' + const encodedPsk = encodeURIComponent(psk) it('retrieves invitation code if url is a proper share url', () => { - const psk = 'abcde' - const result = getInvitationCodes(`${QUIET_JOIN_PAGE}#${peerId1}=${address1}&${peerId2}=${address2}&k=${psk}`) + const result = getInvitationCodes( + `${QUIET_JOIN_PAGE}#${peerId1}=${address1}&${peerId2}=${address2}&${Site.PSK_PARAM_KEY}=${encodedPsk}` + ) expect(result).toEqual({ pairs: [ { peerId: peerId1, onionAddress: address1 }, @@ -20,7 +23,6 @@ describe('Invitation code helper', () => { }) it('throws error if code is not a proper share url nor a code', () => { - // const result = 'invalidCode') expect(() => getInvitationCodes('invalidCode')).toThrow() }) @@ -28,9 +30,16 @@ describe('Invitation code helper', () => { expect(() => getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}`)).toThrow() }) + it('throws error if psk has invalid format', () => { + expect(() => + getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}&${Site.PSK_PARAM_KEY}=12345`) + ).toThrow() + }) + it('retrieves invitation code if url is a proper code', () => { - const psk = 'abcde' - const result = getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}&k=${psk}`) + const result = getInvitationCodes( + `${peerId1}=${address1}&${peerId2}=${address2}&${Site.PSK_PARAM_KEY}=${encodedPsk}` + ) expect(result).toEqual({ pairs: [ { peerId: peerId1, onionAddress: address1 }, @@ -41,8 +50,9 @@ describe('Invitation code helper', () => { }) it('retrieves invitation code if url is a proper code', () => { - const psk = 'abcde' - const result = getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}&k=${psk}`) + const result = getInvitationCodes( + `${peerId1}=${address1}&${peerId2}=${address2}&${Site.PSK_PARAM_KEY}=${encodedPsk}` + ) expect(result).toEqual({ pairs: [ { peerId: peerId1, onionAddress: address1 },