Send profile keys in call links
This commit is contained in:
parent
6034a9c214
commit
9ba070c77f
3 changed files with 75 additions and 2 deletions
|
@ -168,6 +168,8 @@ const profileKeyJobDataSchema = z.object({
|
||||||
conversationId: z.string(),
|
conversationId: z.string(),
|
||||||
// Note: we will use whichever recipients list is up to date when this job runs
|
// Note: we will use whichever recipients list is up to date when this job runs
|
||||||
revision: z.number().optional(),
|
revision: z.number().optional(),
|
||||||
|
// Setting this to true lets you send profile key without adding to contacts
|
||||||
|
isOneTimeSend: z.boolean().optional(),
|
||||||
});
|
});
|
||||||
export type ProfileKeyJobData = z.infer<typeof profileKeyJobDataSchema>;
|
export type ProfileKeyJobData = z.infer<typeof profileKeyJobDataSchema>;
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ export async function sendProfileKey(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conversation.get('profileSharing')) {
|
if (!data?.isOneTimeSend && !conversation.get('profileSharing')) {
|
||||||
log.info('No longer sharing profile. Cancelling job.');
|
log.info('No longer sharing profile. Cancelling job.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,10 @@ import {
|
||||||
toAdminKeyBytes,
|
toAdminKeyBytes,
|
||||||
} from '../util/callLinks';
|
} from '../util/callLinks';
|
||||||
import { isAdhocCallingEnabled } from '../util/isAdhocCallingEnabled';
|
import { isAdhocCallingEnabled } from '../util/isAdhocCallingEnabled';
|
||||||
import { conversationJobQueue } from '../jobs/conversationJobQueue';
|
import {
|
||||||
|
conversationJobQueue,
|
||||||
|
conversationQueueJobEnum,
|
||||||
|
} from '../jobs/conversationJobQueue';
|
||||||
import type { ReadCallLinkState } from '../types/CallLink';
|
import type { ReadCallLinkState } from '../types/CallLink';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -351,6 +354,10 @@ export class CallingClass {
|
||||||
|
|
||||||
private callDebugNumber: number = 0;
|
private callDebugNumber: number = 0;
|
||||||
|
|
||||||
|
// Send our profile key to other participants in call link calls to ensure they
|
||||||
|
// can see our profile info. Only send once per aci until the next app start.
|
||||||
|
private sendProfileKeysForAdhocCallCache: Set<AciString>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.videoCapturer = new GumVideoCapturer({
|
this.videoCapturer = new GumVideoCapturer({
|
||||||
maxWidth: REQUESTED_VIDEO_WIDTH,
|
maxWidth: REQUESTED_VIDEO_WIDTH,
|
||||||
|
@ -360,6 +367,7 @@ export class CallingClass {
|
||||||
this.videoRenderer = new CanvasVideoRenderer();
|
this.videoRenderer = new CanvasVideoRenderer();
|
||||||
|
|
||||||
this.callsLookup = {};
|
this.callsLookup = {};
|
||||||
|
this.sendProfileKeysForAdhocCallCache = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(reduxInterface: CallingReduxInterface, sfuUrl: string): void {
|
initialize(reduxInterface: CallingReduxInterface, sfuUrl: string): void {
|
||||||
|
@ -1118,6 +1126,7 @@ export class CallingClass {
|
||||||
peerId: conversationId,
|
peerId: conversationId,
|
||||||
eraId,
|
eraId,
|
||||||
callMode,
|
callMode,
|
||||||
|
peekInfo,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1136,6 +1145,14 @@ export class CallingClass {
|
||||||
);
|
);
|
||||||
|
|
||||||
this.syncGroupCallToRedux(conversationId, groupCall, callMode);
|
this.syncGroupCallToRedux(conversationId, groupCall, callMode);
|
||||||
|
if (callMode === CallMode.Adhoc) {
|
||||||
|
drop(
|
||||||
|
this.sendProfileKeysForAdhocCall({
|
||||||
|
roomId: conversationId,
|
||||||
|
peekInfo,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onAudioLevels: groupCall => {
|
onAudioLevels: groupCall => {
|
||||||
const remoteDeviceStates = groupCall.getRemoteDeviceStates();
|
const remoteDeviceStates = groupCall.getRemoteDeviceStates();
|
||||||
|
@ -1198,6 +1215,7 @@ export class CallingClass {
|
||||||
peerId: conversationId,
|
peerId: conversationId,
|
||||||
eraId,
|
eraId,
|
||||||
callMode,
|
callMode,
|
||||||
|
peekInfo,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1242,18 +1260,71 @@ export class CallingClass {
|
||||||
callMode,
|
callMode,
|
||||||
peerId,
|
peerId,
|
||||||
eraId,
|
eraId,
|
||||||
|
peekInfo,
|
||||||
}: {
|
}: {
|
||||||
callMode: CallMode.Group | CallMode.Adhoc;
|
callMode: CallMode.Group | CallMode.Adhoc;
|
||||||
peerId: string;
|
peerId: string;
|
||||||
eraId: string;
|
eraId: string;
|
||||||
|
peekInfo: PeekInfo | null;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
if (callMode === CallMode.Group) {
|
if (callMode === CallMode.Group) {
|
||||||
drop(this.sendGroupCallUpdateMessage(peerId, eraId));
|
drop(this.sendGroupCallUpdateMessage(peerId, eraId));
|
||||||
} else if (callMode === CallMode.Adhoc) {
|
} else if (callMode === CallMode.Adhoc) {
|
||||||
this.reduxInterface?.joinedAdhocCall(peerId);
|
this.reduxInterface?.joinedAdhocCall(peerId);
|
||||||
|
drop(this.sendProfileKeysForAdhocCall({ roomId: peerId, peekInfo }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async sendProfileKeysForAdhocCall({
|
||||||
|
roomId,
|
||||||
|
peekInfo,
|
||||||
|
}: {
|
||||||
|
roomId: string;
|
||||||
|
peekInfo: PeekInfo | null | undefined;
|
||||||
|
}): Promise<void> {
|
||||||
|
if (!peekInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||||
|
const reason = `sendProfileKeysForAdhocCall(${roomId})`;
|
||||||
|
peekInfo.devices.forEach(async device => {
|
||||||
|
const aci = device.userId ? this.formatUserId(device.userId) : null;
|
||||||
|
if (
|
||||||
|
!aci ||
|
||||||
|
aci === ourAci ||
|
||||||
|
this.sendProfileKeysForAdhocCallCache.has(aci)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const logId = `sendProfileKeysForAdhocCall aci=${aci}`;
|
||||||
|
const conversation = window.ConversationController.lookupOrCreate({
|
||||||
|
serviceId: aci,
|
||||||
|
reason,
|
||||||
|
});
|
||||||
|
if (!conversation) {
|
||||||
|
log.warn(`${logId}: Could not lookup or create conversation for aci`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conversation.isBlocked()) {
|
||||||
|
log.info(`${logId}: Skipping blocked aci`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(`${logId}: Sending profile key`);
|
||||||
|
drop(
|
||||||
|
conversationJobQueue.add({
|
||||||
|
type: conversationQueueJobEnum.enum.ProfileKey,
|
||||||
|
conversationId: conversation.id,
|
||||||
|
isOneTimeSend: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.sendProfileKeysForAdhocCallCache.add(aci);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async joinCallLinkCall({
|
public async joinCallLinkCall({
|
||||||
roomId,
|
roomId,
|
||||||
rootKey,
|
rootKey,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue