diff --git a/ts/test-both/util/getProvisioningUrl_test.ts b/ts/test-both/util/getProvisioningUrl_test.ts new file mode 100644 index 000000000000..6c415ff659ca --- /dev/null +++ b/ts/test-both/util/getProvisioningUrl_test.ts @@ -0,0 +1,23 @@ +// Copyright 2021 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { assert } from 'chai'; +import { size } from '../../util/iterables'; + +import { getProvisioningUrl } from '../../util/getProvisioningUrl'; + +describe('getProvisioningUrl', () => { + it('returns a URL with a UUID and public key', () => { + const uuid = 'a08bf1fd-1799-427f-a551-70af747e3956'; + const publicKey = new Uint8Array([9, 8, 7, 6, 5, 4, 3]); + + const result = getProvisioningUrl(uuid, publicKey); + const resultUrl = new URL(result); + + assert(result.startsWith('tsdevice:/?')); + assert.strictEqual(resultUrl.protocol, 'tsdevice:'); + assert.strictEqual(size(resultUrl.searchParams.entries()), 2); + assert.strictEqual(resultUrl.searchParams.get('uuid'), uuid); + assert.strictEqual(resultUrl.searchParams.get('pub_key'), 'CQgHBgUEAw=='); + }); +}); diff --git a/ts/textsecure/AccountManager.ts b/ts/textsecure/AccountManager.ts index b859f3aa1116..c4d6cf5a6f75 100644 --- a/ts/textsecure/AccountManager.ts +++ b/ts/textsecure/AccountManager.ts @@ -1,4 +1,4 @@ -// Copyright 2020 Signal Messenger, LLC +// Copyright 2020-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only /* eslint-disable @typescript-eslint/no-explicit-any */ @@ -29,6 +29,7 @@ import { } from '../Curve'; import { isMoreRecentThan, isOlderThan } from '../util/timestamp'; import { ourProfileKeyService } from '../services/ourProfileKey'; +import { getProvisioningUrl } from '../util/getProvisioningUrl'; const ARCHIVE_AGE = 30 * 24 * 60 * 60 * 1000; const PREKEY_ROTATION_AGE = 24 * 60 * 60 * 1000; @@ -222,12 +223,11 @@ export default class AccountManager extends EventTarget { const proto = window.textsecure.protobuf.ProvisioningUuid.decode( request.body ); - const url = [ - 'tsdevice:/?uuid=', - proto.uuid, - '&pub_key=', - encodeURIComponent(btoa(utils.getString(pubKey))), - ].join(''); + const { uuid } = proto; + if (!uuid) { + throw new Error('registerSecondDevice: expected a UUID'); + } + const url = getProvisioningUrl(uuid, pubKey); if (window.CI) { window.CI.setProvisioningURL(url); diff --git a/ts/util/getProvisioningUrl.ts b/ts/util/getProvisioningUrl.ts new file mode 100644 index 000000000000..ce143b511570 --- /dev/null +++ b/ts/util/getProvisioningUrl.ts @@ -0,0 +1,15 @@ +// Copyright 2021 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +import { arrayBufferToBase64 } from '../Crypto'; + +export function getProvisioningUrl( + uuid: string, + publicKey: ArrayBuffer +): string { + const params = new URLSearchParams({ + uuid, + pub_key: arrayBufferToBase64(publicKey), + }); + return `tsdevice:/?${params.toString()}`; +}