resolveUsernameByLink: Move to libsignal typed API

This commit is contained in:
Scott Nonnenberg
2026-01-06 07:00:18 +10:00
committed by GitHub
parent df85bcf2a5
commit 8030284a40
2 changed files with 28 additions and 39 deletions

View File

@@ -30,6 +30,7 @@ import {
deleteUsername as doDeleteUsername,
resolveUsernameLink,
} from '../textsecure/WebAPI.preload.js';
import type { ResolveUsernameByLinkOptionsType } from '../textsecure/WebAPI.preload.js';
import { HTTPError } from '../types/HTTPError.std.js';
import { findRetryAfterTimeFromError } from '../jobs/helpers/findRetryAfterTimeFromError.std.js';
import * as Bytes from '../Bytes.std.js';
@@ -364,28 +365,22 @@ export async function resolveUsernameByLinkBase64(
const entropy = content.subarray(0, USERNAME_LINK_ENTROPY_SIZE);
const serverId = content.subarray(USERNAME_LINK_ENTROPY_SIZE);
return resolveUsernameByLink({ entropy, serverId });
const uuid = bytesToUuid(serverId);
strictAssert(uuid, 'Failed to re-encode server id as uuid');
return resolveUsernameByLink({ entropy, uuid });
}
export type ResolveUsernameByLinkOptionsType = Readonly<{
entropy: Uint8Array;
serverId: Uint8Array;
}>;
export async function resolveUsernameByLink({
entropy,
serverId: serverIdBytes,
}: ResolveUsernameByLinkOptionsType): Promise<string | undefined> {
const serverId = bytesToUuid(serverIdBytes);
strictAssert(serverId, 'Failed to re-encode server id as uuid');
export async function resolveUsernameByLink(
options: ResolveUsernameByLinkOptionsType
): Promise<string | undefined> {
try {
const { usernameLinkEncryptedValue } = await resolveUsernameLink(serverId);
const result = await resolveUsernameLink(options);
if (!result) {
return undefined;
}
return usernames.decryptUsernameLink({
entropy,
encryptedUsername: usernameLinkEncryptedValue,
});
return result.username;
} catch (error) {
if (error instanceof HTTPError && error.code === 404) {
return undefined;

View File

@@ -1061,14 +1061,14 @@ export type ReplaceUsernameLinkResultType = z.infer<
typeof replaceUsernameLinkResultZod
>;
const resolveUsernameLinkResultZod = z.object({
usernameLinkEncryptedValue: z
.string()
.transform(x => Bytes.fromBase64(fromWebSafeBase64(x))),
});
export type ResolveUsernameLinkResultType = z.infer<
typeof resolveUsernameLinkResultZod
>;
export type ResolveUsernameByLinkOptionsType = Readonly<{
entropy: Uint8Array;
uuid: string;
}>;
export type ResolveUsernameLinkResultType = {
username: string;
hash: Uint8Array;
} | null;
export type CreateAccountOptionsType = Readonly<{
sessionId: string;
@@ -2659,19 +2659,13 @@ export async function deleteUsernameLink(): Promise<void> {
});
}
export async function resolveUsernameLink(
serverId: string
): Promise<ResolveUsernameLinkResultType> {
return _ajax({
host: 'chatService',
httpType: 'GET',
call: 'usernameLink',
urlParameters: `/${encodeURIComponent(serverId)}`,
responseType: 'json',
unauthenticated: true,
accessKey: undefined,
groupSendToken: undefined,
zodSchema: resolveUsernameLinkResultZod,
export async function resolveUsernameLink({
entropy,
uuid,
}: ResolveUsernameByLinkOptionsType): Promise<ResolveUsernameLinkResultType> {
return _retry(async () => {
const chat = await socketManager.getUnauthenticatedLibsignalApi();
return chat.lookUpUsernameLink({ uuid, entropy });
});
}