Add DeviceId type

This commit is contained in:
Max Radermacher 2025-03-21 16:49:38 -05:00 committed by GitHub
parent 5445d2a62a
commit 279a11f742
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
70 changed files with 387 additions and 333 deletions

View File

@ -711,6 +711,7 @@
50EF8DD32A1EC6B100A00935 /* OWSDisappearingMessagesConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50EF8DD22A1EC6B100A00935 /* OWSDisappearingMessagesConfigurationTest.swift */; };
50EF8DD52A1FE55D00A00935 /* SignalAccountMergeObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50EF8DD42A1FE55D00A00935 /* SignalAccountMergeObserver.swift */; };
50F039C42C6D239500162B99 /* BlockedRecipientStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F039C32C6D239500162B99 /* BlockedRecipientStore.swift */; };
50F401CC2D483BF40094CA56 /* DeviceId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F401CB2D483BF40094CA56 /* DeviceId.swift */; };
50F54C2D2CE3FF7C005765EA /* GroupSendEndorsementStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F54C2C2CE3FF7C005765EA /* GroupSendEndorsementStore.swift */; };
50F54C2F2CE3FF9E005765EA /* GroupSendEndorsementRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F54C2E2CE3FF9E005765EA /* GroupSendEndorsementRecord.swift */; };
50F75E312AD9F18F0032530F /* RecipientDatabaseTableTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F75E302AD9F18F0032530F /* RecipientDatabaseTableTest.swift */; };
@ -4585,6 +4586,7 @@
50EF8DD22A1EC6B100A00935 /* OWSDisappearingMessagesConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSDisappearingMessagesConfigurationTest.swift; sourceTree = "<group>"; };
50EF8DD42A1FE55D00A00935 /* SignalAccountMergeObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignalAccountMergeObserver.swift; sourceTree = "<group>"; };
50F039C32C6D239500162B99 /* BlockedRecipientStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedRecipientStore.swift; sourceTree = "<group>"; };
50F401CB2D483BF40094CA56 /* DeviceId.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceId.swift; sourceTree = "<group>"; };
50F54C2C2CE3FF7C005765EA /* GroupSendEndorsementStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupSendEndorsementStore.swift; sourceTree = "<group>"; };
50F54C2E2CE3FF9E005765EA /* GroupSendEndorsementRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupSendEndorsementRecord.swift; sourceTree = "<group>"; };
50F75E302AD9F18F0032530F /* RecipientDatabaseTableTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipientDatabaseTableTest.swift; sourceTree = "<group>"; };
@ -13958,6 +13960,7 @@
isa = PBXGroup;
children = (
F9C5CA5F289453B100548EEE /* Model */,
50F401CB2D483BF40094CA56 /* DeviceId.swift */,
5050A8782B76E2E100E9BFA4 /* PreKeyId.swift */,
F9C5CA59289453B100548EEE /* SenderKeyStore.swift */,
C1CD0E352A6B0BC900307F1A /* SignalPreKeyStore.swift */,
@ -17494,6 +17497,7 @@
D9247EA82BFD28E800DFEF6F /* DeleteForMeSyncMessageReceiver.swift in Sources */,
F9C5CC34289453B300548EEE /* DeliveryReceiptContext.swift in Sources */,
6698FC1A2980AB45004EFC30 /* DependenciesBridge.swift in Sources */,
50F401CC2D483BF40094CA56 /* DeviceId.swift in Sources */,
505C2ED629971D4E00C23FB2 /* DeviceLimitExceededError.swift in Sources */,
50E5E4B129932D9B00E15A1C /* DeviceMessage.swift in Sources */,
F9C5CE0C289453B400548EEE /* DeviceNames.swift in Sources */,

View File

@ -273,7 +273,7 @@ extension SignalApp {
@MainActor
static func resetLinkedAppDataWithUI(
currentDeviceId: Int,
currentDeviceId: DeviceId,
keyFetcher: GRDBKeyFetcher = SSKEnvironment.shared.databaseStorageRef.keyFetcher
) {
Logger.info("")

View File

@ -79,7 +79,7 @@ final class IndividualCallService: CallServiceStateObserver {
let localDeviceId = tsAccountManager.storedDeviceIdWithMaybeTransaction
do {
try callManager.placeCall(call: call, callMediaType: call.individualCall.offerMediaType.asCallMediaType, localDevice: localDeviceId)
try callManager.placeCall(call: call, callMediaType: call.individualCall.offerMediaType.asCallMediaType, localDevice: localDeviceId.uint32Value)
} catch {
self.handleFailedCall(failedCall: call, error: error, shouldResetUI: true, shouldResetRingRTC: true)
}
@ -164,7 +164,7 @@ final class IndividualCallService: CallServiceStateObserver {
*/
public func handleReceivedOffer(
caller: Aci,
sourceDevice: UInt32,
sourceDevice: DeviceId,
localIdentity: OWSIdentity,
callId: UInt64,
opaque: Data?,
@ -244,12 +244,12 @@ final class IndividualCallService: CallServiceStateObserver {
do {
try self.callManager.receivedOffer(
call: newCall,
sourceDevice: sourceDevice,
sourceDevice: sourceDevice.uint32Value,
callId: callId,
opaque: opaque,
messageAgeSec: messageAgeSec,
callMediaType: newCall.individualCall.offerMediaType.asCallMediaType,
localDevice: localDeviceId,
localDevice: localDeviceId.uint32Value,
senderIdentityKey: partialResult.identityKeys.contactIdentityKey.publicKey.keyBytes.asData,
receiverIdentityKey: partialResult.identityKeys.localIdentityKey.publicKey.keyBytes.asData
)
@ -265,7 +265,7 @@ final class IndividualCallService: CallServiceStateObserver {
public func handleReceivedAnswer(
caller: Aci,
callId: UInt64,
sourceDevice: UInt32,
sourceDevice: DeviceId,
opaque: Data?,
tx: DBReadTransaction
) {
@ -285,7 +285,7 @@ final class IndividualCallService: CallServiceStateObserver {
@MainActor
private func _handleReceivedAnswer(
callId: UInt64,
sourceDevice: UInt32,
sourceDevice: DeviceId,
opaque: Data,
identityKeys: CallIdentityKeys?
) {
@ -298,7 +298,7 @@ final class IndividualCallService: CallServiceStateObserver {
do {
try callManager.receivedAnswer(
sourceDevice: sourceDevice,
sourceDevice: sourceDevice.uint32Value,
callId: callId,
opaque: opaque,
senderIdentityKey: identityKeys.contactIdentityKey.publicKey.keyBytes.asData,
@ -315,7 +315,7 @@ final class IndividualCallService: CallServiceStateObserver {
/**
* Remote client (could be caller or callee) sent us a connectivity update.
*/
public func handleReceivedIceCandidates(caller: Aci, callId: UInt64, sourceDevice: UInt32, candidates: [SSKProtoCallMessageIceUpdate]) {
public func handleReceivedIceCandidates(caller: Aci, callId: UInt64, sourceDevice: DeviceId, candidates: [SSKProtoCallMessageIceUpdate]) {
Logger.info("callId: \(callId), \(caller)")
let iceCandidates = candidates.filter { $0.id == callId && $0.opaque != nil }.map { $0.opaque! }
@ -330,9 +330,9 @@ final class IndividualCallService: CallServiceStateObserver {
}
@MainActor
private func _handleReceivedIceCandidates(callId: UInt64, sourceDevice: UInt32, iceCandidates: [Data]) {
private func _handleReceivedIceCandidates(callId: UInt64, sourceDevice: DeviceId, iceCandidates: [Data]) {
do {
try callManager.receivedIceCandidates(sourceDevice: sourceDevice, callId: callId, candidates: iceCandidates)
try callManager.receivedIceCandidates(sourceDevice: sourceDevice.uint32Value, callId: callId, candidates: iceCandidates)
} catch {
owsFailDebug("error: \(error)")
// we don't necessarily want to fail the call just because CallManager errored on an
@ -343,7 +343,7 @@ final class IndividualCallService: CallServiceStateObserver {
/**
* The remote client (caller or callee) ended the call.
*/
public func handleReceivedHangup(caller: Aci, callId: UInt64, sourceDevice: UInt32, type: SSKProtoCallMessageHangupType, deviceId: UInt32) {
public func handleReceivedHangup(caller: Aci, callId: UInt64, sourceDevice: DeviceId, type: SSKProtoCallMessageHangupType, deviceId: UInt32) {
Logger.info("callId: \(callId), \(caller)")
let hangupType: HangupType
@ -361,9 +361,9 @@ final class IndividualCallService: CallServiceStateObserver {
}
@MainActor
private func _handleReceivedHangup(callId: UInt64, sourceDevice: UInt32, hangupType: HangupType, deviceId: UInt32) {
private func _handleReceivedHangup(callId: UInt64, sourceDevice: DeviceId, hangupType: HangupType, deviceId: UInt32) {
do {
try callManager.receivedHangup(sourceDevice: sourceDevice, callId: callId, hangupType: hangupType, deviceId: deviceId)
try callManager.receivedHangup(sourceDevice: sourceDevice.uint32Value, callId: callId, hangupType: hangupType, deviceId: deviceId)
} catch {
owsFailDebug("\(error)")
if let currentCall = callServiceState.currentCall, currentCall.individualCall?.callId == callId {
@ -375,7 +375,7 @@ final class IndividualCallService: CallServiceStateObserver {
/**
* The callee was already in another call.
*/
public func handleReceivedBusy(caller: Aci, callId: UInt64, sourceDevice: UInt32) {
public func handleReceivedBusy(caller: Aci, callId: UInt64, sourceDevice: DeviceId) {
Logger.info("callId: \(callId), \(caller)")
DispatchQueue.main.async {
@ -384,9 +384,9 @@ final class IndividualCallService: CallServiceStateObserver {
}
@MainActor
private func _handleReceivedBusy(callId: UInt64, sourceDevice: UInt32) {
private func _handleReceivedBusy(callId: UInt64, sourceDevice: DeviceId) {
do {
try callManager.receivedBusy(sourceDevice: sourceDevice, callId: callId)
try callManager.receivedBusy(sourceDevice: sourceDevice.uint32Value, callId: callId)
} catch {
owsFailDebug("\(error)")
if let currentCall = callServiceState.currentCall, currentCall.individualCall?.callId == callId {
@ -917,6 +917,8 @@ final class IndividualCallService: CallServiceStateObserver {
Task {
do {
let deviceId = DeviceId(rawValue: deviceId)
let destinationDeviceId = destinationDeviceId.map(DeviceId.init(rawValue:))
let sendPromise = await self.databaseStorage.awaitableWrite { tx in
return CallHangupSender.sendHangup(
thread: call.individualCall.thread,
@ -936,7 +938,7 @@ final class IndividualCallService: CallServiceStateObserver {
)
}
try await sendPromise.awaitable()
Logger.debug("sent hangup message to \(call.individualCall.thread.contactAddress) device: \((destinationDeviceId != nil) ? String(destinationDeviceId!) : "nil")")
Logger.debug("sent hangup message to \(call.individualCall.thread.contactAddress) device: \(destinationDeviceId as Optional)")
try self.callManager.signalingMessageDidSend(callId: callId)
} catch {
Logger.error("failed to send hangup message to \(call.individualCall.thread.contactAddress) with error: \(error)")

View File

@ -24,7 +24,7 @@ class WebRTCCallMessageHandler: CallMessageHandler {
func receivedEnvelope(
_ envelope: SSKProtoEnvelope,
callEnvelope: CallEnvelopeType,
from caller: (aci: Aci, deviceId: UInt32),
from caller: (aci: Aci, deviceId: DeviceId),
toLocalIdentity localIdentity: OWSIdentity,
plaintextData: Data,
wasReceivedByUD: Bool,
@ -109,8 +109,8 @@ class WebRTCCallMessageHandler: CallMessageHandler {
DispatchQueue.main.async {
self.callService.callManager.receivedCallMessage(
senderUuid: caller.aci.rawUUID,
senderDeviceId: caller.deviceId,
localDeviceId: localDeviceId,
senderDeviceId: caller.deviceId.uint32Value,
localDeviceId: localDeviceId.uint32Value,
message: message,
messageAgeSec: messageAgeSec
)

View File

@ -537,12 +537,12 @@ class ProvisioningCoordinatorImpl: ProvisioningCoordinator {
throw .genericError(error)
}
let deviceId: UInt32
let deviceId: DeviceId
switch authedDevice.deviceId {
case .primary:
throw .genericError(OWSAssertionError("Primary device id when provisioning"))
case .secondary(let uInt32):
deviceId = uInt32
case .secondary(let deviceId2):
deviceId = deviceId2
}
await self.db.awaitableWrite { tx in
@ -706,7 +706,7 @@ class ProvisioningCoordinatorImpl: ProvisioningCoordinator {
throw .genericError(OWSAssertionError("Primary device id?"))
case .secondary(let deviceId):
do {
try await deviceService.unlinkDevice(deviceId: Int(deviceId), auth: authedDevice.authedAccount.chatServiceAuth)
try await deviceService.unlinkDevice(deviceId: deviceId, auth: authedDevice.authedAccount.chatServiceAuth)
} catch {
throw .genericError(error)
}

View File

@ -51,8 +51,8 @@ public class RegistrationCoordinatorLoaderImpl: RegistrationCoordinatorLoader {
public let oldAuthToken: String
@AciUuid public var localAci: Aci
public let localAccountId: String
public let localDeviceId: UInt32
public let localUserAllDeviceIds: [UInt32]
public let localDeviceId: DeviceId
public let localUserAllDeviceIds: [DeviceId]
public struct PendingPniState {
public let newE164: E164
@ -69,8 +69,8 @@ public class RegistrationCoordinatorLoaderImpl: RegistrationCoordinatorLoader {
oldAuthToken: String,
localAci: Aci,
localAccountId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32],
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId],
pniState: PendingPniState?
) {
self.oldE164 = oldE164

View File

@ -21,8 +21,8 @@ public enum RegistrationMode: CustomDebugStringConvertible {
public let oldAuthToken: String
@AciUuid public var localAci: Aci
public let localAccountId: String
public let localDeviceId: UInt32
public let localUserAllDeviceIds: [UInt32]
public let localDeviceId: DeviceId
public let localUserAllDeviceIds: [DeviceId]
}
public var debugDescription: String {

View File

@ -215,7 +215,7 @@ class AccountSettingsViewController: OWSTableViewController2 {
proceedTitle: OWSLocalizedString("PROCEED_BUTTON", comment: ""),
proceedStyle: .destructive
) { _ in
let deviceId = Int(DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction)
let deviceId = DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction
SignalApp.resetLinkedAppDataWithUI(currentDeviceId: deviceId)
}
}

View File

@ -1111,14 +1111,14 @@ class DebugUIMessages: DebugUIPage {
outgoingMessage.updateWithSentRecipient(incomingSenderAci, wasSentByUD: false, transaction: transaction)
outgoingMessage.update(
withDeliveredRecipient: SignalServiceAddress(incomingSenderAci),
deviceId: 0,
deviceId: .primary,
deliveryTimestamp: timestamp,
context: PassthroughDeliveryReceiptContext(),
tx: transaction
)
outgoingMessage.update(
withReadRecipient: SignalServiceAddress(incomingSenderAci),
deviceId: 0,
deviceId: .primary,
readTimestamp: timestamp,
tx: transaction
)
@ -1675,7 +1675,7 @@ class DebugUIMessages: DebugUIPage {
owsAssertDebug(address.isValid)
message.update(
withDeliveredRecipient: address,
deviceId: 0,
deviceId: .primary,
deliveryTimestamp: Date.ows_millisecondTimestamp(),
context: PassthroughDeliveryReceiptContext(),
tx: transaction
@ -1688,7 +1688,7 @@ class DebugUIMessages: DebugUIPage {
owsAssertDebug(address.isValid)
message.update(
withReadRecipient: address,
deviceId: 0,
deviceId: .primary,
readTimestamp: Date.ows_millisecondTimestamp(),
tx: transaction
)

View File

@ -106,7 +106,7 @@ public class ProvisioningCoordinatorTest: XCTestCase {
provisioningVersion: 1
)
let deviceName = "test device"
let deviceId = UInt32.random(in: 1...5)
let deviceId = DeviceId(rawValue: UInt32.random(in: 1...5))
let mockSession = UrlSessionMock()
@ -225,7 +225,7 @@ private class MockOWSDeviceService: OWSDeviceService {
// do nothing
}
func unlinkDevice(deviceId: Int, auth: SignalServiceKit.ChatServiceAuth) async throws {
func unlinkDevice(deviceId: DeviceId, auth: SignalServiceKit.ChatServiceAuth) async throws {
// do nothing
}
}

View File

@ -30,7 +30,7 @@ class NSECallMessageHandler: CallMessageHandler {
func receivedEnvelope(
_ envelope: SSKProtoEnvelope,
callEnvelope: CallEnvelopeType,
from caller: (aci: Aci, deviceId: UInt32),
from caller: (aci: Aci, deviceId: DeviceId),
toLocalIdentity localIdentity: OWSIdentity,
plaintextData: Data,
wasReceivedByUD: Bool,

View File

@ -22,7 +22,7 @@ public enum PniDistribution {
public static func mock(
pniIdentityKeyPair: ECKeyPair,
localDeviceId: UInt32,
localDeviceId: DeviceId,
localDevicePniSignedPreKey: SignalServiceKit.SignedPreKeyRecord,
localDevicePniPqLastResortPreKey: KyberPreKeyRecord,
localDevicePniRegistrationId: UInt32
@ -40,7 +40,7 @@ public enum PniDistribution {
#endif
fileprivate mutating func addLocalDevice(
localDeviceId: UInt32,
localDeviceId: DeviceId,
signedPreKey: SignalServiceKit.SignedPreKeyRecord,
pqLastResortPreKey: KyberPreKeyRecord,
registrationId: UInt32
@ -51,7 +51,7 @@ public enum PniDistribution {
}
fileprivate mutating func addLinkedDevice(
deviceId: UInt32,
deviceId: DeviceId,
signedPreKey: SignalServiceKit.SignedPreKeyRecord,
pqLastResortPreKey: KyberPreKeyRecord,
registrationId: UInt32,
@ -90,8 +90,8 @@ protocol PniDistributionParamaterBuilder {
func buildPniDistributionParameters(
localAci: Aci,
localRecipientUniqueId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32],
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId],
localPniIdentityKeyPair: ECKeyPair,
localE164: E164,
localDevicePniSignedPreKey: SignalServiceKit.SignedPreKeyRecord,
@ -126,8 +126,8 @@ final class PniDistributionParameterBuilderImpl: PniDistributionParamaterBuilder
func buildPniDistributionParameters(
localAci: Aci,
localRecipientUniqueId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32],
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId],
localPniIdentityKeyPair: ECKeyPair,
localE164: E164,
localDevicePniSignedPreKey: SignalServiceKit.SignedPreKeyRecord,
@ -170,7 +170,7 @@ final class PniDistributionParameterBuilderImpl: PniDistributionParamaterBuilder
/// Bundles parameters concerning linked devices and PNI identity
/// generation.
private struct LinkedDevicePniGenerationParams {
let deviceId: UInt32
let deviceId: DeviceId
let signedPreKey: SignalServiceKit.SignedPreKeyRecord
let pqLastResortPreKey: KyberPreKeyRecord
let registrationId: UInt32
@ -186,12 +186,12 @@ final class PniDistributionParameterBuilderImpl: PniDistributionParamaterBuilder
private func buildLinkedDevicePniGenerationParams(
localAci: Aci,
localRecipientUniqueId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32],
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId],
pniIdentityKeyPair: ECKeyPair,
e164: E164
) async throws -> [LinkedDevicePniGenerationParams] {
let localUserLinkedDeviceIds: [UInt32] = localUserAllDeviceIds.filter { deviceId in
let localUserLinkedDeviceIds: [DeviceId] = localUserAllDeviceIds.filter { deviceId in
deviceId != localDeviceId
}
@ -259,7 +259,7 @@ final class PniDistributionParameterBuilderImpl: PniDistributionParamaterBuilder
private func encryptPniDistributionMessage(
recipientUniqueId: String,
recipientAci: Aci,
recipientDeviceId: UInt32,
recipientDeviceId: DeviceId,
identityKeyPair: ECKeyPair,
signedPreKey: SignalServiceKit.SignedPreKeyRecord,
pqLastResortPreKey: KyberPreKeyRecord,
@ -310,7 +310,7 @@ protocol _PniDistributionParameterBuilder_MessageSender_Shim {
messageEncryptionStyle: EncryptionStyle,
recipientUniqueId: String,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
isOnlineMessage: Bool,
isTransientSenderKeyDistributionMessage: Bool,
isResendRequestMessage: Bool,
@ -330,7 +330,7 @@ class _PniDistributionParameterBuilder_MessageSender_Wrapper: _PniDistributionPa
messageEncryptionStyle: EncryptionStyle,
recipientUniqueId: String,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
isOnlineMessage: Bool,
isTransientSenderKeyDistributionMessage: Bool,
isResendRequestMessage: Bool,

View File

@ -101,7 +101,7 @@ class PniHelloWorldManagerImpl: PniHelloWorldManager {
var localE164: E164
var localRecipient: SignalRecipient
var localPniIdentityKeyPair: ECKeyPair
var localDeviceId: UInt32
var localDeviceId: DeviceId
var localDevicePniRegistrationId: UInt32
var localDevicePniSignedPreKey: SignalServiceKit.SignedPreKeyRecord
var localDevicePniPqLastResortPreKey: SignalServiceKit.KyberPreKeyRecord

View File

@ -52,6 +52,16 @@ extension ServiceId {
}
}
extension ProtocolAddress {
public convenience init(_ serviceId: ServiceId, deviceId: DeviceId) {
self.init(serviceId, deviceId: deviceId.uint32Value)
}
public var deviceIdObj: DeviceId {
return DeviceId(rawValue: self.deviceId)
}
}
public struct AtLeastOneServiceId {
/// Non-Optional because we must have at least an ACI or a PNI.
public let aciOrElsePni: ServiceId

View File

@ -52,11 +52,11 @@ public class MockTSAccountManager: TSAccountManager {
return storedServerAuthTokenWithMaybeTransaction
}
public var storedDeviceIdMock: (() -> UInt32) = { 1 }
public var storedDeviceIdMock: (() -> DeviceId) = { .primary }
open var storedDeviceIdWithMaybeTransaction: UInt32 { storedDeviceIdMock() }
open var storedDeviceIdWithMaybeTransaction: DeviceId { storedDeviceIdMock() }
open func storedDeviceId(tx: DBReadTransaction) -> UInt32 {
open func storedDeviceId(tx: DBReadTransaction) -> DeviceId {
return storedDeviceIdWithMaybeTransaction
}

View File

@ -44,12 +44,12 @@ open class MockRegistrationStateChangeManager: RegistrationStateChangeManager {
_ aci: Aci,
_ pni: Pni,
_ authToken: String,
_ deviceId: UInt32
_ deviceId: DeviceId
) -> Void = { [weak self] _, _, _, _, _ in
self?.registrationStateMock = { .provisioned }
}
open func didProvisionSecondary(e164: E164, aci: Aci, pni: Pni, authToken: String, deviceId: UInt32, tx: DBWriteTransaction) {
open func didProvisionSecondary(e164: E164, aci: Aci, pni: Pni, authToken: String, deviceId: DeviceId, tx: DBWriteTransaction) {
didProvisionSecondaryMock(e164, aci, pni, authToken, deviceId)
}

View File

@ -61,7 +61,7 @@ public protocol RegistrationStateChangeManager {
aci: Aci,
pni: Pni,
authToken: String,
deviceId: UInt32,
deviceId: DeviceId,
tx: DBWriteTransaction
)

View File

@ -78,7 +78,7 @@ public class RegistrationStateChangeManagerImpl: RegistrationStateChangeManager
e164: e164,
aci: aci,
pni: pni,
deviceId: OWSDevice.primaryDeviceId,
deviceId: .primary,
serverAuthToken: authToken,
tx: tx
)
@ -96,7 +96,7 @@ public class RegistrationStateChangeManagerImpl: RegistrationStateChangeManager
aci: Aci,
pni: Pni,
authToken: String,
deviceId: UInt32,
deviceId: DeviceId,
tx: DBWriteTransaction
) {
tsAccountManager.initializeLocalIdentifiers(
@ -345,7 +345,7 @@ extension RegistrationStateChangeManagerImpl {
e164: E164(localIdentifiers.phoneNumber)!,
aci: localIdentifiers.aci,
pni: localIdentifiers.pni!,
deviceId: OWSDevice.primaryDeviceId,
deviceId: .primary,
serverAuthToken: "",
tx: tx
)

View File

@ -24,9 +24,9 @@ public protocol TSAccountManager {
func storedServerAuthToken(tx: DBReadTransaction) -> String?
var storedDeviceIdWithMaybeTransaction: UInt32 { get }
var storedDeviceIdWithMaybeTransaction: DeviceId { get }
func storedDeviceId(tx: DBReadTransaction) -> UInt32
func storedDeviceId(tx: DBReadTransaction) -> DeviceId
// MARK: - Registration State
@ -108,7 +108,7 @@ public protocol LocalIdentifiersSetter {
e164: E164,
aci: Aci,
pni: Pni,
deviceId: UInt32,
deviceId: DeviceId,
serverAuthToken: String,
tx: DBWriteTransaction
)

View File

@ -90,11 +90,11 @@ public class TSAccountManagerImpl: TSAccountManager {
return getOrLoadAccountState(tx: tx).serverAuthToken
}
public var storedDeviceIdWithMaybeTransaction: UInt32 {
public var storedDeviceIdWithMaybeTransaction: DeviceId {
return getOrLoadAccountStateWithMaybeTransaction().deviceId
}
public func storedDeviceId(tx: DBReadTransaction) -> UInt32 {
public func storedDeviceId(tx: DBReadTransaction) -> DeviceId {
return getOrLoadAccountState(tx: tx).deviceId
}
@ -193,7 +193,7 @@ extension TSAccountManagerImpl: LocalIdentifiersSetter {
e164: E164,
aci: Aci,
pni: Pni,
deviceId: UInt32,
deviceId: DeviceId,
serverAuthToken: String,
tx: DBWriteTransaction
) {
@ -211,8 +211,8 @@ extension TSAccountManagerImpl: LocalIdentifiersSetter {
// Encoded without the "PNI:" prefix for backwards compatibility.
kvStore.setString(pni.rawUUID.uuidString, key: Keys.localPni, transaction: tx)
Self.regStateLogger.info("device id is primary? \(deviceId == OWSDevice.primaryDeviceId)")
kvStore.setUInt32(deviceId, key: Keys.deviceId, transaction: tx)
Self.regStateLogger.info("device id is primary? \(deviceId == .primary)")
kvStore.setUInt32(deviceId.uint32Value, key: Keys.deviceId, transaction: tx)
kvStore.setString(serverAuthToken, key: Keys.serverAuthToken, transaction: tx)
kvStore.setDate(dateProvider(), key: Keys.registrationDate, transaction: tx)
@ -423,7 +423,7 @@ extension TSAccountManagerImpl {
let localIdentifiers: LocalIdentifiers?
let deviceId: UInt32
let deviceId: DeviceId
let serverAuthToken: String?
@ -466,7 +466,7 @@ extension TSAccountManagerImpl {
transaction: tx
)
// Assume primary, for backwards compatibility.
self.deviceId = persistedDeviceId ?? OWSDevice.primaryDeviceId
self.deviceId = DeviceId(rawValue: persistedDeviceId ?? OWSDevice.primaryDeviceId)
self.serverAuthToken = kvStore.getString(Keys.serverAuthToken, transaction: tx)

View File

@ -19,7 +19,7 @@ public protocol CallMessageHandler {
func receivedEnvelope(
_ envelope: SSKProtoEnvelope,
callEnvelope: CallEnvelopeType,
from caller: (aci: Aci, deviceId: UInt32),
from caller: (aci: Aci, deviceId: DeviceId),
toLocalIdentity localIdentity: OWSIdentity,
plaintextData: Data,
wasReceivedByUD: Bool,

View File

@ -50,7 +50,7 @@ public class CallOfferHandlerImpl {
public func startHandlingOffer(
caller: Aci,
sourceDevice: UInt32,
sourceDevice: DeviceId,
localIdentity: OWSIdentity,
callId: UInt64,
callType: SSKProtoCallMessageOfferType,
@ -200,8 +200,8 @@ public enum CallHangupSender {
thread: TSContactThread,
callId: UInt64,
hangupType: SSKProtoCallMessageHangupType,
localDeviceId: UInt32,
remoteDeviceId: UInt32?,
localDeviceId: DeviceId,
remoteDeviceId: DeviceId?,
tx: DBWriteTransaction
) -> Promise<Void> {
let hangupBuilder = SSKProtoCallMessageHangup.builder(id: callId)
@ -211,7 +211,7 @@ public enum CallHangupSender {
if hangupType != .hangupNormal {
// deviceId is optional and only used when indicated by a hangup due to
// a call being accepted elsewhere.
hangupBuilder.setDeviceID(localDeviceId)
hangupBuilder.setDeviceID(localDeviceId.uint32Value)
}
let hangupMessage: SSKProtoCallMessageHangup
@ -225,7 +225,7 @@ public enum CallHangupSender {
let callMessage = OWSOutgoingCallMessage(
thread: thread,
hangupMessage: hangupMessage,
destinationDeviceId: remoteDeviceId.map(NSNumber.init(value:)),
destinationDeviceId: (remoteDeviceId?.uint32Value).map(NSNumber.init(value:)),
transaction: tx
)
let preparedMessage = PreparedOutgoingMessage.preprepared(

View File

@ -37,8 +37,8 @@ public protocol ChangePhoneNumberPniManager {
forNewE164 newE164: E164,
localAci: Aci,
localRecipientUniqueId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32]
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId]
) -> Guarantee<ChangePhoneNumberPni.GeneratePniIdentityResult>
/// Commits an identity generated for a change number request.
@ -133,8 +133,8 @@ class ChangePhoneNumberPniManagerImpl: ChangePhoneNumberPniManager {
forNewE164 newE164: E164,
localAci: Aci,
localRecipientUniqueId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32]
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId]
) -> Guarantee<ChangePhoneNumberPni.GeneratePniIdentityResult> {
logger.info("Generating PNI identity!")

View File

@ -19,8 +19,8 @@ public class ChangePhoneNumberPniManagerMock: ChangePhoneNumberPniManager {
forNewE164 newE164: E164,
localAci: Aci,
localRecipientUniqueId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32]
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId]
) -> Guarantee<ChangePhoneNumberPni.GeneratePniIdentityResult> {
let keyPair = ECKeyPair.generateKeyPair()
let registrationId = UInt32.random(in: 1...0x3fff)

View File

@ -52,7 +52,7 @@ public final class SignalRecipient: NSObject, NSCopying, SDSCodableModel, Decoda
/// it's safe to check it at time-of-fetch and throw an error.
public var pni: Pni?
public var phoneNumber: PhoneNumber?
fileprivate(set) public var deviceIds: [UInt32]
fileprivate(set) public var deviceIds: [DeviceId]
fileprivate(set) public var unregisteredAtTimestamp: UInt64?
public var aci: Aci? {
@ -83,7 +83,7 @@ public final class SignalRecipient: NSObject, NSCopying, SDSCodableModel, Decoda
self.init(aci: aci, pni: pni, phoneNumber: phoneNumber, deviceIds: [])
}
public convenience init(aci: Aci?, pni: Pni?, phoneNumber: E164?, deviceIds: [UInt32]) {
public convenience init(aci: Aci?, pni: Pni?, phoneNumber: E164?, deviceIds: [DeviceId]) {
self.init(
id: nil,
uniqueId: UUID().uuidString,
@ -106,14 +106,14 @@ public final class SignalRecipient: NSObject, NSCopying, SDSCodableModel, Decoda
isRegistered: Bool,
unregisteredAtTimestamp: UInt64?
) -> Self {
let deviceIds: [UInt32]
let deviceIds: [DeviceId]
if isRegistered {
// If we think they are registered, just add the primary device id.
// When we try and send a message, the server will tell us about
// any other device ids.
// ...The server would tell us too if we sent an empty deviceIds array,
// so there's not really a material difference.
deviceIds = [OWSDevice.primaryDeviceId]
deviceIds = [.primary]
} else {
// Otherwise (including if we don't know if they're registered),
// use an empty device IDs array. This doesn't make any difference,
@ -143,7 +143,7 @@ public final class SignalRecipient: NSObject, NSCopying, SDSCodableModel, Decoda
aciString: String?,
pni: Pni?,
phoneNumber: PhoneNumber?,
deviceIds: [UInt32],
deviceIds: [DeviceId],
unregisteredAtTimestamp: UInt64?
) {
self.id = id
@ -238,7 +238,7 @@ public final class SignalRecipient: NSObject, NSCopying, SDSCodableModel, Decoda
// If we can't parse the values in the NSOrderedSet, assume the user isn't
// registered. If they are registered, we'll correct the data store the
// next time we try to send them a message.
deviceIds = deviceArray ?? []
deviceIds = deviceArray?.map(DeviceId.init(rawValue:)) ?? []
unregisteredAtTimestamp = try container.decodeIfPresent(UInt64.self, forKey: .unregisteredAtTimestamp)
}
@ -251,7 +251,7 @@ public final class SignalRecipient: NSObject, NSCopying, SDSCodableModel, Decoda
try container.encodeIfPresent(pni?.serviceIdUppercaseString, forKey: .pni)
try container.encodeIfPresent(phoneNumber?.stringValue, forKey: .phoneNumber)
try container.encodeIfPresent(phoneNumber?.isDiscoverable, forKey: .isPhoneNumberDiscoverable)
let deviceSetObjC = NSOrderedSet(array: deviceIds.map { NSNumber(value: $0) })
let deviceSetObjC = NSOrderedSet(array: deviceIds.map { NSNumber(value: $0.uint32Value) })
let encodedDevices = LegacySDSSerializer().serializeAsLegacySDSData(property: deviceSetObjC)
try container.encode(encodedDevices, forKey: .deviceIds)
try container.encodeIfPresent(unregisteredAtTimestamp, forKey: .unregisteredAtTimestamp)
@ -312,7 +312,7 @@ public final class SignalRecipient: NSObject, NSCopying, SDSCodableModel, Decoda
extension SignalRecipientManagerImpl {
func setDeviceIds(
_ deviceIds: Set<UInt32>,
_ deviceIds: Set<DeviceId>,
for recipient: SignalRecipient,
shouldUpdateStorageService: Bool
) {

View File

@ -13,8 +13,8 @@ public protocol SignalRecipientManager {
func modifyAndSave(
_ recipient: SignalRecipient,
deviceIdsToAdd: [UInt32],
deviceIdsToRemove: [UInt32],
deviceIdsToAdd: [DeviceId],
deviceIdsToRemove: [DeviceId],
shouldUpdateStorageService: Bool,
tx: DBWriteTransaction
)
@ -35,7 +35,7 @@ public enum UnregisteredAt {
extension SignalRecipientManager {
public func markAsRegisteredAndSave(
_ recipient: SignalRecipient,
deviceId: UInt32 = OWSDevice.primaryDeviceId,
deviceId: DeviceId = .primary,
shouldUpdateStorageService: Bool,
tx: DBWriteTransaction
) {
@ -96,19 +96,19 @@ public class SignalRecipientManagerImpl: SignalRecipientManager {
public func modifyAndSave(
_ recipient: SignalRecipient,
deviceIdsToAdd: [UInt32],
deviceIdsToRemove: [UInt32],
deviceIdsToAdd: [DeviceId],
deviceIdsToRemove: [DeviceId],
shouldUpdateStorageService: Bool,
tx: DBWriteTransaction
) {
var deviceIdsToAdd = deviceIdsToAdd
// Always add the primary if any other device is registered.
if !deviceIdsToAdd.isEmpty {
deviceIdsToAdd.append(OWSDevice.primaryDeviceId)
deviceIdsToAdd.append(.primary)
}
let oldDeviceIds = Set(recipient.deviceIds)
let newDeviceIds = oldDeviceIds.union(deviceIdsToAdd).subtracting(deviceIdsToRemove)
let oldDeviceIds: Set<DeviceId> = Set(recipient.deviceIds)
let newDeviceIds: Set<DeviceId> = oldDeviceIds.union(deviceIdsToAdd).subtracting(deviceIdsToRemove)
if oldDeviceIds == newDeviceIds {
return

View File

@ -10,7 +10,7 @@ public protocol OWSDeviceService {
func refreshDevices() async throws -> Bool
/// Unlink the given device.
func unlinkDevice(deviceId: Int, auth: ChatServiceAuth) async throws
func unlinkDevice(deviceId: DeviceId, auth: ChatServiceAuth) async throws
/// Renames a device with the given encrypted name.
func renameDevice(
@ -21,12 +21,16 @@ public protocol OWSDeviceService {
extension OWSDeviceService {
public func unlinkDevice(deviceId: Int) async throws {
public func unlinkDevice(deviceId: DeviceId) async throws {
try await self.unlinkDevice(deviceId: deviceId, auth: .implicit())
}
public func unlinkDevice(_ device: OWSDevice, auth: ChatServiceAuth = .implicit()) async throws {
try await unlinkDevice(deviceId: device.deviceId, auth: auth)
guard let deviceId = UInt32(exactly: device.deviceId) else {
// If it's not valid, the device can't exist on the server.
return
}
try await unlinkDevice(deviceId: DeviceId(rawValue: deviceId), auth: auth)
}
}
@ -134,7 +138,7 @@ struct OWSDeviceServiceImpl: OWSDeviceService {
// MARK: -
func unlinkDevice(deviceId: Int, auth: ChatServiceAuth) async throws {
func unlinkDevice(deviceId: DeviceId, auth: ChatServiceAuth) async throws {
let request = TSRequest.deleteDevice(deviceId: deviceId)
request.auth = .identified(auth)
_ = try await networkManager.asyncRequest(request, canUseWebSocket: false)
@ -219,7 +223,7 @@ private extension TSRequest {
}
static func deleteDevice(
deviceId: Int
deviceId: DeviceId
) -> TSRequest {
return TSRequest(
url: URL(string: "v1/devices/\(deviceId)")!,

View File

@ -11,7 +11,7 @@ public class NoopCallMessageHandler: CallMessageHandler {
public func receivedEnvelope(
_ envelope: SSKProtoEnvelope,
callEnvelope: CallEnvelopeType,
from caller: (aci: Aci, deviceId: UInt32),
from caller: (aci: Aci, deviceId: DeviceId),
toLocalIdentity localIdentity: OWSIdentity,
plaintextData: Data,
wasReceivedByUD: Bool,

View File

@ -27,7 +27,7 @@ class DecryptedIncomingEnvelope {
let timestamp: UInt64
let serverTimestamp: UInt64
let sourceAci: Aci
let sourceDeviceId: UInt32
let sourceDeviceId: DeviceId
let localIdentity: OWSIdentity
let wasReceivedByUD: Bool
let plaintextData: Data
@ -37,7 +37,7 @@ class DecryptedIncomingEnvelope {
validatedEnvelope: ValidatedIncomingEnvelope,
updatedEnvelope: SSKProtoEnvelope,
sourceAci: Aci,
sourceDeviceId: UInt32,
sourceDeviceId: DeviceId,
wasReceivedByUD: Bool,
plaintextData: Data,
isPlaintextCipher: Bool?

View File

@ -7,12 +7,12 @@ import Foundation
struct DeviceMessage {
let type: SSKProtoEnvelopeType
let destinationDeviceId: UInt32
let destinationDeviceId: DeviceId
let destinationRegistrationId: UInt32
let content: Data
}
struct SentDeviceMessage {
var destinationDeviceId: UInt32
var destinationDeviceId: DeviceId
var destinationRegistrationId: UInt32
}

View File

@ -151,11 +151,11 @@ public class EarlyMessageManager {
}
// PNP0 TODO: This should be an Aci for read/viewed receipts.
init(receiptType: SSKProtoReceiptMessageType, sender: ServiceId, senderDeviceId: UInt32, timestamp: UInt64) {
init(receiptType: SSKProtoReceiptMessageType, sender: ServiceId, senderDeviceId: DeviceId, timestamp: UInt64) {
switch receiptType {
case .delivery: self = .outgoingMessageDelivered(sender: SignalServiceAddress(sender), deviceId: senderDeviceId, timestamp: timestamp)
case .read: self = .outgoingMessageRead(sender: SignalServiceAddress(sender), deviceId: senderDeviceId, timestamp: timestamp)
case .viewed: self = .outgoingMessageViewed(sender: SignalServiceAddress(sender), deviceId: senderDeviceId, timestamp: timestamp)
case .delivery: self = .outgoingMessageDelivered(sender: SignalServiceAddress(sender), deviceId: senderDeviceId.uint32Value, timestamp: timestamp)
case .read: self = .outgoingMessageRead(sender: SignalServiceAddress(sender), deviceId: senderDeviceId.uint32Value, timestamp: timestamp)
case .viewed: self = .outgoingMessageViewed(sender: SignalServiceAddress(sender), deviceId: senderDeviceId.uint32Value, timestamp: timestamp)
}
}
}
@ -229,7 +229,7 @@ public class EarlyMessageManager {
public func recordEarlyReceiptForOutgoingMessage(
type: SSKProtoReceiptMessageType,
senderServiceId: ServiceId,
senderDeviceId: UInt32,
senderDeviceId: DeviceId,
timestamp: UInt64,
associatedMessageTimestamp: UInt64,
tx: DBWriteTransaction
@ -359,7 +359,7 @@ public class EarlyMessageManager {
}
message.update(
withReadRecipient: sender,
deviceId: deviceId,
deviceId: DeviceId(rawValue: deviceId),
readTimestamp: timestamp,
tx: transaction
)
@ -372,7 +372,7 @@ public class EarlyMessageManager {
}
message.update(
withViewedRecipient: sender,
deviceId: deviceId,
deviceId: DeviceId(rawValue: deviceId),
viewedTimestamp: timestamp,
tx: transaction
)
@ -385,7 +385,7 @@ public class EarlyMessageManager {
}
message.update(
withDeliveredRecipient: sender,
deviceId: deviceId,
deviceId: DeviceId(rawValue: deviceId),
deliveryTimestamp: timestamp,
context: PassthroughDeliveryReceiptContext(),
tx: transaction

View File

@ -430,7 +430,7 @@ public extension TSOutgoingMessage {
fileprivate func maybeClearShouldSharePhoneNumber(
for recipientAddress: SignalServiceAddress,
recipientDeviceId deviceId: UInt32,
recipientDeviceId deviceId: DeviceId,
transaction: DBWriteTransaction
) {
guard let aci = recipientAddress.serviceId as? Aci else {
@ -570,7 +570,7 @@ extension TSOutgoingMessage {
extension TSOutgoingMessage {
public func update(
withDeliveredRecipient recipientAddress: SignalServiceAddress,
deviceId: UInt32,
deviceId: DeviceId,
deliveryTimestamp timestamp: UInt64,
context: DeliveryReceiptContext,
tx: DBWriteTransaction
@ -587,7 +587,7 @@ extension TSOutgoingMessage {
public func update(
withReadRecipient recipientAddress: SignalServiceAddress,
deviceId: UInt32,
deviceId: DeviceId,
readTimestamp timestamp: UInt64,
tx: DBWriteTransaction
) {
@ -602,7 +602,7 @@ extension TSOutgoingMessage {
public func update(
withViewedRecipient recipientAddress: SignalServiceAddress,
deviceId: UInt32,
deviceId: DeviceId,
viewedTimestamp timestamp: UInt64,
tx: DBWriteTransaction
) {
@ -631,7 +631,7 @@ extension TSOutgoingMessage {
private func handleReceipt(
from recipientAddress: SignalServiceAddress,
deviceId: UInt32,
deviceId: DeviceId,
receiptType: IncomingReceiptType,
receiptTimestamp: UInt64,
tryToClearPhoneNumberSharing: Bool = false,
@ -738,8 +738,7 @@ extension TSOutgoingMessage {
@objc
var encryptionStyle: EncryptionStyle { .whisper }
@objc
func clearMessageSendLogEntry(forRecipient address: SignalServiceAddress, deviceId: UInt32, tx: DBWriteTransaction) {
func clearMessageSendLogEntry(forRecipient address: SignalServiceAddress, deviceId: DeviceId, tx: DBWriteTransaction) {
// MSL entries will only exist for addresses with ACIs
guard let aci = address.serviceId as? Aci else {
return

View File

@ -315,7 +315,7 @@ public class MessageProcessor {
private func buildNextCombinedRequest(
envelopes: inout [ReceivedEnvelope],
localIdentifiers: LocalIdentifiers,
localDeviceId: UInt32,
localDeviceId: DeviceId,
tx: DBWriteTransaction
) -> RelatedProcessingRequests {
let result = RelatedProcessingRequests()
@ -475,7 +475,7 @@ private class RelatedProcessingRequests {
private struct ProcessingRequestBuilder {
let receivedEnvelope: ReceivedEnvelope
let blockingManager: BlockingManager
let localDeviceId: UInt32
let localDeviceId: DeviceId
let localIdentifiers: LocalIdentifiers
let messageDecrypter: OWSMessageDecrypter
let messageReceiver: MessageReceiver
@ -483,7 +483,7 @@ private struct ProcessingRequestBuilder {
init(
_ receivedEnvelope: ReceivedEnvelope,
blockingManager: BlockingManager,
localDeviceId: UInt32,
localDeviceId: DeviceId,
localIdentifiers: LocalIdentifiers,
messageDecrypter: OWSMessageDecrypter,
messageReceiver: MessageReceiver
@ -637,7 +637,7 @@ private extension MessageProcessor {
func processingRequest(
for envelope: ReceivedEnvelope,
localIdentifiers: LocalIdentifiers,
localDeviceId: UInt32,
localDeviceId: DeviceId,
tx: DBWriteTransaction
) -> ProcessingRequest {
assertOnQueue(serialQueue)
@ -676,7 +676,7 @@ private struct ReceivedEnvelope {
func decryptIfNeeded(
messageDecrypter: OWSMessageDecrypter,
localIdentifiers: LocalIdentifiers,
localDeviceId: UInt32,
localDeviceId: DeviceId,
tx: DBWriteTransaction
) throws -> DecryptionResult {
// Figure out what type of envelope we're dealing with.

View File

@ -1289,7 +1289,7 @@ public final class MessageReceiver {
// If destinationDevice is defined, ignore messages not addressed to this device.
let tsAccountManager = DependenciesBridge.shared.tsAccountManager
let localDeviceId = tsAccountManager.storedDeviceId(tx: tx)
if callMessage.hasDestinationDeviceID, callMessage.destinationDeviceID != localDeviceId {
if callMessage.hasDestinationDeviceID, callMessage.destinationDeviceID != localDeviceId.uint32Value {
Logger.info("Ignoring call message for other device #\(callMessage.destinationDeviceID)")
return
}
@ -1484,7 +1484,7 @@ public final class MessageReceiver {
private func recordEarlyReceipts(
receiptType: SSKProtoReceiptMessageType,
senderServiceId: ServiceId,
senderDeviceId: UInt32,
senderDeviceId: DeviceId,
associatedMessageTimestamps: [UInt64],
actionTimestamp: UInt64,
tx: DBWriteTransaction
@ -1516,7 +1516,7 @@ public final class MessageReceiver {
}
let errorMessage = try DecryptionErrorMessage(bytes: decryptionErrorMessage)
let tsAccountManager = DependenciesBridge.shared.tsAccountManager
guard errorMessage.deviceId == tsAccountManager.storedDeviceId(tx: tx) else {
guard errorMessage.deviceId == tsAccountManager.storedDeviceId(tx: tx).uint32Value else {
Logger.info("Received a DecryptionError message targeting a linked device. Ignoring.")
return
}

View File

@ -166,7 +166,7 @@ public class MessageSendLog {
func fetchPayload(
recipientAci: Aci,
recipientDeviceId: UInt32,
recipientDeviceId: DeviceId,
timestamp: UInt64,
tx: DBReadTransaction
) -> Payload? {
@ -185,7 +185,7 @@ public class MessageSendLog {
.joining(required: Payload.hasMany(Recipient.self).aliased(recipientAlias))
.filter(Column("sentTimestamp") == timestamp)
.filter(recipientAlias[Column("recipientUUID")] == recipientAci.serviceIdUppercaseString)
.filter(recipientAlias[Column("recipientDeviceId")] == Int64(recipientDeviceId))
.filter(recipientAlias[Column("recipientDeviceId")] == Int64(recipientDeviceId.uint32Value))
existingValue = try fetchUniquePayload(query: request, tx: tx)
} catch {
owsFailDebug("\(error)")
@ -265,14 +265,14 @@ public class MessageSendLog {
for payloadId: Int64,
recipientAci: Aci,
tx: DBReadTransaction
) -> [UInt32?]? {
) -> [DeviceId?]? {
do {
return try Recipient
.filter(Column("payloadId") == payloadId)
.filter(Column("recipientUuid") == recipientAci.serviceIdUppercaseString)
.select(Column("recipientDeviceId"), as: Int64.self)
.fetchAll(tx.database)
.map { UInt32(exactly: $0) }
.map { UInt32(exactly: $0).map(DeviceId.init(rawValue:)) }
} catch {
owsFailDebug("\(error)")
return nil
@ -282,7 +282,7 @@ public class MessageSendLog {
func recordPendingDelivery(
payloadId: Int64,
recipientAci: Aci,
recipientDeviceId: UInt32,
recipientDeviceId: DeviceId,
message: TSOutgoingMessage,
tx: DBWriteTransaction
) {
@ -293,7 +293,7 @@ public class MessageSendLog {
try Recipient(
payloadId: payloadId,
recipientUUID: recipientAci.serviceIdUppercaseString,
recipientDeviceId: Int64(recipientDeviceId)
recipientDeviceId: Int64(recipientDeviceId.uint32Value)
).insert(tx.database)
} catch let error as DatabaseError where error.extendedResultCode == .SQLITE_CONSTRAINT_FOREIGNKEY {
// There's a tiny race where a recipient could send a delivery receipt before we record an MSL entry
@ -317,7 +317,7 @@ public class MessageSendLog {
func recordSuccessfulDelivery(
message: TSOutgoingMessage,
recipientAci: Aci,
recipientDeviceId: UInt32,
recipientDeviceId: DeviceId,
tx: DBWriteTransaction
) {
guard !RemoteConfig.current.messageResendKillSwitch else {
@ -332,7 +332,7 @@ public class MessageSendLog {
try Recipient
.filter(Column("payloadId") == payloadId)
.filter(Column("recipientUuid") == recipientAci.serviceIdUppercaseString)
.filter(Column("recipientDeviceId") == recipientDeviceId)
.filter(Column("recipientDeviceId") == Int64(recipientDeviceId.uint32Value))
.deleteAll(db)
try deletePayloadIfNecessary(payload, tx: tx)

View File

@ -408,9 +408,9 @@ class MessageDeletedBeforeSentError: CustomNSError, IsRetryableProvider {
class MessageSendEncryptionError: CustomNSError, IsRetryableProvider {
public let serviceId: ServiceId
public let deviceId: UInt32
public let deviceId: DeviceId
init(serviceId: ServiceId, deviceId: UInt32) {
init(serviceId: ServiceId, deviceId: DeviceId) {
self.serviceId = serviceId
self.deviceId = deviceId
}

View File

@ -8,7 +8,7 @@ import LibSignalClient
extension MessageSender {
struct Recipient {
let serviceId: ServiceId
let devices: [UInt32]
let devices: [DeviceId]
var protocolAddresses: [ProtocolAddress] {
return devices.map { ProtocolAddress(serviceId, deviceId: $0) }
}

View File

@ -53,7 +53,7 @@ public class MessageSender {
// MARK: - Creating Signal Protocol Sessions
private func containsValidSession(for serviceId: ServiceId, deviceId: UInt32, tx: DBReadTransaction) throws -> Bool {
private func containsValidSession(for serviceId: ServiceId, deviceId: DeviceId, tx: DBReadTransaction) throws -> Bool {
let sessionStore = DependenciesBridge.shared.signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore
do {
guard let session = try sessionStore.loadSession(for: serviceId, deviceId: deviceId, tx: tx) else {
@ -74,7 +74,7 @@ public class MessageSender {
private func ensureRecipientHasSession(
recipientUniqueId: RecipientUniqueId,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
isOnlineMessage: Bool,
isTransientSenderKeyDistributionMessage: Bool,
sealedSenderParameters: SealedSenderParameters?
@ -109,7 +109,7 @@ public class MessageSender {
private func makePrekeyRequest(
recipientUniqueId: RecipientUniqueId?,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
isOnlineMessage: Bool,
isTransientSenderKeyDistributionMessage: Bool,
sealedSenderParameters: SealedSenderParameters?
@ -182,7 +182,7 @@ public class MessageSender {
for preKeyBundle: SignalServiceKit.PreKeyBundle,
recipientUniqueId: String,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
transaction: DBWriteTransaction
) throws {
assert(!Thread.isMainThread)
@ -203,7 +203,7 @@ public class MessageSender {
if let pqPreKey = deviceBundle.pqPreKey {
bundle = try LibSignalClient.PreKeyBundle(
registrationId: deviceBundle.registrationId,
deviceId: deviceId,
deviceId: deviceId.uint32Value,
prekeyId: preKey.keyId,
prekey: preKey.publicKey,
signedPrekeyId: deviceBundle.signedPreKey.keyId,
@ -217,7 +217,7 @@ public class MessageSender {
} else {
bundle = try LibSignalClient.PreKeyBundle(
registrationId: deviceBundle.registrationId,
deviceId: deviceId,
deviceId: deviceId.uint32Value,
prekeyId: preKey.keyId,
prekey: preKey.publicKey,
signedPrekeyId: deviceBundle.signedPreKey.keyId,
@ -230,7 +230,7 @@ public class MessageSender {
if let pqPreKey = deviceBundle.pqPreKey {
bundle = try LibSignalClient.PreKeyBundle(
registrationId: deviceBundle.registrationId,
deviceId: deviceId,
deviceId: deviceId.uint32Value,
signedPrekeyId: deviceBundle.signedPreKey.keyId,
signedPrekey: deviceBundle.signedPreKey.publicKey,
signedPrekeySignature: deviceBundle.signedPreKey.signature,
@ -242,7 +242,7 @@ public class MessageSender {
} else {
bundle = try LibSignalClient.PreKeyBundle(
registrationId: deviceBundle.registrationId,
deviceId: deviceId,
deviceId: deviceId.uint32Value,
signedPrekeyId: deviceBundle.signedPreKey.keyId,
signedPrekey: deviceBundle.signedPreKey.publicKey,
signedPrekeySignature: deviceBundle.signedPreKey.signature,
@ -253,7 +253,7 @@ public class MessageSender {
do {
let identityManager = DependenciesBridge.shared.identityManager
let protocolAddress = ProtocolAddress(serviceId, deviceId: deviceId)
let protocolAddress = ProtocolAddress(serviceId, deviceId: deviceId.uint32Value)
try processPreKeyBundle(
bundle,
for: protocolAddress,
@ -1382,7 +1382,7 @@ public class MessageSender {
messageEncryptionStyle: EncryptionStyle,
recipientUniqueId: RecipientUniqueId,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
isOnlineMessage: Bool,
isTransientSenderKeyDistributionMessage: Bool,
isResendRequestMessage: Bool,
@ -1611,8 +1611,8 @@ public class MessageSender {
}
struct MismatchedDevices: Decodable {
let extraDevices: [Int8]
let missingDevices: [Int8]
let extraDevices: [DeviceId]
let missingDevices: [DeviceId]
fileprivate static func parse(_ responseData: Data) throws -> Self {
return try JSONDecoder().decode(Self.self, from: responseData)
@ -1620,7 +1620,7 @@ public class MessageSender {
}
struct StaleDevices: Decodable {
let staleDevices: [Int8]
let staleDevices: [DeviceId]
fileprivate static func parse(_ responseData: Data) throws -> Self {
return try JSONDecoder().decode(Self.self, from: responseData)
@ -1729,28 +1729,28 @@ public class MessageSender {
)
}
func handleMismatchedDevices(serviceId: ServiceId, missingDevices: [Int8], extraDevices: [Int8], tx: DBWriteTransaction) {
func handleMismatchedDevices(serviceId: ServiceId, missingDevices: [DeviceId], extraDevices: [DeviceId], tx: DBWriteTransaction) {
Logger.warn("Mismatched devices for \(serviceId): +\(missingDevices) -\(extraDevices)")
self.updateDevices(
serviceId: serviceId,
devicesToAdd: missingDevices.compactMap({ UInt32(exactly: $0) }),
devicesToRemove: extraDevices.compactMap({ UInt32(exactly: $0) }),
devicesToAdd: missingDevices,
devicesToRemove: extraDevices,
transaction: tx
)
}
func handleStaleDevices(serviceId: ServiceId, staleDevices: [Int8], tx: DBWriteTransaction) {
func handleStaleDevices(serviceId: ServiceId, staleDevices: [DeviceId], tx: DBWriteTransaction) {
Logger.warn("Stale devices for \(serviceId): \(staleDevices)")
let sessionStore = DependenciesBridge.shared.signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore
for staleDeviceId in staleDevices.compactMap({ UInt32(exactly: $0) }) {
for staleDeviceId in staleDevices {
sessionStore.archiveSession(for: serviceId, deviceId: staleDeviceId, tx: tx)
}
}
func updateDevices(
serviceId: ServiceId,
devicesToAdd: [UInt32],
devicesToRemove: [UInt32],
devicesToAdd: [DeviceId],
devicesToRemove: [DeviceId],
transaction: DBWriteTransaction
) {
AssertNotOnMainThread()
@ -1781,7 +1781,7 @@ public class MessageSender {
private func encryptMessage(
plaintextContent plainText: Data,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
sealedSenderParameters: SealedSenderParameters?,
transaction: DBWriteTransaction
) throws -> DeviceMessage {
@ -1854,7 +1854,7 @@ public class MessageSender {
return DeviceMessage(
type: messageType,
destinationDeviceId: protocolAddress.deviceId,
destinationDeviceId: deviceId,
destinationRegistrationId: try session.remoteRegistrationId(),
content: serializedMessage
)
@ -1863,7 +1863,7 @@ public class MessageSender {
private func wrapPlaintextMessage(
plaintextContent rawPlaintext: Data,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
isResendRequestMessage: Bool,
sealedSenderParameters: SealedSenderParameters?,
transaction: DBWriteTransaction
@ -1909,7 +1909,7 @@ public class MessageSender {
let session = try sessionStore.loadSession(for: protocolAddress, context: transaction)!
return DeviceMessage(
type: messageType,
destinationDeviceId: protocolAddress.deviceId,
destinationDeviceId: deviceId,
destinationRegistrationId: try session.remoteRegistrationId(),
content: serializedMessage
)

View File

@ -128,7 +128,7 @@ public class OWSMessageDecrypter {
private struct UnsealedEnvelope {
let sourceAci: Aci
let sourceDeviceId: UInt32
let sourceDeviceId: DeviceId
let content: Data?
let cipherType: CiphertextMessage.MessageType
let untrustedGroupId: Data?
@ -305,7 +305,7 @@ public class OWSMessageDecrypter {
originalMessageBytes: unsealedContent,
type: unsealedEnvelope.cipherType,
timestamp: validatedEnvelope.timestamp,
originalSenderDeviceId: unsealedEnvelope.sourceDeviceId
originalSenderDeviceId: unsealedEnvelope.sourceDeviceId.uint32Value
)
return Data(errorMessage.serialize())
} catch {
@ -334,7 +334,7 @@ public class OWSMessageDecrypter {
private func resetSessionIfNecessary(
for sourceAci: Aci,
sourceDeviceId: UInt32,
sourceDeviceId: DeviceId,
contactThread: TSContactThread,
transaction: DBWriteTransaction
) -> Bool {
@ -527,7 +527,7 @@ public class OWSMessageDecrypter {
func decryptUnidentifiedSenderEnvelope(
_ validatedEnvelope: ValidatedIncomingEnvelope,
localIdentifiers: LocalIdentifiers,
localDeviceId: UInt32,
localDeviceId: DeviceId,
tx transaction: DBWriteTransaction
) throws -> DecryptedIncomingEnvelope {
let localIdentity = validatedEnvelope.localIdentity
@ -586,21 +586,19 @@ public class OWSMessageDecrypter {
DependenciesBridge.shared.preKeyManager.checkPreKeysIfNecessary(tx: transaction)
}
let rawSourceDeviceId = decryptResult.senderDeviceId
guard rawSourceDeviceId > 0, rawSourceDeviceId < UInt32.max else {
guard decryptResult.senderDeviceId.uint32Value > 0 else {
throw OWSAssertionError("Invalid UD sender device id.")
}
let sourceDeviceId = rawSourceDeviceId
let envelopeBuilder = validatedEnvelope.envelope.asBuilder()
envelopeBuilder.setSourceServiceID(decryptResult.senderAci.serviceIdString)
envelopeBuilder.setSourceDevice(sourceDeviceId)
envelopeBuilder.setSourceDevice(decryptResult.senderDeviceId.uint32Value)
let decryptedEnvelope = try DecryptedIncomingEnvelope(
validatedEnvelope: validatedEnvelope,
updatedEnvelope: try envelopeBuilder.build(),
sourceAci: decryptResult.senderAci,
sourceDeviceId: sourceDeviceId,
sourceDeviceId: decryptResult.senderDeviceId,
wasReceivedByUD: validatedEnvelope.envelope.sourceServiceID == nil,
plaintextData: decryptResult.paddedPayload.withoutPadding(),
isPlaintextCipher: decryptResult.messageType == .plaintext

View File

@ -46,7 +46,7 @@ final class OWSOutgoingResendResponse: TSOutgoingMessage {
convenience init?(
aci: Aci,
deviceId: UInt32,
deviceId: DeviceId,
failedTimestamp: UInt64,
didResetSession: Bool,
tx: DBWriteTransaction

View File

@ -883,7 +883,7 @@ extension OWSReceiptManager {
/// might arrive after the receipts.
func processDeliveryReceipts(
from recipientServiceId: ServiceId,
recipientDeviceId: UInt32,
recipientDeviceId: DeviceId,
sentTimestamps: [UInt64],
deliveryTimestamp: UInt64,
context: DeliveryReceiptContext,
@ -913,7 +913,7 @@ extension OWSReceiptManager {
/// might arrive after the receipts.
func processReadReceipts(
from recipientAci: Aci,
recipientDeviceId: UInt32,
recipientDeviceId: DeviceId,
sentTimestamps: [UInt64],
readTimestamp: UInt64,
tx: DBWriteTransaction
@ -946,7 +946,7 @@ extension OWSReceiptManager {
/// might arrive after the receipts.
func processViewedReceipts(
from recipientAci: Aci,
recipientDeviceId: UInt32,
recipientDeviceId: DeviceId,
sentTimestamps: [UInt64],
viewedTimestamp: UInt64,
tx: DBWriteTransaction

View File

@ -13,7 +13,7 @@ import LibSignalClient
class ServerReceiptEnvelope {
let validatedEnvelope: ValidatedIncomingEnvelope
let sourceServiceId: ServiceId
let sourceDeviceId: UInt32
let sourceDeviceId: DeviceId
init(_ validatedEnvelope: ValidatedIncomingEnvelope) throws {
let (sourceServiceId, sourceDeviceId) = try validatedEnvelope.validateSource(ServiceId.self)

View File

@ -392,7 +392,7 @@ public class OWSUDManagerImpl: OWSUDManager {
private func isValidCertificate(_ certificate: SenderCertificate) -> Bool {
let sender = certificate.sender
guard sender.deviceId == DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction else {
guard sender.deviceId == DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction.uint32Value else {
Logger.warn("Sender certificate has incorrect device ID")
return false
}

View File

@ -8,16 +8,16 @@ public import LibSignalClient
public struct SecretSessionKnownSenderError: Error {
public let senderAci: Aci
public let senderDeviceId: UInt32
public let senderDeviceId: DeviceId
public let cipherType: CiphertextMessage.MessageType
public let groupId: Data?
public let unsealedContent: Data
public let contentHint: UnidentifiedSenderMessageContent.ContentHint
public let underlyingError: Error
init(senderAci: Aci, messageContent: UnidentifiedSenderMessageContent, underlyingError: Error) {
init(senderAci: Aci, senderDeviceId: DeviceId, messageContent: UnidentifiedSenderMessageContent, underlyingError: Error) {
self.senderAci = senderAci
self.senderDeviceId = messageContent.senderCertificate.sender.deviceId
self.senderDeviceId = senderDeviceId
self.cipherType = messageContent.messageType
self.groupId = messageContent.groupId.map { Data($0) }
self.unsealedContent = Data(messageContent.contents)
@ -45,7 +45,7 @@ public enum SMKMessageType: Int {
public struct SMKDecryptResult {
let senderAci: Aci
let senderE164: String?
let senderDeviceId: UInt32
let senderDeviceId: DeviceId
let paddedPayload: Data
let messageType: SMKMessageType
}
@ -104,7 +104,7 @@ public class SMKSecretSessionCipher: NSObject {
public func encryptMessage(
for serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
paddedPlaintext: Data,
contentHint: UnidentifiedSenderMessageContent.ContentHint,
groupId: Data?,
@ -174,7 +174,7 @@ public class SMKSecretSessionCipher: NSObject {
cipherTextData: Data,
timestamp: UInt64,
localIdentifiers: LocalIdentifiers,
localDeviceId: UInt32,
localDeviceId: DeviceId,
protocolContext: StoreContext?
) throws -> SMKDecryptResult {
guard timestamp > 0 else {
@ -193,11 +193,12 @@ public class SMKSecretSessionCipher: NSObject {
guard sender.deviceId <= Int32.max else {
throw SMKError.assertionError(description: "[\(type(of: self))] Invalid senderDeviceId.")
}
let deviceId = DeviceId(rawValue: sender.deviceId)
guard let senderAci = Aci.parseFrom(aciString: sender.uuidString) else {
throw SMKError.assertionError(description: "[\(type(of: self))] Invalid senderAci.")
}
if localIdentifiers.aci == senderAci && sender.deviceId == localDeviceId {
if localIdentifiers.aci == senderAci && deviceId == localDeviceId {
Logger.info("Discarding self-sent message")
throw SMKSecretSessionCipherError.selfSentMessage
}
@ -216,13 +217,14 @@ public class SMKSecretSessionCipher: NSObject {
return SMKDecryptResult(
senderAci: senderAci,
senderE164: sender.e164,
senderDeviceId: sender.deviceId,
senderDeviceId: deviceId,
paddedPayload: Data(paddedMessagePlaintext),
messageType: SMKMessageType(messageContent.messageType)
)
} catch {
throw SecretSessionKnownSenderError(
senderAci: senderAci,
senderDeviceId: deviceId,
messageContent: messageContent,
underlyingError: error
)

View File

@ -69,7 +69,7 @@ class ValidatedIncomingEnvelope {
// MARK: - Source
func validateSource<T: ServiceId>(_ type: T.Type) throws -> (T, UInt32) {
func validateSource<T: ServiceId>(_ type: T.Type) throws -> (T, DeviceId) {
guard
let sourceServiceIdString = envelope.sourceServiceID,
let sourceServiceId = try ServiceId.parseFrom(serviceIdString: sourceServiceIdString) as? T
@ -79,7 +79,7 @@ class ValidatedIncomingEnvelope {
guard envelope.hasSourceDevice, envelope.sourceDevice >= 1 else {
throw OWSAssertionError("Invalid source device.")
}
return (sourceServiceId, envelope.sourceDevice)
return (sourceServiceId, DeviceId(rawValue: envelope.sourceDevice))
}
// MARK: - Destination

View File

@ -25,8 +25,8 @@ class MockSessionStore: SignalSessionStore {
func mergeRecipient(_ recipient: SignalRecipient, into targetRecipient: SignalRecipient, tx: DBWriteTransaction) { }
func archiveAllSessions(for serviceId: ServiceId, tx: DBWriteTransaction) { }
func archiveAllSessions(for address: SignalServiceAddress, tx: DBWriteTransaction) { }
func archiveSession(for serviceId: ServiceId, deviceId: UInt32, tx: DBWriteTransaction) { }
func loadSession(for serviceId: ServiceId, deviceId: UInt32, tx: DBReadTransaction) throws -> LibSignalClient.SessionRecord? { nil }
func archiveSession(for serviceId: ServiceId, deviceId: DeviceId, tx: DBWriteTransaction) { }
func loadSession(for serviceId: ServiceId, deviceId: DeviceId, tx: DBReadTransaction) throws -> LibSignalClient.SessionRecord? { nil }
func loadSession(for address: ProtocolAddress, context: StoreContext) throws -> LibSignalClient.SessionRecord? { nil }
func resetSessionStore(tx: DBWriteTransaction) { }
func deleteAllSessions(for serviceId: ServiceId, tx: DBWriteTransaction) { }

View File

@ -12,7 +12,7 @@ public enum AuthedDevice {
public enum DeviceId: Equatable {
case primary
case secondary(UInt32)
case secondary(SignalServiceKit.DeviceId)
public func authUsername(aci: Aci) -> String {
switch self {

View File

@ -493,7 +493,7 @@ public enum OWSRequestFactory {
return TSRequest(url: URL(string: path)!, method: "GET", parameters: [:])
}
static func recipientPreKeyRequest(serviceId: ServiceId, deviceId: UInt32, auth: TSRequest.SealedSenderAuth?) -> TSRequest {
static func recipientPreKeyRequest(serviceId: ServiceId, deviceId: DeviceId, auth: TSRequest.SealedSenderAuth?) -> TSRequest {
let path = "\(self.textSecureKeysAPI)/\(serviceId.serviceIdString)/\(deviceId)"
let request = TSRequest(url: URL(string: path)!, method: "GET", parameters: [:])

View File

@ -24,6 +24,6 @@ public enum ProvisioningServiceResponses {
public struct VerifySecondaryDeviceResponse: Codable, Equatable {
@PniUuid public var pni: Pni
public let deviceId: UInt32
public let deviceId: DeviceId
}
}

View File

@ -0,0 +1,34 @@
//
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public struct DeviceId: Codable, Comparable, CustomStringConvertible, Hashable {
private let rawValue: UInt32
public static let primary: DeviceId = DeviceId(rawValue: OWSDevice.primaryDeviceId)
public init(rawValue: UInt32) {
self.rawValue = rawValue
}
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
self.init(rawValue: try container.decode(UInt32.self))
}
public func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(self.rawValue)
}
public var description: String { "\(rawValue)" }
public static func < (lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue < rhs.rawValue
}
public var uint32Value: UInt32 { rawValue }
}

View File

@ -29,7 +29,7 @@ struct PreKeyBundle: Decodable {
}
struct PreKeyDeviceBundle: Decodable {
let deviceId: Int8
let deviceId: DeviceId
let registrationId: UInt32
let signedPreKey: SignedPreKey
let preKey: OneTimePreKey?

View File

@ -246,10 +246,10 @@ public final class SSKSessionStore: SignalSessionStore {
extension SSKSessionStore {
public func loadSession(
for serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
tx: DBReadTransaction
) throws -> SessionRecord? {
guard let serializedData = try loadSerializedSession(for: serviceId, deviceId: deviceId, tx: tx) else {
guard let serializedData = try loadSerializedSession(for: serviceId, deviceId: deviceId.uint32Value, tx: tx) else {
return nil
}
return try SessionRecord(bytes: serializedData)
@ -264,13 +264,13 @@ extension SSKSessionStore {
try storeSerializedSession(Data(record.serialize()), for: serviceId, deviceId: deviceId, tx: tx)
}
public func archiveSession(for serviceId: ServiceId, deviceId: UInt32, tx: DBWriteTransaction) {
public func archiveSession(for serviceId: ServiceId, deviceId: DeviceId, tx: DBWriteTransaction) {
do {
guard let session = try loadSession(for: serviceId, deviceId: deviceId, tx: tx) else {
return
}
session.archiveCurrentState()
try storeSession(session, for: serviceId, deviceId: deviceId, tx: tx)
try storeSession(session, for: serviceId, deviceId: deviceId.uint32Value, tx: tx)
} catch {
owsFailDebug("\(error)")
}
@ -279,7 +279,7 @@ extension SSKSessionStore {
extension SSKSessionStore: LibSignalClient.SessionStore {
public func loadSession(for address: ProtocolAddress, context: StoreContext) throws -> SessionRecord? {
return try loadSession(for: address.serviceId, deviceId: address.deviceId, tx: context.asTransaction)
return try loadSession(for: address.serviceId, deviceId: address.deviceIdObj, tx: context.asTransaction)
}
public func loadExistingSessions(

View File

@ -163,7 +163,7 @@ public class SenderKeyStore {
public func skdmBytesForThread(
_ thread: TSThread,
localAci: Aci,
localDeviceId: UInt32,
localDeviceId: DeviceId,
tx: DBWriteTransaction
) -> Data? {
do {
@ -211,7 +211,7 @@ extension SenderKeyStore: LibSignalClient.SenderKeyStore {
updatedValue = KeyMetadata(
record: record,
senderAci: senderAci,
senderDeviceId: sender.deviceId,
senderDeviceId: sender.deviceIdObj,
localIdentifiers: localIdentifiers,
localDeviceId: DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: tx),
distributionId: distributionId
@ -408,8 +408,8 @@ private struct KeyRecipient: Codable {
let deviceId: UInt32
let registrationId: UInt32?
init(deviceId: UInt32, registrationId: UInt32?) {
self.deviceId = deviceId
init(deviceId: DeviceId, registrationId: UInt32?) {
self.deviceId = deviceId.uint32Value
self.registrationId = registrationId
}
@ -447,19 +447,18 @@ private struct KeyRecipient: Codable {
throw OWSAssertionError("Invalid device array")
}
let deviceIds = recipient.deviceIds
let protocolAddresses = deviceIds.map { ProtocolAddress(serviceId, deviceId: $0) }
let sessionStore = DependenciesBridge.shared.signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore
let devices: [Device] = try protocolAddresses.map {
let devices: [Device] = try deviceIds.map { deviceId in
// We have to fetch the registrationId since deviceIds can be reused.
// By comparing a set of (deviceId,registrationId) structs, we should be able to detect reused
// deviceIds that will need an SKDM
let registrationId = try sessionStore.loadSession(
for: $0.serviceId,
deviceId: $0.deviceId,
for: serviceId,
deviceId: deviceId,
tx: tx
)?.remoteRegistrationId()
return Device(deviceId: $0.deviceId, registrationId: registrationId)
return Device(deviceId: deviceId, registrationId: registrationId)
}
return KeyRecipient(devices: Set(devices))
}
@ -477,7 +476,7 @@ private struct KeyRecipient: Codable {
private struct KeyMetadata {
let distributionId: SenderKeyStore.DistributionId
@AciUuid var ownerAci: Aci
let ownerDeviceId: UInt32
let ownerDeviceId: DeviceId
var keyId: String { SenderKeyStore.buildKeyId(authorAci: ownerAci, distributionId: distributionId) }
@ -509,9 +508,9 @@ private struct KeyMetadata {
init(
record: SenderKeyRecord,
senderAci: Aci,
senderDeviceId: UInt32,
senderDeviceId: DeviceId,
localIdentifiers: LocalIdentifiers,
localDeviceId: UInt32,
localDeviceId: DeviceId,
distributionId: SenderKeyStore.DistributionId
) {
self.serializedRecord = Data(record.serialize())
@ -569,7 +568,7 @@ extension KeyMetadata: Codable {
distributionId = try container.decode(SenderKeyStore.DistributionId.self, forKey: .distributionId)
_ownerAci = try container.decode(AciUuid.self, forKey: .ownerAci)
ownerDeviceId = try container.decode(UInt32.self, forKey: .ownerDeviceId)
ownerDeviceId = try container.decode(DeviceId.self, forKey: .ownerDeviceId)
creationDate = try container.decode(Date.self, forKey: .creationDate)
isForEncrypting = try container.decode(Bool.self, forKey: .isForEncrypting)

View File

@ -31,13 +31,13 @@ public protocol SignalSessionStore: LibSignalClient.SessionStore {
func archiveSession(
for serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
tx: DBWriteTransaction
)
func loadSession(
for serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
tx: DBReadTransaction
) throws -> SessionRecord?

View File

@ -1066,7 +1066,7 @@ class StorageServiceOperation {
manifestBuilder.setRecordIkm(manifestRecordIkm)
}
manifestBuilder.setKeys(identifiers.map { $0.buildRecord() })
manifestBuilder.setSourceDevice(DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction)
manifestBuilder.setSourceDevice(DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction.uint32Value)
return manifestBuilder.buildInfallibly()
}

View File

@ -15,11 +15,11 @@ public protocol TypingIndicators: AnyObject {
func didSendOutgoingMessage(inThread thread: TSThread)
func didReceiveTypingStartedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: UInt32)
func didReceiveTypingStartedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: DeviceId)
func didReceiveTypingStoppedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: UInt32)
func didReceiveTypingStoppedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: DeviceId)
func didReceiveIncomingMessage(inThread thread: TSThread, senderAci: Aci, deviceId: UInt32)
func didReceiveIncomingMessage(inThread thread: TSThread, senderAci: Aci, deviceId: DeviceId)
// Returns the address of the user who should currently be shown typing for a given thread.
//
@ -114,19 +114,19 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators {
outgoingIndicators.didSendOutgoingMessage()
}
public func didReceiveTypingStartedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: UInt32) {
public func didReceiveTypingStartedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: DeviceId) {
AssertIsOnMainThread()
ensureIncomingIndicators(forThread: thread, senderAci: senderAci, deviceId: deviceId)
.didReceiveTypingStartedMessage()
}
public func didReceiveTypingStoppedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: UInt32) {
public func didReceiveTypingStoppedMessage(inThread thread: TSThread, senderAci: Aci, deviceId: DeviceId) {
AssertIsOnMainThread()
ensureIncomingIndicators(forThread: thread, senderAci: senderAci, deviceId: deviceId)
.didReceiveTypingStoppedMessage()
}
public func didReceiveIncomingMessage(inThread thread: TSThread, senderAci: Aci, deviceId: UInt32) {
public func didReceiveIncomingMessage(inThread thread: TSThread, senderAci: Aci, deviceId: DeviceId) {
AssertIsOnMainThread()
ensureIncomingIndicators(forThread: thread, senderAci: senderAci, deviceId: deviceId)
.didReceiveIncomingMessage()
@ -296,18 +296,18 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators {
private var incomingIndicatorsMap = [String: [AddressWithDeviceId: IncomingIndicators]]()
private struct AddressWithDeviceId: Hashable {
let aci: Aci
let deviceId: UInt32
let deviceId: DeviceId
}
private func incomingIndicatorsKey(forThread thread: TSThread) -> String {
return String(describing: thread.uniqueId)
return thread.uniqueId
}
private func incomingIndicatorsKey(aci: Aci, deviceId: UInt32) -> AddressWithDeviceId {
private func incomingIndicatorsKey(aci: Aci, deviceId: DeviceId) -> AddressWithDeviceId {
return AddressWithDeviceId(aci: aci, deviceId: deviceId)
}
private func ensureIncomingIndicators(forThread thread: TSThread, senderAci: Aci, deviceId: UInt32) -> IncomingIndicators {
private func ensureIncomingIndicators(forThread thread: TSThread, senderAci: Aci, deviceId: DeviceId) -> IncomingIndicators {
AssertIsOnMainThread()
let threadKey = incomingIndicatorsKey(forThread: thread)
@ -332,7 +332,7 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators {
private weak var delegate: TypingIndicators?
private let thread: TSThread
fileprivate let senderAci: Aci
private let deviceId: UInt32
private let deviceId: DeviceId
private var displayTypingTimer: Timer?
fileprivate var startedTypingTimestamp: UInt64?
@ -347,7 +347,7 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators {
}
}
init(delegate: TypingIndicators, thread: TSThread, senderAci: Aci, deviceId: UInt32) {
init(delegate: TypingIndicators, thread: TSThread, senderAci: Aci, deviceId: DeviceId) {
self.delegate = delegate
self.thread = thread
self.senderAci = senderAci

View File

@ -45,12 +45,12 @@ class PniDistributionParameterBuilderTest: XCTestCase {
}
messageSenderMock.deviceMessageMocks.update {
$0[123] = .valid(registrationId: 456)
$0[DeviceId(rawValue: 123)] = .valid(registrationId: 456)
}
let parameters = try await build(
localDeviceId: 1,
localUserAllDeviceIds: [1, 123],
localDeviceId: DeviceId(rawValue: 1),
localUserAllDeviceIds: [1, 123].map(DeviceId.init(rawValue:)),
localPniIdentityKeyPair: pniKeyPair,
localDevicePniSignedPreKey: localSignedPreKey,
localDevicePniPqLastResortPreKey: localPqLastResortPreKey,
@ -75,7 +75,7 @@ class PniDistributionParameterBuilderTest: XCTestCase {
)
XCTAssertEqual(parameters.deviceMessages.count, 1)
XCTAssertEqual(parameters.deviceMessages.first?.destinationDeviceId, 123)
XCTAssertEqual(parameters.deviceMessages.first?.destinationDeviceId, DeviceId(rawValue: 123))
XCTAssertEqual(parameters.deviceMessages.first?.destinationRegistrationId, 456)
XCTAssertTrue(messageSenderMock.deviceMessageMocks.get().isEmpty)
@ -90,13 +90,13 @@ class PniDistributionParameterBuilderTest: XCTestCase {
}
messageSenderMock.deviceMessageMocks.update {
$0[123] = .valid(registrationId: 456)
$0[DeviceId(rawValue: 123)] = .valid(registrationId: 456)
}
let result = await Result {
return try await build(
localDeviceId: 1,
localUserAllDeviceIds: [2, 123],
localDeviceId: DeviceId(rawValue: 1),
localUserAllDeviceIds: [2, 123].map(DeviceId.init(rawValue:)),
localPniIdentityKeyPair: pniKeyPair,
localDevicePniSignedPreKey: localSignedPreKey,
localDevicePniPqLastResortPreKey: localPqLastResortPreKey,
@ -118,13 +118,13 @@ class PniDistributionParameterBuilderTest: XCTestCase {
}
messageSenderMock.deviceMessageMocks.update {
$0[123] = .valid(registrationId: 456)
$0[1234] = .invalidDevice
$0[DeviceId(rawValue: 123)] = .valid(registrationId: 456)
$0[DeviceId(rawValue: 1234)] = .invalidDevice
}
let parameters = try await build(
localDeviceId: 1,
localUserAllDeviceIds: [1, 123, 1234],
localDeviceId: DeviceId(rawValue: 1),
localUserAllDeviceIds: [1, 123, 1234].map(DeviceId.init(rawValue:)),
localPniIdentityKeyPair: pniKeyPair,
localDevicePniSignedPreKey: localSignedPreKey,
localDevicePniPqLastResortPreKey: localPqLastResortPreKey,
@ -142,7 +142,7 @@ class PniDistributionParameterBuilderTest: XCTestCase {
XCTAssertLessThan(parameters.pniRegistrationIds.count, registrationIdGeneratorMock.generatedRegistrationIds.count)
XCTAssertEqual(parameters.deviceMessages.count, 1)
XCTAssertEqual(parameters.deviceMessages.first?.destinationDeviceId, 123)
XCTAssertEqual(parameters.deviceMessages.first?.destinationDeviceId, DeviceId(rawValue: 123))
XCTAssertEqual(parameters.deviceMessages.first?.destinationRegistrationId, 456)
XCTAssert(messageSenderMock.deviceMessageMocks.get().isEmpty)
@ -157,13 +157,13 @@ class PniDistributionParameterBuilderTest: XCTestCase {
}
messageSenderMock.deviceMessageMocks.update {
$0[123] = .error
$0[DeviceId(rawValue: 123)] = .error
}
let result = await Result {
return try await build(
localDeviceId: 1,
localUserAllDeviceIds: [1, 123],
localDeviceId: DeviceId(rawValue: 1),
localUserAllDeviceIds: [1, 123].map(DeviceId.init(rawValue:)),
localPniIdentityKeyPair: pniKeyPair,
localDevicePniSignedPreKey: localSignedPreKey,
localDevicePniPqLastResortPreKey: localPqLastResortPreKey,
@ -180,8 +180,8 @@ class PniDistributionParameterBuilderTest: XCTestCase {
// MARK: Helpers
private func build(
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32],
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId],
localPniIdentityKeyPair: ECKeyPair,
localDevicePniSignedPreKey: SignalServiceKit.SignedPreKeyRecord,
localDevicePniPqLastResortPreKey: SignalServiceKit.KyberPreKeyRecord,
@ -219,14 +219,14 @@ private class MessageSenderMock: PniDistributionParameterBuilderImpl.Shims.Messa
private struct BuildDeviceMessageError: Error {}
/// Populated with device messages to be returned by ``buildDeviceMessage``.
let deviceMessageMocks: AtomicValue<[UInt32: DeviceMessageMock]> = .init([:], lock: .init())
let deviceMessageMocks: AtomicValue<[DeviceId: DeviceMessageMock]> = .init([:], lock: .init())
func buildDeviceMessage(
forMessagePlaintextContent messagePlaintextContent: Data,
messageEncryptionStyle: EncryptionStyle,
recipientUniqueId: String,
serviceId: ServiceId,
deviceId: UInt32,
deviceId: DeviceId,
isOnlineMessage: Bool,
isTransientSenderKeyDistributionMessage: Bool,
isResendRequestMessage: Bool,

View File

@ -81,7 +81,7 @@ class PniHelloWorldManagerTest: XCTestCase {
aci: localIdentifiers.aci,
pni: localIdentifiers.pni,
phoneNumber: E164(localIdentifiers.phoneNumber)!,
deviceIds: [1, 2, 3]
deviceIds: [1, 2, 3].map(DeviceId.init(rawValue:))
), transaction: tx)
}
@ -99,7 +99,7 @@ class PniHelloWorldManagerTest: XCTestCase {
try await runRunRun()
XCTAssert(didMakeNetworkRequest)
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3]])
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3].map(DeviceId.init(rawValue:))])
XCTAssertTrue(db.read { kvStore.hasSaidHelloWorld(tx: $0) })
}
@ -112,7 +112,7 @@ class PniHelloWorldManagerTest: XCTestCase {
try await runRunRun()
XCTAssert(didMakeNetworkRequest)
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3]])
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3].map(DeviceId.init(rawValue:))])
XCTAssertTrue(db.read { kvStore.hasSaidHelloWorld(tx: $0) })
}
@ -175,7 +175,7 @@ class PniHelloWorldManagerTest: XCTestCase {
try? await runRunRun()
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3]])
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3].map(DeviceId.init(rawValue:))])
XCTAssertFalse(db.read { kvStore.hasSaidHelloWorld(tx: $0) })
}
@ -185,7 +185,7 @@ class PniHelloWorldManagerTest: XCTestCase {
try? await runRunRun()
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3]])
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedDeviceIds, [[1, 2, 3].map(DeviceId.init(rawValue:))])
XCTAssertFalse(db.read { kvStore.hasSaidHelloWorld(tx: $0) })
}
}
@ -211,13 +211,13 @@ private class PniDistributionParamaterBuilderMock: PniDistributionParamaterBuild
}
var buildOutcomes: [BuildOutcome] = []
var buildRequestedDeviceIds: [[UInt32]] = []
var buildRequestedDeviceIds: [[DeviceId]] = []
func buildPniDistributionParameters(
localAci _: Aci,
localRecipientUniqueId _: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32],
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId],
localPniIdentityKeyPair: ECKeyPair,
localE164: E164,
localDevicePniSignedPreKey: SignalServiceKit.SignedPreKeyRecord,

View File

@ -54,7 +54,7 @@ class ChangePhoneNumberPniManagerTest: XCTestCase {
let (parameters, pendingState) = await generateIdentity(
e164: e164,
linkedDeviceIds: [2, 3]
linkedDeviceIds: [DeviceId(rawValue: 2), DeviceId(rawValue: 3)]
).awaitable().unwrapSuccess
XCTAssertEqual(e164, pendingState.newE164)
@ -69,7 +69,8 @@ class ChangePhoneNumberPniManagerTest: XCTestCase {
XCTAssertEqual(registrationIdGeneratorMock.generatedRegistrationIds.count, 1)
XCTAssertEqual(registrationIdGeneratorMock.generatedRegistrationIds.first, pendingState.localDevicePniRegistrationId)
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedForDeviceIds, [[1, 2, 3]])
let expectedDeviceIds = [DeviceId(rawValue: 1), DeviceId(rawValue: 2), DeviceId(rawValue: 3)]
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedForDeviceIds, [expectedDeviceIds])
XCTAssertTrue(pniDistributionParameterBuilderMock.buildOutcomes.isEmpty)
}
@ -80,7 +81,7 @@ class ChangePhoneNumberPniManagerTest: XCTestCase {
let isFailureResult = await generateIdentity(
e164: e164,
linkedDeviceIds: [2, 3]
linkedDeviceIds: [DeviceId(rawValue: 2), DeviceId(rawValue: 3)]
).awaitable().isError
XCTAssertTrue(isFailureResult)
@ -89,7 +90,8 @@ class ChangePhoneNumberPniManagerTest: XCTestCase {
XCTAssertEqual(signedPreKeyStoreMock.generatedSignedPreKeys.count, 1)
XCTAssertEqual(registrationIdGeneratorMock.generatedRegistrationIds.count, 1)
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedForDeviceIds, [[1, 2, 3]])
let expectedDeviceIds = [DeviceId(rawValue: 1), DeviceId(rawValue: 2), DeviceId(rawValue: 3)]
XCTAssertEqual(pniDistributionParameterBuilderMock.buildRequestedForDeviceIds, [expectedDeviceIds])
XCTAssertTrue(pniDistributionParameterBuilderMock.buildOutcomes.isEmpty)
}
@ -102,7 +104,7 @@ class ChangePhoneNumberPniManagerTest: XCTestCase {
let (_, pendingState) = await generateIdentity(
e164: e164,
linkedDeviceIds: [2, 3]
linkedDeviceIds: [DeviceId(rawValue: 2), DeviceId(rawValue: 3)]
).awaitable().unwrapSuccess
db.write { transaction in
@ -140,12 +142,12 @@ class ChangePhoneNumberPniManagerTest: XCTestCase {
private func generateIdentity(
e164: E164,
linkedDeviceIds: [UInt32]
linkedDeviceIds: [DeviceId]
) -> Guarantee<ChangePhoneNumberPni.GeneratePniIdentityResult> {
let aci = Aci.randomForTesting()
let recipientUniqueId: String = UUID().uuidString
let localDeviceId: UInt32 = 1
let localDeviceId: DeviceId = .primary
return changeNumberPniManager.generatePniIdentity(
forNewE164: e164,
@ -223,13 +225,13 @@ private class PniDistributionParameterBuilderMock: PniDistributionParamaterBuild
}
var buildOutcomes: [BuildOutcome] = []
var buildRequestedForDeviceIds: [[UInt32]] = []
var buildRequestedForDeviceIds: [[DeviceId]] = []
func buildPniDistributionParameters(
localAci: Aci,
localRecipientUniqueId: String,
localDeviceId: UInt32,
localUserAllDeviceIds: [UInt32],
localDeviceId: DeviceId,
localUserAllDeviceIds: [DeviceId],
localPniIdentityKeyPair: ECKeyPair,
localE164: E164,
localDevicePniSignedPreKey: SignalServiceKit.SignedPreKeyRecord,

View File

@ -18,7 +18,7 @@ final class ContactDiscoveryManagerTest: XCTestCase {
static func foundResponse(for phoneNumbers: Set<String>) -> Set<SignalRecipient> {
Set(phoneNumbers.lazy.map {
SignalRecipient(aci: Aci.randomForTesting(), pni: Pni.randomForTesting(), phoneNumber: E164($0)!, deviceIds: [1])
SignalRecipient(aci: Aci.randomForTesting(), pni: Pni.randomForTesting(), phoneNumber: E164($0)!, deviceIds: [DeviceId(rawValue: 1)])
})
}
}

View File

@ -675,7 +675,7 @@ final class SignalRecipient2Test: XCTestCase {
XCTAssertEqual(signalRecipients[0].id, 18)
XCTAssertEqual(signalRecipients[0].uniqueId, "00000000-0000-4000-8000-00000000000A")
XCTAssertEqual(signalRecipients[0].deviceIds, [1, 2, 5, 4, 6])
XCTAssertEqual(signalRecipients[0].deviceIds, [1, 2, 5, 4, 6].map(DeviceId.init(rawValue:)))
XCTAssertEqual(signalRecipients[0].phoneNumber?.stringValue, "+16505550100")
XCTAssertEqual(signalRecipients[0].phoneNumber?.isDiscoverable, false)
XCTAssertEqual(signalRecipients[0].aciString, "00000000-0000-4000-8000-000000000000")
@ -729,7 +729,7 @@ final class SignalRecipient2Test: XCTestCase {
}
func testEqualityAndHashing() {
let someRecipient = SignalRecipient(aci: Aci.randomForTesting(), pni: nil, phoneNumber: nil, deviceIds: [1, 2])
let someRecipient = SignalRecipient(aci: Aci.randomForTesting(), pni: nil, phoneNumber: nil, deviceIds: [1, 2].map(DeviceId.init(rawValue:)))
let copiedRecipient = someRecipient.copyRecipient()
XCTAssertEqual(copiedRecipient, someRecipient)
XCTAssertEqual(copiedRecipient.hashValue, someRecipient.hashValue)
@ -792,9 +792,9 @@ final class SignalRecipient2Test: XCTestCase {
mockDb.write { tx in
for testCase in testCases {
let recipient = recipientFetcher.fetchOrCreate(serviceId: Aci.randomForTesting(), tx: tx)
recipientManager.setDeviceIds(testCase.initialDeviceIds, for: recipient, shouldUpdateStorageService: false)
recipientManager.markAsRegisteredAndSave(recipient, deviceId: testCase.addedDeviceId, shouldUpdateStorageService: false, tx: tx)
XCTAssertEqual(Set(recipient.deviceIds), testCase.expectedDeviceIds, "\(testCase)")
recipientManager.setDeviceIds(Set(testCase.initialDeviceIds.map(DeviceId.init(rawValue:))), for: recipient, shouldUpdateStorageService: false)
recipientManager.markAsRegisteredAndSave(recipient, deviceId: DeviceId(rawValue: testCase.addedDeviceId), shouldUpdateStorageService: false, tx: tx)
XCTAssertEqual(Set(recipient.deviceIds), Set(testCase.expectedDeviceIds.map(DeviceId.init(rawValue:))), "\(testCase)")
}
}
}

View File

@ -236,7 +236,7 @@ private class MockDevicesService: OWSDeviceService {
return true
}
func unlinkDevice(deviceId: Int, auth: ChatServiceAuth) async throws {}
func unlinkDevice(deviceId: DeviceId, auth: ChatServiceAuth) async throws {}
func renameDevice(device: OWSDevice, toEncryptedName encryptedName: String) async throws {}
}

View File

@ -517,7 +517,7 @@ private enum CrashyMocks {
}
final class MockCallMessageHandler: CallMessageHandler {
func receivedEnvelope(_ envelope: SSKProtoEnvelope, callEnvelope: CallEnvelopeType, from caller: (aci: Aci, deviceId: UInt32), toLocalIdentity localIdentity: OWSIdentity, plaintextData: Data, wasReceivedByUD: Bool, sentAtTimestamp: UInt64, serverReceivedTimestamp: UInt64, serverDeliveryTimestamp: UInt64, tx: DBWriteTransaction) { failTest(Self.self) }
func receivedEnvelope(_ envelope: SSKProtoEnvelope, callEnvelope: CallEnvelopeType, from caller: (aci: Aci, deviceId: DeviceId), toLocalIdentity localIdentity: OWSIdentity, plaintextData: Data, wasReceivedByUD: Bool, sentAtTimestamp: UInt64, serverReceivedTimestamp: UInt64, serverDeliveryTimestamp: UInt64, tx: DBWriteTransaction) { failTest(Self.self) }
func receivedGroupCallUpdateMessage(_ updateMessage: SSKProtoDataMessageGroupCallUpdate, forGroupId groupId: GroupIdentifier, serverReceivedTimestamp: UInt64) async { failTest(Self.self) }
}

View File

@ -227,14 +227,14 @@ final class DisappearingMessageFinderTest: SSKBaseTest {
expiringDeliveredOutgoingMessage.update(
withDeliveredRecipient: otherAddress,
deviceId: 0,
deviceId: DeviceId(rawValue: 0),
deliveryTimestamp: now,
context: PassthroughDeliveryReceiptContext(),
tx: transaction
)
expiringDeliveredAndReadOutgoingMessage.update(
withReadRecipient: otherAddress,
deviceId: 0,
deviceId: DeviceId(rawValue: 0),
readTimestamp: now,
tx: transaction
)

View File

@ -144,7 +144,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: otherAci,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
message: message,
tx: transaction
)
@ -154,7 +154,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
message.update(
withDeliveredRecipient: otherAddress,
deviceId: 1,
deviceId: DeviceId(rawValue: 1),
deliveryTimestamp: NSDate.ows_millisecondTimeStamp(),
context: PassthroughDeliveryReceiptContext(),
tx: transaction
@ -184,14 +184,14 @@ class TSOutgoingMessageTest: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: otherAci,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
message: message,
tx: transaction
)
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: otherAci,
recipientDeviceId: 2,
recipientDeviceId: DeviceId(rawValue: 2),
message: message,
tx: transaction
)
@ -201,7 +201,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
message.update(
withDeliveredRecipient: otherAddress,
deviceId: 1,
deviceId: DeviceId(rawValue: 1),
deliveryTimestamp: NSDate.ows_millisecondTimeStamp(),
context: PassthroughDeliveryReceiptContext(),
tx: transaction
@ -212,7 +212,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
message.update(
withDeliveredRecipient: otherAddress,
deviceId: 2,
deviceId: DeviceId(rawValue: 2),
deliveryTimestamp: NSDate.ows_millisecondTimeStamp(),
context: PassthroughDeliveryReceiptContext(),
tx: transaction
@ -243,7 +243,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: otherAci,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
message: message,
tx: transaction
)
@ -253,7 +253,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
message.update(
withDeliveredRecipient: otherAddress,
deviceId: 1,
deviceId: DeviceId(rawValue: 1),
deliveryTimestamp: NSDate.ows_millisecondTimeStamp(),
context: PassthroughDeliveryReceiptContext(),
tx: transaction
@ -283,7 +283,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: otherAci,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
message: message,
tx: transaction
)
@ -294,7 +294,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
message.update(
withDeliveredRecipient: otherAddress,
deviceId: 1,
deviceId: DeviceId(rawValue: 1),
deliveryTimestamp: NSDate.ows_millisecondTimeStamp(),
context: PassthroughDeliveryReceiptContext(),
tx: transaction
@ -327,7 +327,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: otherAci,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
message: message,
tx: transaction
)
@ -354,7 +354,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
message.update(
withDeliveredRecipient: otherAddress,
deviceId: 1,
deviceId: DeviceId(rawValue: 1),
deliveryTimestamp: NSDate.ows_millisecondTimeStamp(),
context: PassthroughDeliveryReceiptContext(),
tx: transaction

View File

@ -21,7 +21,7 @@ class MessageSendLogTests: SSKBaseTest {
// "Send" the message to a recipient
let serviceId = Aci.randomForTesting()
let deviceId = UInt32.random(in: 0..<100)
let deviceId = DeviceId(rawValue: UInt32.random(in: 0..<100))
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
@ -53,7 +53,7 @@ class MessageSendLogTests: SSKBaseTest {
// "Send" the message to one recipient
let serviceId = Aci.randomForTesting()
let deviceId = UInt32.random(in: 0..<100)
let deviceId = DeviceId(rawValue: UInt32.random(in: 0..<100))
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
@ -65,7 +65,7 @@ class MessageSendLogTests: SSKBaseTest {
// Expect no results when re-fetching the payload with a different deviceId
XCTAssertNil(messageSendLog.fetchPayload(
recipientAci: serviceId,
recipientDeviceId: deviceId+1,
recipientDeviceId: DeviceId(rawValue: deviceId.uint32Value+1),
timestamp: newMessage.timestamp,
tx: writeTx
))
@ -89,7 +89,7 @@ class MessageSendLogTests: SSKBaseTest {
// "Send" the message to two devices
let serviceId = Aci.randomForTesting()
for deviceId: UInt32 in [0, 1] {
for deviceId in [0, 1].map(DeviceId.init(rawValue:)) {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
@ -103,14 +103,14 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
tx: writeTx
)
// Expect no results when re-fetching the payload for the first device
XCTAssertNil(messageSendLog.fetchPayload(
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
timestamp: newMessage.timestamp,
tx: writeTx
))
@ -118,7 +118,7 @@ class MessageSendLogTests: SSKBaseTest {
// Expect some results when re-fetching the payload for the second device
XCTAssertNotNil(messageSendLog.fetchPayload(
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
timestamp: newMessage.timestamp,
tx: writeTx
))
@ -134,7 +134,7 @@ class MessageSendLogTests: SSKBaseTest {
// "Send" the message to a recipient
let serviceId = Aci.randomForTesting()
let deviceId = UInt32.random(in: 0..<100)
let deviceId = DeviceId(rawValue: UInt32.random(in: 0..<100))
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
@ -162,7 +162,7 @@ class MessageSendLogTests: SSKBaseTest {
// "Send" the message to one recipient, two devices
let serviceId = Aci.randomForTesting()
for deviceId: UInt32 in [0, 1] {
for deviceId in [0, 1].map(DeviceId.init(rawValue:)) {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
@ -177,7 +177,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
tx: writeTx
)
@ -188,7 +188,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
tx: writeTx
)
@ -210,14 +210,14 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
message: newMessage,
tx: writeTx
)
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
tx: writeTx
)
@ -225,7 +225,7 @@ class MessageSendLogTests: SSKBaseTest {
XCTAssertTrue(isPayloadAlive(index: payloadId, transaction: writeTx))
// "Send" the message to two more devices. Mark send as complete
for deviceId: UInt32 in [1, 2] {
for deviceId in [1, 2].map(DeviceId.init(rawValue:)) {
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
@ -240,7 +240,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
tx: writeTx
)
@ -251,7 +251,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 2,
recipientDeviceId: DeviceId(rawValue: 2),
tx: writeTx
)
@ -273,7 +273,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: initialPayloadId,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
message: newMessage,
tx: writeTx
)
@ -285,7 +285,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: initialPayloadId,
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
message: newMessage,
tx: writeTx
)
@ -299,7 +299,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
tx: writeTx
)
@ -310,7 +310,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
tx: writeTx
)
@ -331,14 +331,14 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: initialPayloadId,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
message: newMessage,
tx: writeTx
)
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 0,
recipientDeviceId: DeviceId(rawValue: 0),
tx: writeTx
)
messageSendLog.sendComplete(message: newMessage, tx: writeTx)
@ -351,7 +351,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordPendingDelivery(
payloadId: secondPayloadId,
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
message: newMessage,
tx: writeTx
)
@ -359,7 +359,7 @@ class MessageSendLogTests: SSKBaseTest {
messageSendLog.recordSuccessfulDelivery(
message: newMessage,
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
tx: writeTx
)
@ -397,7 +397,7 @@ class MessageSendLogTests: SSKBaseTest {
// "Send" the message to a recipient
let serviceId = Aci.randomForTesting()
let deviceId = UInt32.random(in: 0..<100)
let deviceId = DeviceId(rawValue: UInt32.random(in: 0..<100))
messageSendLog.recordPendingDelivery(
payloadId: payloadId,
recipientAci: serviceId,
@ -430,7 +430,7 @@ class MessageSendLogTests: SSKBaseTest {
// "Send" the messages to a recipient
let serviceId = Aci.randomForTesting()
let deviceId = UInt32.random(in: 0..<100)
let deviceId = DeviceId(rawValue: UInt32.random(in: 0..<100))
for index in [index1, index2, index3] {
messageSendLog.recordPendingDelivery(
payloadId: index,
@ -502,11 +502,11 @@ class MessageSendLogTests: SSKBaseTest {
XCTAssertEqual(message.timestamp, originalTimestamp)
let index = try XCTUnwrap(messageSendLog.recordPayload(data, for: message, tx: writeTx))
messageSendLog.recordPendingDelivery(payloadId: index, recipientAci: serviceId, recipientDeviceId: 1, message: message, tx: writeTx)
messageSendLog.recordPendingDelivery(payloadId: index, recipientAci: serviceId, recipientDeviceId: DeviceId(rawValue: 1), message: message, tx: writeTx)
let fetchedPayload = messageSendLog.fetchPayload(
recipientAci: serviceId,
recipientDeviceId: 1,
recipientDeviceId: DeviceId(rawValue: 1),
timestamp: originalTimestamp,
tx: writeTx
)

View File

@ -14,14 +14,14 @@ class SMKSecretSessionCipherTest: XCTestCase {
private lazy var aliceMockClient = MockClient(
aci: Aci.constantForTesting("aaaaaaaa-7000-11eb-b32a-33b8a8a487a6"),
phoneNumber: E164("+16505550100")!,
deviceId: 1,
deviceId: .primary,
registrationId: 1234
)
private lazy var bobMockClient = MockClient(
aci: Aci.constantForTesting("bbbbbbbb-7000-11eb-b32a-33b8a8a487a6"),
phoneNumber: E164("+16505550101")!,
deviceId: 1,
deviceId: .primary,
registrationId: 1234
)
@ -155,7 +155,7 @@ class SMKSecretSessionCipherTest: XCTestCase {
originalMessageBytes: knownSenderError.unsealedContent,
type: knownSenderError.cipherType,
timestamp: 31335,
originalSenderDeviceId: knownSenderError.senderDeviceId
originalSenderDeviceId: knownSenderError.senderDeviceId.uint32Value
)
)
XCTAssertEqual(knownSenderError.senderAci, aliceMockClient.aci)
@ -235,7 +235,7 @@ class SMKSecretSessionCipherTest: XCTestCase {
originalMessageBytes: knownSenderError.unsealedContent,
type: knownSenderError.cipherType,
timestamp: 31338,
originalSenderDeviceId: knownSenderError.senderDeviceId
originalSenderDeviceId: knownSenderError.senderDeviceId.uint32Value
)
)
XCTAssertEqual(knownSenderError.senderAci, aliceMockClient.aci)
@ -421,7 +421,7 @@ class SMKSecretSessionCipherTest: XCTestCase {
// through decryption failures because of missing a missing sender key. This will
// help with recovery.
XCTAssertEqual(knownSenderError.senderAci, aliceMockClient.aci)
XCTAssertEqual(knownSenderError.senderDeviceId, UInt32(aliceMockClient.deviceId))
XCTAssertEqual(knownSenderError.senderDeviceId, aliceMockClient.deviceId)
XCTAssertEqual(Data(knownSenderError.groupId!), "inyalowda".data(using: String.Encoding.utf8)!)
XCTAssertEqual(knownSenderError.contentHint, .resendable)
XCTAssertNoThrow(
@ -429,7 +429,7 @@ class SMKSecretSessionCipherTest: XCTestCase {
originalMessageBytes: knownSenderError.unsealedContent,
type: knownSenderError.cipherType,
timestamp: 31335,
originalSenderDeviceId: knownSenderError.senderDeviceId
originalSenderDeviceId: knownSenderError.senderDeviceId.uint32Value
)
)

View File

@ -14,7 +14,7 @@ class MockClient {
try! SealedSenderAddress(
e164: phoneNumber.stringValue,
uuidString: aci.serviceIdString,
deviceId: UInt32(deviceId)
deviceId: deviceId.uint32Value
)
}
@ -24,7 +24,7 @@ class MockClient {
let aci: Aci
let phoneNumber: E164
let deviceId: UInt32
let deviceId: DeviceId
let registrationId: Int32
let identityKeyPair: IdentityKeyPair
@ -36,7 +36,7 @@ class MockClient {
let identityStore: InMemorySignalProtocolStore
let senderKeyStore: InMemorySignalProtocolStore
init(aci: Aci, phoneNumber: E164, deviceId: UInt32, registrationId: Int32) {
init(aci: Aci, phoneNumber: E164, deviceId: DeviceId, registrationId: Int32) {
self.aci = aci
self.phoneNumber = phoneNumber
self.deviceId = deviceId
@ -100,7 +100,7 @@ class MockClient {
// PreKeyBundle bobBundle = new PreKeyBundle(1, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey());
let bobBundle = try! PreKeyBundle(
registrationId: UInt32(bitPattern: bobMockClient.registrationId),
deviceId: bobMockClient.deviceId,
deviceId: bobMockClient.deviceId.uint32Value,
prekeyId: bobPreKey.id,
prekey: try! bobPreKey.publicKey(),
signedPrekeyId: bobSignedPreKey.id,

View File

@ -38,7 +38,7 @@ class SessionStoreTest: SSKBaseTest {
read {
XCTAssertTrue(sessionStore.mightContainSession(for: recipient, tx: $0))
XCTAssertNotNil(try! sessionStore.loadSession(for: recipient.aci!, deviceId: 1, tx: $0))
XCTAssertNotNil(try! sessionStore.loadSession(for: recipient.aci!, deviceId: DeviceId(rawValue: 1), tx: $0))
}
// Then imitate a session store with a mix of legacy and modern sessions.
@ -55,7 +55,7 @@ class SessionStoreTest: SSKBaseTest {
// There's something in the store...
XCTAssertTrue(sessionStore.mightContainSession(for: recipient, tx: $0))
// ...but it turns into nil on load.
XCTAssertNil(try! sessionStore.loadSession(for: recipient.aci!, deviceId: 2, tx: $0))
XCTAssertNil(try! sessionStore.loadSession(for: recipient.aci!, deviceId: DeviceId(rawValue: 2), tx: $0))
}
}
}

View File

@ -27,7 +27,7 @@ final class ChatServiceAuthTest: XCTestCase {
let aciString = "125a6d22-5364-4583-9132-66227867d9ec"
let aci = Aci.constantForTesting(aciString)
let auth = ChatServiceAuth.explicit(aci: aci, deviceId: .secondary(3), password: "foo bar")
let auth = ChatServiceAuth.explicit(aci: aci, deviceId: .secondary(DeviceId(rawValue: 3)), password: "foo bar")
XCTAssertEqual(auth.credentials, .explicit(username: "\(aciString).3", password: "foo bar"))
}