130 lines
4 KiB
Swift
130 lines
4 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
public import LibSignalClient
|
|
|
|
public class LocalIdentifiersObjC: NSObject {
|
|
public let wrappedValue: LocalIdentifiers
|
|
|
|
public init(_ wrappedValue: LocalIdentifiers) {
|
|
self.wrappedValue = wrappedValue
|
|
}
|
|
|
|
@objc
|
|
public var aci: AciObjC { AciObjC(wrappedValue.aci) }
|
|
|
|
@objc
|
|
public var aciAddress: SignalServiceAddress { wrappedValue.aciAddress }
|
|
|
|
@objc
|
|
public var phoneNumber: String { wrappedValue.phoneNumber }
|
|
}
|
|
|
|
public class LocalIdentifiers {
|
|
/// The ACI for the current user.
|
|
public let aci: Aci
|
|
|
|
/// The PNI for the current user.
|
|
///
|
|
/// - Note: Primary & linked devices may not have access to their PNI. The
|
|
/// primary may need to fetch it from the server, and a linked device may be
|
|
/// waiting to learn about it from the primary.
|
|
public let pni: Pni?
|
|
|
|
/// The phone number for the current user.
|
|
///
|
|
/// - Note: This is a `String` because the phone number we've saved to disk
|
|
/// in prior versions of the application may not be a valid E164.
|
|
public let phoneNumber: String
|
|
|
|
public init(aci: Aci, pni: Pni?, phoneNumber: String) {
|
|
self.aci = aci
|
|
self.pni = pni
|
|
self.phoneNumber = phoneNumber
|
|
}
|
|
|
|
public convenience init(aci: Aci, pni: Pni?, e164: E164) {
|
|
self.init(aci: aci, pni: pni, phoneNumber: e164.stringValue)
|
|
}
|
|
|
|
/// Checks if `serviceId` refers to ourself.
|
|
///
|
|
/// Returns true if it's our ACI or our PNI.
|
|
public func contains(serviceId: ServiceId) -> Bool {
|
|
return serviceId == aci || serviceId == pni
|
|
}
|
|
|
|
/// Checks if `phoneNumber` refers to ourself.
|
|
public func contains(phoneNumber: E164) -> Bool {
|
|
return contains(phoneNumber: phoneNumber.stringValue)
|
|
}
|
|
|
|
/// Checks if `phoneNumber` refers to ourself.
|
|
public func contains(phoneNumber: String) -> Bool {
|
|
return phoneNumber == self.phoneNumber
|
|
}
|
|
|
|
/// Checks if `address` refers to ourself.
|
|
///
|
|
/// This generally means that `address.serviceId` matches our ACI or PNI.
|
|
public func contains(address: SignalServiceAddress) -> Bool {
|
|
// If the address has a ServiceId, then it must match one of our
|
|
// ServiceIds. (If it has some other ServiceId, then it's not us because
|
|
// that's not our ServiceId, even if the phone number matches.)
|
|
if let serviceId = address.serviceId {
|
|
return contains(serviceId: serviceId)
|
|
}
|
|
// Otherwise, it's us if the phone number matches. (This shouldn't happen
|
|
// in production because we populate `SignalServiceAddressCache` with our
|
|
// own identifiers.)
|
|
if let phoneNumber = address.phoneNumber {
|
|
return contains(phoneNumber: phoneNumber)
|
|
}
|
|
return false
|
|
}
|
|
|
|
public func containsAnyOf(aci: Aci?, phoneNumber: E164?, pni: Pni?) -> Bool {
|
|
if let aci, self.aci == aci {
|
|
return true
|
|
}
|
|
if let phoneNumber, self.phoneNumber == phoneNumber.stringValue {
|
|
return true
|
|
}
|
|
if let pni, self.pni == pni {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
public func isAciAddressEqualToAddress(_ address: SignalServiceAddress) -> Bool {
|
|
if let serviceId = address.serviceId {
|
|
return serviceId == self.aci
|
|
}
|
|
return address.phoneNumber == self.phoneNumber
|
|
}
|
|
}
|
|
|
|
public extension LocalIdentifiers {
|
|
var aciAddress: SignalServiceAddress {
|
|
SignalServiceAddress(serviceId: aci, phoneNumber: phoneNumber)
|
|
}
|
|
}
|
|
|
|
// MARK: - Unit Tests
|
|
|
|
#if TESTABLE_BUILD
|
|
|
|
extension LocalIdentifiers {
|
|
static var forUnitTests: LocalIdentifiers {
|
|
return LocalIdentifiers(
|
|
aci: Aci.constantForTesting("00000000-0000-4000-8000-000000000AAA"),
|
|
pni: Pni.constantForTesting("PNI:00000000-0000-4000-8000-000000000BBB"),
|
|
phoneNumber: "+16505550100"
|
|
)
|
|
}
|
|
}
|
|
|
|
#endif
|