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 8ab0b5988d..7a804d7b60 100644 --- a/packages/backend/src/nest/connections-manager/connections-manager.service.ts +++ b/packages/backend/src/nest/connections-manager/connections-manager.service.ts @@ -62,6 +62,7 @@ import Logger from '../common/logger' import { emitError } from '../socket/socket.errors' import { toString as uint8ArrayToString } from 'uint8arrays/to-string' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import { isPSKcodeValid } from '@quiet/common' @Injectable() export class ConnectionsManagerService extends EventEmitter implements OnModuleInit { @@ -280,7 +281,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI const psk = community.psk if (psk) { console.log('createNetwork got psk', psk) - if (!validator.isBase64(psk)) { + if (!isPSKcodeValid(psk)) { emitError(this.serverIoProvider.io, { type: SocketActionTypes.NETWORK, message: ErrorMessages.NETWORK_SETUP_FAILED, diff --git a/packages/common/src/invitationCode.test.ts b/packages/common/src/invitationCode.test.ts index f44588fe1f..ed405f723c 100644 --- a/packages/common/src/invitationCode.test.ts +++ b/packages/common/src/invitationCode.test.ts @@ -70,7 +70,7 @@ describe('Invitation code helper', () => { expect(composeInvitationShareUrl(pairs)).toEqual(expected) }) - it('builds proper invitation share url', () => { + it('builds proper invitation share url from peers addresses', () => { const peerList = [ '/dns4/gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad.onion/tcp/443/wss/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE', 'invalidAddress', @@ -94,6 +94,17 @@ describe('Invitation code helper', () => { }) }) + it.each([['12345'], ['a2FzemE='], 'a2FycGllIHcgZ2FsYXJlY2llIGVjaWUgcGVjaWUgYWxlIGkgdGFrIHpqZWNpZQ=='])( + 'parsing invitation code throws error if psk is invalid: (%s)', + (psk: string) => { + expect(() => { + parseInvitationCodeDeepUrl( + `quiet://?${peerId1}=${address1}&${peerId2}=${address2}&${Site.PSK_PARAM_KEY}=${psk}` + ) + }).toThrow() + } + ) + it('retrieves invitation codes from deep url with partly invalid codes', () => { const peerId2 = 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLs' const address2 = 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdvcbzw5vex2crsr26qd' diff --git a/packages/common/src/invitationCode.ts b/packages/common/src/invitationCode.ts index 4cc50616b8..ab3bf0b50a 100644 --- a/packages/common/src/invitationCode.ts +++ b/packages/common/src/invitationCode.ts @@ -1,6 +1,6 @@ import { InvitationData, InvitationPair } from '@quiet/types' -import { ONION_ADDRESS_REGEX, PEER_ID_REGEX, QUIET_JOIN_PAGE, Site } from './static' -import { createLibp2pAddress } from './libp2p' +import { ONION_ADDRESS_REGEX, PEER_ID_REGEX, PSK_LENGTH, QUIET_JOIN_PAGE, Site } from './static' +import { createLibp2pAddress, isPSKcodeValid } from './libp2p' import validator from 'validator' const parseDeepUrl = ({ url, expectedProtocol = `quiet:` }: { url: string; expectedProtocol?: string }) => { @@ -29,7 +29,7 @@ const parseDeepUrl = ({ url, expectedProtocol = `quiet:` }: { url: string; expec if (!psk) throw new Error(`No psk found in invitation code '${url}'`) psk = decodeURIComponent(psk) - if (!validator.isBase64(psk)) throw new Error(`Invalid psk in invitation code '${url}'`) + if (!isPSKcodeValid(psk)) throw new Error(`Invalid psk in invitation code '${url}'`) params.delete(Site.PSK_PARAM_KEY) diff --git a/packages/common/src/libp2p.ts b/packages/common/src/libp2p.ts index e86ee508e2..24154f8e4e 100644 --- a/packages/common/src/libp2p.ts +++ b/packages/common/src/libp2p.ts @@ -1,3 +1,6 @@ +import validator from 'validator' +import { PSK_LENGTH } from './static' + const ONION = '.onion' export const createLibp2pAddress = (address: string, peerId: string) => { @@ -9,3 +12,8 @@ export const createLibp2pListenAddress = (address: string) => { if (!address.endsWith(ONION)) address += ONION return `/dns4/${address}/tcp/80/ws` } + +export const isPSKcodeValid = (psk: string): boolean => { + const _psk = psk.trim() + return validator.isBase64(_psk) && _psk.length === PSK_LENGTH +} diff --git a/packages/common/src/static.ts b/packages/common/src/static.ts index df3b741511..aad1efffa4 100644 --- a/packages/common/src/static.ts +++ b/packages/common/src/static.ts @@ -1,5 +1,6 @@ export const ONION_ADDRESS_REGEX = /^[a-z0-9]{56}$/g export const PEER_ID_REGEX = /^[a-zA-Z0-9]{46}$/g +export const PSK_LENGTH = 44 // PSK is 256 bits/8 = 32 bytes which encodes to 44 characters base64 export enum Site { DEEP_URL_SCHEME_WITH_SEPARATOR = 'quiet://',