Skip to content

Commit

Permalink
Standardize peer address param
Browse files Browse the repository at this point in the history
  • Loading branch information
islathehut committed Nov 19, 2024
1 parent 672d384 commit b355742
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 89 deletions.
1 change: 1 addition & 0 deletions packages/common/src/invitationLink/invitationLink.const.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// V1 invitation code format (p2p without relay)
export const PSK_PARAM_KEY = 'k'
export const OWNER_ORBIT_DB_IDENTITY_PARAM_KEY = 'o'
export const PEER_ADDRESS_KEY = 'p'

// v2 invitation code format (v1 with LFA integration)
export const AUTH_DATA_KEY = 'a'
Expand Down
85 changes: 73 additions & 12 deletions packages/common/src/invitationLink/invitationLink.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import {
composeInvitationShareUrl,
parseInvitationLinkDeepUrl,
p2pAddressesToPairs,
peerPairsToUrlParamString,
} from './invitationLink'
import {
PSK_PARAM_KEY,
OWNER_ORBIT_DB_IDENTITY_PARAM_KEY,
DEEP_URL_SCHEME_WITH_SEPARATOR,
AUTH_DATA_KEY,
PEER_ADDRESS_KEY,
} from './invitationLink.const'
import { QUIET_JOIN_PAGE } from '../const'
import { validInvitationDatav1, validInvitationDatav2 } from '../tests'
Expand All @@ -25,8 +27,7 @@ describe(`Invitation link helper ${InvitationDataVersion.v1}`, () => {
pairs: [...validInvitationDatav1[0].pairs, { peerId: peerId, onionAddress: address }],
}
const urlParams = [
[data.pairs[0].peerId, data.pairs[0].onionAddress],
[data.pairs[1].peerId, data.pairs[1].onionAddress],
[PEER_ADDRESS_KEY, peerPairsToUrlParamString([data.pairs[0], data.pairs[1]])],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
]
Expand Down Expand Up @@ -127,8 +128,7 @@ describe(`Invitation link helper ${InvitationDataVersion.v2}`, () => {
pairs: [...validInvitationDatav1[0].pairs, { peerId: peerId, onionAddress: address }],
}
const urlParams = [
[data.pairs[0].peerId, data.pairs[0].onionAddress],
[data.pairs[1].peerId, data.pairs[1].onionAddress],
[PEER_ADDRESS_KEY, peerPairsToUrlParamString([data.pairs[0], data.pairs[1]])],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[AUTH_DATA_KEY, encodeAuthData(data.authData)],
Expand Down Expand Up @@ -189,8 +189,7 @@ describe(`Invitation link helper ${InvitationDataVersion.v2}`, () => {
it('throw error if auth data string is invalid', () => {
const url = new URL(DEEP_URL_SCHEME_WITH_SEPARATOR)
const urlParams = [
[data.pairs[0].peerId, data.pairs[0].onionAddress],
[data.pairs[1].peerId, data.pairs[1].onionAddress],
[PEER_ADDRESS_KEY, peerPairsToUrlParamString([data.pairs[0], data.pairs[1]])],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[AUTH_DATA_KEY, '()_*'],
Expand All @@ -205,11 +204,46 @@ describe(`Invitation link helper ${InvitationDataVersion.v2}`, () => {
}
})

it('throw error if peer address param is present but no valid addresses are found', () => {
const url = new URL(DEEP_URL_SCHEME_WITH_SEPARATOR)
const urlParams = [
[PEER_ADDRESS_KEY, 'foobar'],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[AUTH_DATA_KEY, encodeAuthData(data.authData)],
]
urlParams.forEach(([key, value]) => url.searchParams.append(key, value))

try {
const parsed = parseInvitationLinkDeepUrl(url.href)
expect(parsed).toBe(null)
} catch (e) {
expect(e.message).toContain(`Invalid value 'foobar' for key 'p' in invitation link`)
}
})

// TODO: TECH DEBT: Get rid of when we go to 3.0
it('LEGACY - throw error if no peer pairs are found as named param or dynamic params', () => {
const url = new URL(DEEP_URL_SCHEME_WITH_SEPARATOR)
const urlParams = [
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[AUTH_DATA_KEY, encodeAuthData(data.authData)],
]
urlParams.forEach(([key, value]) => url.searchParams.append(key, value))

try {
const parsed = parseInvitationLinkDeepUrl(url.href)
expect(parsed).toBe(null)
} catch (e) {
expect(e.message).toContain(`No valid peer addresses found in invitation link`)
}
})

it('throw error if community name is invalid', () => {
const url = new URL(DEEP_URL_SCHEME_WITH_SEPARATOR)
const urlParams = [
[data.pairs[0].peerId, data.pairs[0].onionAddress],
[data.pairs[1].peerId, data.pairs[1].onionAddress],
[PEER_ADDRESS_KEY, peerPairsToUrlParamString([data.pairs[0], data.pairs[1]])],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[
Expand All @@ -233,8 +267,7 @@ describe(`Invitation link helper ${InvitationDataVersion.v2}`, () => {
it('throw error if seed is invalid', () => {
const url = new URL(DEEP_URL_SCHEME_WITH_SEPARATOR)
const urlParams = [
[data.pairs[0].peerId, data.pairs[0].onionAddress],
[data.pairs[1].peerId, data.pairs[1].onionAddress],
[PEER_ADDRESS_KEY, peerPairsToUrlParamString([data.pairs[0], data.pairs[1]])],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[
Expand Down Expand Up @@ -273,16 +306,44 @@ describe(`Invitation link helper ${InvitationDataVersion.v2}`, () => {

it('retrieves invitation data from deep url with partly invalid addresses', () => {
const urlParamsWithInvalidAddress = [
[
PEER_ADDRESS_KEY,
peerPairsToUrlParamString([
data.pairs[0],
data.pairs[1],
{
peerId: 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wf',
onionAddress: 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdv',
},
]),
],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[AUTH_DATA_KEY, encodeAuthData(data.authData)],
]

const url = new URL(DEEP_URL_SCHEME_WITH_SEPARATOR)
urlParamsWithInvalidAddress.forEach(([key, value]) => url.searchParams.append(key, value))

const parsed = parseInvitationLinkDeepUrl(url.href)
expect(parsed).toEqual({
version: InvitationDataVersion.v2,
...data,
})
})

// TODO: TECH DEBT: Get rid of when we go to 3.0
it('LEGACY - retrieves invitation data from url with dynamic peer address params', () => {
const urlParamsWithDynamicPeerParams = [
[data.pairs[0].peerId, data.pairs[0].onionAddress],
[data.pairs[1].peerId, data.pairs[1].onionAddress],
['QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wf', 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdv'],
[PSK_PARAM_KEY, data.psk],
[OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity],
[AUTH_DATA_KEY, encodeAuthData(data.authData)],
]

const url = new URL(DEEP_URL_SCHEME_WITH_SEPARATOR)
urlParamsWithInvalidAddress.forEach(([key, value]) => url.searchParams.append(key, value))
urlParamsWithDynamicPeerParams.forEach(([key, value]) => url.searchParams.append(key, value))

const parsed = parseInvitationLinkDeepUrl(url.href)
expect(parsed).toEqual({
Expand Down
17 changes: 11 additions & 6 deletions packages/common/src/invitationLink/invitationLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
DEEP_URL_SCHEME,
DEEP_URL_SCHEME_WITH_SEPARATOR,
OWNER_ORBIT_DB_IDENTITY_PARAM_KEY,
PEER_ADDRESS_KEY,
PSK_PARAM_KEY,
} from './invitationLink.const'
import {
Expand Down Expand Up @@ -205,6 +206,14 @@ export const composeInvitationDeepUrl = (data: InvitationData): string => {
return composeInvitationUrl(`${DEEP_URL_SCHEME_WITH_SEPARATOR}`, data)
}

export const peerPairsToUrlParamString = (pairs: InvitationPair[]): string => {
const commaSeparatedPairs: string[] = []
for (const pair of pairs) {
commaSeparatedPairs.push(`${pair.peerId},${pair.onionAddress}`)
}
return commaSeparatedPairs.join(';')
}

/**
* Given a base URL (e.g. `quiet://`) and an InvitationData object determine the version of the invite data and
* convert to URL parameters and return the completed invite link
Expand All @@ -221,16 +230,12 @@ const composeInvitationUrl = (baseUrl: string, data: InvitationDataV1 | Invitati

switch (data.version) {
case InvitationDataVersion.v1:
for (const pair of data.pairs) {
url.searchParams.append(pair.peerId, pair.onionAddress)
}
url.searchParams.append(PEER_ADDRESS_KEY, peerPairsToUrlParamString(data.pairs))
url.searchParams.append(PSK_PARAM_KEY, data.psk)
url.searchParams.append(OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity)
break
case InvitationDataVersion.v2:
for (const pair of data.pairs) {
url.searchParams.append(pair.peerId, pair.onionAddress)
}
url.searchParams.append(PEER_ADDRESS_KEY, peerPairsToUrlParamString(data.pairs))
url.searchParams.append(PSK_PARAM_KEY, data.psk)
url.searchParams.append(OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity)
url.searchParams.append(AUTH_DATA_KEY, encodeAuthData(data.authData))
Expand Down
Loading

0 comments on commit b355742

Please sign in to comment.