Revert "Add urlPath util for building escaped URL paths"
This commit is contained in:
parent
cd50c715a9
commit
03ed42188e
3 changed files with 75 additions and 146 deletions
|
@ -7,8 +7,7 @@ import { size } from '../../util/iterables';
|
||||||
import {
|
import {
|
||||||
maybeParseUrl,
|
maybeParseUrl,
|
||||||
setUrlSearchParams,
|
setUrlSearchParams,
|
||||||
urlPath,
|
urlPathFromComponents,
|
||||||
urlPathJoin,
|
|
||||||
} from '../../util/url';
|
} from '../../util/url';
|
||||||
|
|
||||||
describe('URL utilities', () => {
|
describe('URL utilities', () => {
|
||||||
|
@ -86,43 +85,17 @@ describe('URL utilities', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('urlPath', () => {
|
describe('urlPathFromComponents', () => {
|
||||||
it('escapes values', () => {
|
it('returns / if no components are provided', () => {
|
||||||
|
assert.strictEqual(urlPathFromComponents([]), '/');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('joins components, percent-encoding them and removing empty components', () => {
|
||||||
|
const components = ['foo', '', '~', 'bar / baz qúx'];
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
urlPath`/path/to/${' %?&='}/${true}/${42}`.toString(),
|
urlPathFromComponents(components),
|
||||||
'/path/to/%20%25%3F%26%3D/true/42'
|
'/foo/~/bar%20%2F%20baz%20q%C3%BAx'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('doesnt escape nested url paths', () => {
|
|
||||||
assert.strictEqual(
|
|
||||||
urlPath`${urlPath`/path?param=true`}&other=${' %?&='}`.toString(),
|
|
||||||
'/path?param=true&other=%20%25%3F%26%3D'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('urlPathJoin', () => {
|
|
||||||
it('escapes values', () => {
|
|
||||||
assert.strictEqual(
|
|
||||||
urlPathJoin([' %?&=', true, 42], '&').toString(),
|
|
||||||
'%20%25%3F%26%3D&true&42'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('doesnt escape nested url paths', () => {
|
|
||||||
assert.strictEqual(
|
|
||||||
urlPathJoin([urlPath`/path?param=true`, ' %?&='], '&').toString(),
|
|
||||||
'/path?param=true&%20%25%3F%26%3D'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works with empty arrays', () => {
|
|
||||||
assert.strictEqual(urlPathJoin([], '&').toString(), '');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works with single items', () => {
|
|
||||||
assert.strictEqual(urlPathJoin(['hi'], '&').toString(), 'hi');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -67,8 +67,7 @@ import type {
|
||||||
} from './Types.d';
|
} from './Types.d';
|
||||||
import { handleStatusCode, translateError } from './Utils';
|
import { handleStatusCode, translateError } from './Utils';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import type { UrlPath } from '../util/url';
|
import { maybeParseUrl, urlPathFromComponents } from '../util/url';
|
||||||
import { urlPathJoin, maybeParseUrl, urlPath } from '../util/url';
|
|
||||||
import { SECOND } from '../util/durations';
|
import { SECOND } from '../util/durations';
|
||||||
import { safeParseNumber } from '../util/numbers';
|
import { safeParseNumber } from '../util/numbers';
|
||||||
import { isStagingServer } from '../util/isStagingServer';
|
import { isStagingServer } from '../util/isStagingServer';
|
||||||
|
@ -718,7 +717,7 @@ type AjaxOptionsType = {
|
||||||
responseType?: 'json' | 'bytes' | 'byteswithdetails' | 'stream';
|
responseType?: 'json' | 'bytes' | 'byteswithdetails' | 'stream';
|
||||||
schema?: unknown;
|
schema?: unknown;
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
urlParameters?: UrlPath;
|
urlParameters?: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
validateResponse?: any;
|
validateResponse?: any;
|
||||||
isRegistration?: true;
|
isRegistration?: true;
|
||||||
|
@ -1866,7 +1865,7 @@ export function initialize({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!param.urlParameters) {
|
if (!param.urlParameters) {
|
||||||
param.urlParameters = urlPath``;
|
param.urlParameters = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const useWebSocketForEndpoint =
|
const useWebSocketForEndpoint =
|
||||||
|
@ -1883,7 +1882,7 @@ export function initialize({
|
||||||
headers: param.headers,
|
headers: param.headers,
|
||||||
host: param.host || url,
|
host: param.host || url,
|
||||||
password: param.password ?? password,
|
password: param.password ?? password,
|
||||||
path: URL_CALLS[param.call] + param.urlParameters.toString(),
|
path: URL_CALLS[param.call] + param.urlParameters,
|
||||||
proxyUrl,
|
proxyUrl,
|
||||||
responseType: param.responseType,
|
responseType: param.responseType,
|
||||||
timeout: param.timeout,
|
timeout: param.timeout,
|
||||||
|
@ -2046,7 +2045,7 @@ export function initialize({
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
validateResponse: { certificate: 'string' },
|
validateResponse: { certificate: 'string' },
|
||||||
...(omitE164 ? { urlParameters: urlPath`?includeE164=false` } : {}),
|
...(omitE164 ? { urlParameters: '?includeE164=false' } : {}),
|
||||||
})) as GetSenderCertificateResultType;
|
})) as GetSenderCertificateResultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2085,8 +2084,8 @@ export function initialize({
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
responseType: 'byteswithdetails',
|
responseType: 'byteswithdetails',
|
||||||
urlParameters: greaterThanVersion
|
urlParameters: greaterThanVersion
|
||||||
? urlPath`/version/${greaterThanVersion}`
|
? `/version/${greaterThanVersion}`
|
||||||
: urlPath``,
|
: '',
|
||||||
...credentials,
|
...credentials,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2178,11 +2177,13 @@ export function initialize({
|
||||||
profileKeyCredentialRequest,
|
profileKeyCredentialRequest,
|
||||||
}: GetProfileCommonOptionsType
|
}: GetProfileCommonOptionsType
|
||||||
) {
|
) {
|
||||||
let profileUrl = urlPath`/${serviceId}`;
|
let profileUrl = `/${serviceId}`;
|
||||||
if (profileKeyVersion !== undefined) {
|
if (profileKeyVersion !== undefined) {
|
||||||
profileUrl = urlPath`${profileUrl}/${profileKeyVersion}`;
|
profileUrl += `/${profileKeyVersion}`;
|
||||||
if (profileKeyCredentialRequest !== undefined) {
|
if (profileKeyCredentialRequest !== undefined) {
|
||||||
profileUrl = urlPath`${profileUrl}/${profileKeyCredentialRequest}?credentialType=expiringProfileKey`;
|
profileUrl +=
|
||||||
|
`/${profileKeyCredentialRequest}` +
|
||||||
|
'?credentialType=expiringProfileKey';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strictAssert(
|
strictAssert(
|
||||||
|
@ -2225,7 +2226,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'username',
|
call: 'username',
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
urlParameters: urlPath`/${hashBase64}`,
|
urlParameters: `/${hashBase64}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
redactUrl: _createRedactor(hashBase64),
|
redactUrl: _createRedactor(hashBase64),
|
||||||
unauthenticated: true,
|
unauthenticated: true,
|
||||||
|
@ -2442,7 +2443,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
call: 'usernameLink',
|
call: 'usernameLink',
|
||||||
urlParameters: urlPath`/${serverId}`,
|
urlParameters: `/${encodeURIComponent(serverId)}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
unauthenticated: true,
|
unauthenticated: true,
|
||||||
accessKey: undefined,
|
accessKey: undefined,
|
||||||
|
@ -2461,7 +2462,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'reportMessage',
|
call: 'reportMessage',
|
||||||
httpType: 'POST',
|
httpType: 'POST',
|
||||||
urlParameters: urlPath`/${senderAci}/${serverGuid}`,
|
urlParameters: urlPathFromComponents([senderAci, serverGuid]),
|
||||||
responseType: 'bytes',
|
responseType: 'bytes',
|
||||||
jsonData,
|
jsonData,
|
||||||
});
|
});
|
||||||
|
@ -2492,7 +2493,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'verificationSession',
|
call: 'verificationSession',
|
||||||
httpType: 'PATCH',
|
httpType: 'PATCH',
|
||||||
urlParameters: urlPath`/${session.id}`,
|
urlParameters: `/${encodeURIComponent(session.id)}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
jsonData: {
|
jsonData: {
|
||||||
captcha,
|
captcha,
|
||||||
|
@ -2513,7 +2514,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'verificationSession',
|
call: 'verificationSession',
|
||||||
httpType: 'POST',
|
httpType: 'POST',
|
||||||
urlParameters: urlPath`/${session.id}/code`,
|
urlParameters: `/${encodeURIComponent(session.id)}/code`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
jsonData: {
|
jsonData: {
|
||||||
client: 'ios',
|
client: 'ios',
|
||||||
|
@ -2535,7 +2536,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
httpType: 'HEAD',
|
httpType: 'HEAD',
|
||||||
call: 'accountExistence',
|
call: 'accountExistence',
|
||||||
urlParameters: urlPath`/${serviceId}`,
|
urlParameters: `/${serviceId}`,
|
||||||
unauthenticated: true,
|
unauthenticated: true,
|
||||||
accessKey: undefined,
|
accessKey: undefined,
|
||||||
groupSendToken: undefined,
|
groupSendToken: undefined,
|
||||||
|
@ -2621,7 +2622,7 @@ export function initialize({
|
||||||
isRegistration: true,
|
isRegistration: true,
|
||||||
call: 'verificationSession',
|
call: 'verificationSession',
|
||||||
httpType: 'PUT',
|
httpType: 'PUT',
|
||||||
urlParameters: urlPath`/${sessionId}/code`,
|
urlParameters: `/${encodeURIComponent(sessionId)}/code`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
jsonData: {
|
jsonData: {
|
||||||
code,
|
code,
|
||||||
|
@ -2738,7 +2739,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'devices',
|
call: 'devices',
|
||||||
httpType: 'DELETE',
|
httpType: 'DELETE',
|
||||||
urlParameters: urlPath`/${deviceId}`,
|
urlParameters: `/${deviceId}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2823,7 +2824,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
isRegistration: true,
|
isRegistration: true,
|
||||||
call: 'keys',
|
call: 'keys',
|
||||||
urlParameters: urlPath`?${serviceIdKindToQuery(serviceIdKind)}`,
|
urlParameters: `?${serviceIdKindToQuery(serviceIdKind)}`,
|
||||||
httpType: 'PUT',
|
httpType: 'PUT',
|
||||||
jsonData: keys,
|
jsonData: keys,
|
||||||
});
|
});
|
||||||
|
@ -2853,7 +2854,7 @@ export function initialize({
|
||||||
abortSignal,
|
abortSignal,
|
||||||
}: GetBackupStreamOptionsType): Promise<Readable> {
|
}: GetBackupStreamOptionsType): Promise<Readable> {
|
||||||
return _getAttachment({
|
return _getAttachment({
|
||||||
cdnPath: urlPath`/backups/${backupDir}/${backupName}`,
|
cdnPath: `/backups/${encodeURIComponent(backupDir)}/${encodeURIComponent(backupName)}`,
|
||||||
cdnNumber: cdn,
|
cdnNumber: cdn,
|
||||||
redactor: _createRedactor(backupDir, backupName),
|
redactor: _createRedactor(backupDir, backupName),
|
||||||
headers,
|
headers,
|
||||||
|
@ -2953,7 +2954,9 @@ export function initialize({
|
||||||
const res = await _ajax({
|
const res = await _ajax({
|
||||||
call: 'getBackupCredentials',
|
call: 'getBackupCredentials',
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
urlParameters: urlPath`?redemptionStartSeconds=${startDayInSeconds}&redemptionEndSeconds=${endDayInSeconds}`,
|
urlParameters:
|
||||||
|
`?redemptionStartSeconds=${startDayInSeconds}&` +
|
||||||
|
`redemptionEndSeconds=${endDayInSeconds}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2971,7 +2974,7 @@ export function initialize({
|
||||||
accessKey: undefined,
|
accessKey: undefined,
|
||||||
groupSendToken: undefined,
|
groupSendToken: undefined,
|
||||||
headers,
|
headers,
|
||||||
urlParameters: urlPath`?cdn=${cdn}`,
|
urlParameters: `?cdn=${cdn}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3077,12 +3080,12 @@ export function initialize({
|
||||||
cursor,
|
cursor,
|
||||||
limit,
|
limit,
|
||||||
}: BackupListMediaOptionsType) {
|
}: BackupListMediaOptionsType) {
|
||||||
const params: Array<UrlPath> = [];
|
const params = new Array<string>();
|
||||||
|
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
params.push(urlPath`cursor=${cursor}`);
|
params.push(`cursor=${encodeURIComponent(cursor)}`);
|
||||||
}
|
}
|
||||||
params.push(urlPath`limit=${limit}`);
|
params.push(`limit=${limit}`);
|
||||||
|
|
||||||
const res = await _ajax({
|
const res = await _ajax({
|
||||||
call: 'backupMedia',
|
call: 'backupMedia',
|
||||||
|
@ -3092,7 +3095,7 @@ export function initialize({
|
||||||
groupSendToken: undefined,
|
groupSendToken: undefined,
|
||||||
headers,
|
headers,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
urlParameters: urlPath`?${urlPathJoin(params, '&')}`,
|
urlParameters: `?${params.join('&')}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
return backupListMediaResponseSchema.parse(res);
|
return backupListMediaResponseSchema.parse(res);
|
||||||
|
@ -3125,7 +3128,7 @@ export function initialize({
|
||||||
): Promise<ServerKeyCountType> {
|
): Promise<ServerKeyCountType> {
|
||||||
const result = (await _ajax({
|
const result = (await _ajax({
|
||||||
call: 'keys',
|
call: 'keys',
|
||||||
urlParameters: urlPath`?${serviceIdKindToQuery(serviceIdKind)}`,
|
urlParameters: `?${serviceIdKindToQuery(serviceIdKind)}`,
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
validateResponse: { count: 'number', pqCount: 'number' },
|
validateResponse: { count: 'number', pqCount: 'number' },
|
||||||
|
@ -3227,7 +3230,7 @@ export function initialize({
|
||||||
const keys = (await _ajax({
|
const keys = (await _ajax({
|
||||||
call: 'keys',
|
call: 'keys',
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
urlParameters: urlPath`/${serviceId}/${deviceId || '*'}`,
|
urlParameters: `/${serviceId}/${deviceId || '*'}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
validateResponse: { identityKey: 'string', devices: 'object' },
|
validateResponse: { identityKey: 'string', devices: 'object' },
|
||||||
})) as ServerKeyResponseType;
|
})) as ServerKeyResponseType;
|
||||||
|
@ -3245,7 +3248,7 @@ export function initialize({
|
||||||
const keys = (await _ajax({
|
const keys = (await _ajax({
|
||||||
call: 'keys',
|
call: 'keys',
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
urlParameters: urlPath`/${serviceId}/${deviceId || '*'}`,
|
urlParameters: `/${serviceId}/${deviceId || '*'}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
validateResponse: { identityKey: 'string', devices: 'object' },
|
validateResponse: { identityKey: 'string', devices: 'object' },
|
||||||
unauthenticated: true,
|
unauthenticated: true,
|
||||||
|
@ -3281,7 +3284,7 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'messages',
|
call: 'messages',
|
||||||
httpType: 'PUT',
|
httpType: 'PUT',
|
||||||
urlParameters: urlPath`/${destination}?story=${story}`,
|
urlParameters: `/${destination}?story=${booleanToString(story)}`,
|
||||||
jsonData,
|
jsonData,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
unauthenticated: true,
|
unauthenticated: true,
|
||||||
|
@ -3310,12 +3313,16 @@ export function initialize({
|
||||||
await _ajax({
|
await _ajax({
|
||||||
call: 'messages',
|
call: 'messages',
|
||||||
httpType: 'PUT',
|
httpType: 'PUT',
|
||||||
urlParameters: urlPath`/${destination}?story=${story}`,
|
urlParameters: `/${destination}?story=${booleanToString(story)}`,
|
||||||
jsonData,
|
jsonData,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function booleanToString(value: boolean | undefined): string {
|
||||||
|
return value ? 'true' : 'false';
|
||||||
|
}
|
||||||
|
|
||||||
async function sendWithSenderKey(
|
async function sendWithSenderKey(
|
||||||
data: Uint8Array,
|
data: Uint8Array,
|
||||||
accessKeys: Uint8Array | undefined,
|
accessKeys: Uint8Array | undefined,
|
||||||
|
@ -3331,16 +3338,16 @@ export function initialize({
|
||||||
urgent?: boolean;
|
urgent?: boolean;
|
||||||
}
|
}
|
||||||
): Promise<MultiRecipient200ResponseType> {
|
): Promise<MultiRecipient200ResponseType> {
|
||||||
const onlineParam = urlPath`&online=${online ?? false}`;
|
const onlineParam = `&online=${booleanToString(online)}`;
|
||||||
const urgentParam = urlPath`&urgent=${urgent}`;
|
const urgentParam = `&urgent=${booleanToString(urgent)}`;
|
||||||
const storyParam = urlPath`&story=${story}`;
|
const storyParam = `&story=${booleanToString(story)}`;
|
||||||
|
|
||||||
const response = await _ajax({
|
const response = await _ajax({
|
||||||
call: 'multiRecipient',
|
call: 'multiRecipient',
|
||||||
httpType: 'PUT',
|
httpType: 'PUT',
|
||||||
contentType: 'application/vnd.signal-messenger.mrm',
|
contentType: 'application/vnd.signal-messenger.mrm',
|
||||||
data,
|
data,
|
||||||
urlParameters: urlPath`?ts=${timestamp}${onlineParam}${urgentParam}${storyParam}`,
|
urlParameters: `?ts=${timestamp}${onlineParam}${urgentParam}${storyParam}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
unauthenticated: true,
|
unauthenticated: true,
|
||||||
accessKey: accessKeys != null ? Bytes.toBase64(accessKeys) : undefined,
|
accessKey: accessKeys != null ? Bytes.toBase64(accessKeys) : undefined,
|
||||||
|
@ -3479,7 +3486,7 @@ export function initialize({
|
||||||
call: 'getStickerPackUpload',
|
call: 'getStickerPackUpload',
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
urlParameters: urlPath`/${encryptedStickers.length}`,
|
urlParameters: `/${encryptedStickers.length}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { packId, manifest, stickers } =
|
const { packId, manifest, stickers } =
|
||||||
|
@ -3545,7 +3552,7 @@ export function initialize({
|
||||||
};
|
};
|
||||||
}) {
|
}) {
|
||||||
return _getAttachment({
|
return _getAttachment({
|
||||||
cdnPath: urlPath`/attachments/${cdnKey}`,
|
cdnPath: `/attachments/${cdnKey}`,
|
||||||
cdnNumber: cdnNumber ?? 0,
|
cdnNumber: cdnNumber ?? 0,
|
||||||
redactor: _createRedactor(cdnKey),
|
redactor: _createRedactor(cdnKey),
|
||||||
options,
|
options,
|
||||||
|
@ -3572,7 +3579,7 @@ export function initialize({
|
||||||
};
|
};
|
||||||
}) {
|
}) {
|
||||||
return _getAttachment({
|
return _getAttachment({
|
||||||
cdnPath: urlPath`/backups/${backupDir}/${mediaDir}/${mediaId}`,
|
cdnPath: `/backups/${backupDir}/${mediaDir}/${mediaId}`,
|
||||||
cdnNumber,
|
cdnNumber,
|
||||||
headers,
|
headers,
|
||||||
redactor: _createRedactor(backupDir, mediaDir, mediaId),
|
redactor: _createRedactor(backupDir, mediaDir, mediaId),
|
||||||
|
@ -3587,7 +3594,7 @@ export function initialize({
|
||||||
redactor,
|
redactor,
|
||||||
options,
|
options,
|
||||||
}: {
|
}: {
|
||||||
cdnPath: UrlPath;
|
cdnPath: string;
|
||||||
cdnNumber: number;
|
cdnNumber: number;
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
redactor: RedactUrl;
|
redactor: RedactUrl;
|
||||||
|
@ -3620,7 +3627,7 @@ export function initialize({
|
||||||
if (options?.downloadOffset) {
|
if (options?.downloadOffset) {
|
||||||
targetHeaders.range = `bytes=${options.downloadOffset}-`;
|
targetHeaders.range = `bytes=${options.downloadOffset}-`;
|
||||||
}
|
}
|
||||||
streamWithDetails = await _outerAjax(`${cdnUrl}${cdnPath.toString()}`, {
|
streamWithDetails = await _outerAjax(`${cdnUrl}${cdnPath}`, {
|
||||||
headers: targetHeaders,
|
headers: targetHeaders,
|
||||||
certificateAuthority,
|
certificateAuthority,
|
||||||
disableRetries: options?.disableRetries,
|
disableRetries: options?.disableRetries,
|
||||||
|
@ -3682,7 +3689,7 @@ export function initialize({
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeoutStream = getTimeoutStream({
|
const timeoutStream = getTimeoutStream({
|
||||||
name: `getAttachment(${redactor(cdnPath.toString())})`,
|
name: `getAttachment(${redactor(cdnPath)})`,
|
||||||
timeout: GET_ATTACHMENT_CHUNK_TIMEOUT,
|
timeout: GET_ATTACHMENT_CHUNK_TIMEOUT,
|
||||||
abortController,
|
abortController,
|
||||||
});
|
});
|
||||||
|
@ -3947,7 +3954,10 @@ export function initialize({
|
||||||
const endDayInSeconds = endDayInMs / durations.SECOND;
|
const endDayInSeconds = endDayInMs / durations.SECOND;
|
||||||
const response = (await _ajax({
|
const response = (await _ajax({
|
||||||
call: 'getGroupCredentials',
|
call: 'getGroupCredentials',
|
||||||
urlParameters: urlPath`?redemptionStartSeconds=${startDayInSeconds}&redemptionEndSeconds=${endDayInSeconds}&zkcCredential=true`,
|
urlParameters:
|
||||||
|
`?redemptionStartSeconds=${startDayInSeconds}&` +
|
||||||
|
`redemptionEndSeconds=${endDayInSeconds}&` +
|
||||||
|
'zkcCredential=true',
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
})) as GetGroupCredentialsResultType;
|
})) as GetGroupCredentialsResultType;
|
||||||
|
@ -4140,7 +4150,7 @@ export function initialize({
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
responseType: 'bytes',
|
responseType: 'bytes',
|
||||||
urlParameters: safeInviteLinkPassword
|
urlParameters: safeInviteLinkPassword
|
||||||
? urlPath`${safeInviteLinkPassword}`
|
? `${safeInviteLinkPassword}`
|
||||||
: undefined,
|
: undefined,
|
||||||
redactUrl: _createRedactor(safeInviteLinkPassword),
|
redactUrl: _createRedactor(safeInviteLinkPassword),
|
||||||
});
|
});
|
||||||
|
@ -4172,7 +4182,7 @@ export function initialize({
|
||||||
httpType: 'PATCH',
|
httpType: 'PATCH',
|
||||||
responseType: 'bytes',
|
responseType: 'bytes',
|
||||||
urlParameters: safeInviteLinkPassword
|
urlParameters: safeInviteLinkPassword
|
||||||
? urlPath`?inviteLinkPassword=${safeInviteLinkPassword}`
|
? `?inviteLinkPassword=${safeInviteLinkPassword}`
|
||||||
: undefined,
|
: undefined,
|
||||||
redactUrl: safeInviteLinkPassword
|
redactUrl: safeInviteLinkPassword
|
||||||
? _createRedactor(safeInviteLinkPassword)
|
? _createRedactor(safeInviteLinkPassword)
|
||||||
|
@ -4233,7 +4243,11 @@ export function initialize({
|
||||||
headers: {
|
headers: {
|
||||||
'Cached-Send-Endorsements': String(cachedEndorsementsExpiration ?? 0),
|
'Cached-Send-Endorsements': String(cachedEndorsementsExpiration ?? 0),
|
||||||
},
|
},
|
||||||
urlParameters: urlPath`/${startVersion}?includeFirstState=${Boolean(includeFirstState)}&includeLastState=${Boolean(includeLastState)}&maxSupportedChangeEpoch=${Number(maxSupportedChangeEpoch)}`,
|
urlParameters:
|
||||||
|
`/${startVersion}?` +
|
||||||
|
`includeFirstState=${Boolean(includeFirstState)}&` +
|
||||||
|
`includeLastState=${Boolean(includeLastState)}&` +
|
||||||
|
`maxSupportedChangeEpoch=${Number(maxSupportedChangeEpoch)}`,
|
||||||
});
|
});
|
||||||
const { data, response } = withDetails;
|
const { data, response } = withDetails;
|
||||||
const changes = Proto.GroupChanges.decode(data);
|
const changes = Proto.GroupChanges.decode(data);
|
||||||
|
@ -4278,7 +4292,7 @@ export function initialize({
|
||||||
const data = await _ajax({
|
const data = await _ajax({
|
||||||
call: 'subscriptions',
|
call: 'subscriptions',
|
||||||
httpType: 'GET',
|
httpType: 'GET',
|
||||||
urlParameters: urlPath`/${formattedId}`,
|
urlParameters: `/${formattedId}`,
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
unauthenticated: true,
|
unauthenticated: true,
|
||||||
accessKey: undefined,
|
accessKey: undefined,
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { strictAssert } from './assert';
|
|
||||||
|
|
||||||
export function maybeParseUrl(value: string): undefined | URL {
|
export function maybeParseUrl(value: string): undefined | URL {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
try {
|
try {
|
||||||
|
@ -34,64 +32,8 @@ function cloneUrl(url: Readonly<URL>): URL {
|
||||||
return new URL(url.href);
|
return new URL(url.href);
|
||||||
}
|
}
|
||||||
|
|
||||||
class UrlPath {
|
export function urlPathFromComponents(
|
||||||
#urlPath: string;
|
components: ReadonlyArray<string>
|
||||||
|
): string {
|
||||||
constructor(escapedUrlPath: string) {
|
return `/${components.filter(Boolean).map(encodeURIComponent).join('/')}`;
|
||||||
this.#urlPath = escapedUrlPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
toString(): string {
|
|
||||||
return this.#urlPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type { UrlPath };
|
|
||||||
|
|
||||||
export type UrlPathInput = boolean | number | string | UrlPath;
|
|
||||||
|
|
||||||
export function isUrlPath(value: unknown): value is UrlPath {
|
|
||||||
return value instanceof UrlPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeValueForUrlPath(value: UrlPathInput): string {
|
|
||||||
if (typeof value === 'boolean' || typeof value === 'number') {
|
|
||||||
return String(value);
|
|
||||||
}
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
return encodeURIComponent(value);
|
|
||||||
}
|
|
||||||
if (isUrlPath(value)) {
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
throw new TypeError('Unexpected url path component');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function urlPath(
|
|
||||||
strings: TemplateStringsArray,
|
|
||||||
...components: ReadonlyArray<UrlPathInput>
|
|
||||||
): UrlPath {
|
|
||||||
let result = '';
|
|
||||||
for (let index = 0; index < strings.length; index += 1) {
|
|
||||||
result += strings[index];
|
|
||||||
if (index < components.length) {
|
|
||||||
result += escapeValueForUrlPath(components[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new UrlPath(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function urlPathJoin(
|
|
||||||
values: ReadonlyArray<UrlPathInput>,
|
|
||||||
separator: string
|
|
||||||
): UrlPath {
|
|
||||||
strictAssert(isUrlPath(separator), 'Separator must be an EscapedUrlPath');
|
|
||||||
let result = '';
|
|
||||||
for (let index = 0; index < values.length; index += 1) {
|
|
||||||
result += escapeValueForUrlPath(values[index]);
|
|
||||||
if (index < values.length - 1) {
|
|
||||||
result += separator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new UrlPath(result);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue