Improve registration+backups logging

This commit is contained in:
Pete Walters 2026-03-13 10:19:47 -05:00 committed by GitHub
parent c051d06b11
commit 0142d39ef4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 288 additions and 160 deletions

View File

@ -92,16 +92,20 @@ public class SignalApp {
desiredMode: RegistrationMode,
appReadiness: AppReadinessSetter,
) {
let logger: PrefixedLogger
switch desiredMode {
case .registering:
Logger.info("Attempting initial registration on app launch")
logger = PrefixedLogger(prefix: "[Reg]")
logger.info("Attempting initial registration on app launch")
case .reRegistering:
Logger.info("Attempting reregistration on app launch")
logger = PrefixedLogger(prefix: "[ReReg]")
logger.info("Attempting reregistration on app launch")
case .changingNumber:
Logger.info("Attempting change number registration on app launch")
logger = PrefixedLogger(prefix: "[ChgNum]")
logger.info("Attempting change number registration on app launch")
}
let coordinator = SSKEnvironment.shared.databaseStorageRef.write { tx in
return loader.coordinator(forDesiredMode: desiredMode, transaction: tx)
return loader.coordinator(forDesiredMode: desiredMode, transaction: tx, logger: logger)
}
let navController = RegistrationNavigationController.withCoordinator(coordinator, appReadiness: appReadiness)

View File

@ -165,6 +165,8 @@ public protocol RegistrationCoordinator {
/// Cancel from the backup entry screen and clear out any key that has been entered.
func cancelRecoveryKeyEntry() -> Guarantee<RegistrationStep>
var logger: PrefixedLogger { get }
}
public enum AcknowledgeReglockResult {

View File

@ -20,16 +20,19 @@ extension RegistrationCoordinatorImpl {
e164: E164,
candidateCredentials: [SVR2AuthCredential],
signalService: OWSSignalServiceProtocol,
logger: PrefixedLogger,
) async -> SVR2AuthCheckResponse {
let request = RegistrationRequestFactory.svr2AuthCredentialCheckRequest(
e164: e164,
credentials: candidateCredentials,
logger: logger,
)
return await makeRequest(
{ try await signalService.urlSessionForMainSignalService().performRequest(request) },
handler: self.handleSVR2AuthCheckResponse(statusCode:retryAfterHeader:bodyData:),
handler: self.handleSVR2AuthCheckResponse(statusCode:retryAfterHeader:bodyData:logger:),
fallbackError: .genericError,
networkFailureError: .networkError,
logger: logger,
)
}
@ -37,6 +40,7 @@ extension RegistrationCoordinatorImpl {
statusCode: Int,
retryAfterHeader: TimeInterval?,
bodyData: Data?,
logger: PrefixedLogger,
) -> SVR2AuthCheckResponse {
let statusCode = RegistrationServiceResponses.SVR2AuthCheckResponseCodes(rawValue: statusCode)
switch statusCode {
@ -68,6 +72,7 @@ extension RegistrationCoordinatorImpl {
apnRegistrationId: RegistrationRequestFactory.ApnRegistrationId?,
prekeyBundles: RegistrationPreKeyUploadBundles,
signalService: OWSSignalServiceProtocol,
logger: PrefixedLogger,
) async -> AccountResponse {
let request = RegistrationRequestFactory.createAccountRequest(
verificationMethod: method,
@ -77,6 +82,7 @@ extension RegistrationCoordinatorImpl {
skipDeviceTransfer: skipDeviceTransfer,
apnRegistrationId: apnRegistrationId,
prekeyBundles: prekeyBundles,
logger: logger,
)
return await makeRequest(
{ try await signalService.urlSessionForMainSignalService().performRequest(request) },
@ -86,10 +92,12 @@ extension RegistrationCoordinatorImpl {
statusCode: $0,
retryAfterHeader: $1,
bodyData: $2,
logger: $3,
)
},
fallbackError: .genericError,
networkFailureError: .networkError,
logger: logger,
)
}
@ -98,6 +106,7 @@ extension RegistrationCoordinatorImpl {
statusCode: Int,
retryAfterHeader: TimeInterval?,
bodyData: Data?,
logger: PrefixedLogger,
) -> AccountResponse {
let statusCode = RegistrationServiceResponses.AccountCreationResponseCodes(rawValue: statusCode)
switch statusCode {
@ -168,21 +177,23 @@ extension RegistrationCoordinatorImpl {
authPassword: String,
pniChangeNumberParameters: PniDistribution.Parameters,
networkManager: any NetworkManagerProtocol,
logger: PrefixedLogger,
) async -> AccountResponse {
let request = RegistrationRequestFactory.changeNumberRequest(
verificationMethod: method,
e164: e164,
reglockToken: reglockToken,
pniChangeNumberParameters: pniChangeNumberParameters,
logger: .empty(), // TODO [Registration+Backups Logging]
logger: logger,
)
return await makeRequest(
{ try await networkManager.asyncRequest(request) },
handler: {
return self.handleChangeNumberResponse(authPassword: authPassword, statusCode: $0, retryAfterHeader: $1, bodyData: $2)
return self.handleChangeNumberResponse(authPassword: authPassword, statusCode: $0, retryAfterHeader: $1, bodyData: $2, logger: $3)
},
fallbackError: .genericError,
networkFailureError: .networkError,
logger: logger,
)
}
@ -191,6 +202,7 @@ extension RegistrationCoordinatorImpl {
statusCode: Int,
retryAfterHeader: TimeInterval?,
bodyData: Data?,
logger: PrefixedLogger,
) -> AccountResponse {
let statusCode = RegistrationServiceResponses.ChangeNumberResponseCodes(rawValue: statusCode)
switch statusCode {
@ -255,12 +267,13 @@ extension RegistrationCoordinatorImpl {
reglockToken: String,
auth: ChatServiceAuth,
networkManager: any NetworkManagerProtocol,
logger: PrefixedLogger,
) async throws {
try await Retry.performWithBackoff(
maxAttempts: RegistrationCoordinatorImpl.Constants.networkErrorRetries + 1,
isRetryable: { $0.isNetworkFailureOrTimeout },
) {
var request = OWSRequestFactory.enableRegistrationLockV2Request(token: reglockToken)
var request = OWSRequestFactory.enableRegistrationLockV2Request(token: reglockToken, logger: logger)
request.auth = .identified(auth)
_ = try await networkManager.asyncRequest(request)
}
@ -270,6 +283,7 @@ extension RegistrationCoordinatorImpl {
_ attributes: AccountAttributes,
auth: ChatServiceAuth,
networkManager: any NetworkManagerProtocol,
logger: PrefixedLogger,
) async throws {
try await Retry.performWithBackoff(
maxAttempts: RegistrationCoordinatorImpl.Constants.networkErrorRetries + 1,
@ -278,6 +292,7 @@ extension RegistrationCoordinatorImpl {
let request = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
attributes,
auth: auth,
logger: logger,
)
let response = try await networkManager.asyncRequest(request)
guard response.responseStatusCode >= 200, response.responseStatusCode < 300 else {
@ -325,9 +340,10 @@ extension RegistrationCoordinatorImpl {
private static func makeRequest<ResponseType>(
_ makeRequest: () async throws -> HTTPResponse,
handler: (_ statusCode: Int, _ retryAfterHeader: TimeInterval?, _ bodyData: Data?) -> ResponseType,
handler: (_ statusCode: Int, _ retryAfterHeader: TimeInterval?, _ bodyData: Data?, _ logger: PrefixedLogger) -> ResponseType,
fallbackError: ResponseType,
networkFailureError: ResponseType,
logger: PrefixedLogger,
) async -> ResponseType {
do {
let response = try await makeRequest()
@ -335,6 +351,7 @@ extension RegistrationCoordinatorImpl {
response.responseStatusCode,
response.headers.retryAfterTimeInterval,
response.responseBodyData,
logger,
)
} catch where error.isNetworkFailureOrTimeout {
return networkFailureError
@ -343,6 +360,7 @@ extension RegistrationCoordinatorImpl {
error.responseStatusCode,
error.responseHeaders?.retryAfterTimeInterval,
error.httpResponseData,
logger,
)
} catch {
return fallbackError

View File

@ -26,17 +26,20 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
mode: RegistrationCoordinatorLoaderImpl.Mode,
loader: RegistrationCoordinatorLoaderDelegate,
dependencies: RegistrationCoordinatorDependencies,
logger: PrefixedLogger,
) {
self._unsafeToModify_mode = mode
self.kvStore = KeyValueStore(collection: "RegistrationCoordinator")
self.loader = loader
self.baseLogger = logger
self.logger = logger
self.deps = dependencies
}
// MARK: - Public API
public func switchToSecondaryDeviceLinking() -> Bool {
Logger.info("")
logger.info("")
switch mode {
case .registering:
@ -54,11 +57,11 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func exitRegistration() -> Bool {
Logger.info("")
logger.info("")
switch canExitRegistrationFlow() {
case .notAllowed:
Logger.warn("User can't exit registration now")
logger.warn("User can't exit registration now")
return false
case .allowed(let shouldWipeState):
if shouldWipeState {
@ -86,7 +89,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func continueFromSplash() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
db.write { tx in
self.updatePersistedState(tx) {
@ -97,7 +100,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func requestPermissions() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
return Guarantee.wrapAsync { @MainActor in
// Notifications first, then contacts if needed.
@ -109,19 +112,19 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func submitProspectiveChangeNumberE164(_ e164: E164) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
self.inMemoryState.changeNumberProspectiveE164 = e164
return Guarantee.wrapAsync { await self.nextStep() }
}
public func submitE164(_ e164: E164) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
var e164 = e164
switch mode {
case .reRegistering(let reregState):
if e164 != reregState.e164 {
Logger.debug("Tried to submit a changed e164 during rereg; ignoring and submitting the fixed e164 instead.")
logger.debug("Tried to submit a changed e164 during rereg; ignoring and submitting the fixed e164 instead.")
e164 = reregState.e164
}
case .registering, .changingNumber:
@ -175,7 +178,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func requestChangeE164() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
db.write { tx in
updatePersistedState(tx) {
$0.e164 = nil
@ -193,7 +196,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func requestSMSCode() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
switch getPathway() {
case
.opening,
@ -212,7 +215,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func requestVoiceCode() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
switch getPathway() {
case
.opening,
@ -231,7 +234,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func submitVerificationCode(_ code: String) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
switch getPathway() {
case
.opening,
@ -336,7 +339,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func submitCaptcha(_ token: String) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
switch getPathway() {
case
.opening,
@ -366,19 +369,19 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func setPINCodeForConfirmation(_ blob: RegistrationPinConfirmationBlob) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
inMemoryState.unconfirmedPinBlob = blob
return Guarantee.wrapAsync { await self.nextStep() }
}
public func resetUnconfirmedPINCode() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
inMemoryState.unconfirmedPinBlob = nil
return Guarantee.wrapAsync { await self.nextStep() }
}
public func submitPINCode(_ code: String) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
switch getPathway() {
case .registrationRecoveryPassword:
if
@ -436,7 +439,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func skipPINCode() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
let shouldGiveUpTryingToRestoreWithSVR: Bool = {
switch getPathway() {
case
@ -475,7 +478,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func skipAndCreateNewPINCode() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
switch getPathway() {
case
.opening,
@ -484,7 +487,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
.registrationRecoveryPassword,
.svrAuthCredentialCandidates,
.session:
Logger.error("Invalid state from which to skip!")
logger.error("Invalid state from which to skip!")
return Guarantee.wrapAsync { await self.nextStep() }
case
.svrAuthCredential,
@ -514,7 +517,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func skipRestoreFromBackup() -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
inMemoryState.hasSkippedRestoreFromMessageBackup = true
inMemoryState.needsToAskForDeviceTransfer = false
@ -570,7 +573,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
identity: AccountIdentity,
progress: OWSSequentialProgressRootSink<BackupRestoreProgressPhase>?,
) async {
Logger.info("")
logger.info("")
return await _doBackupRestoreStep {
let downloadProgress = await progress?.child(for: .downloadingBackup).addChild(
withLabel: "",
@ -596,7 +599,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
backupKey: backupKey,
backupAuth: backupServiceAuth,
progress: downloadProgress,
logger: .empty(), // TODO [Registration+Backups Logging]
logger: self.logger,
)
}
@ -633,7 +636,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
} else if let metadataHeader = self.inMemoryState.backupMetadataHeader {
nonceSource = .svrB(header: metadataHeader, auth: identity.chatServiceAuth)
} else {
Logger.info("Missing metadata header; refetching from cdn")
self.logger.info("Missing metadata header; refetching from cdn")
let backupServiceAuth = try await self.fetchBackupServiceAuth(
accountEntropyPool: accountEntropyPool,
accountIdentity: identity,
@ -641,7 +644,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
let metadataHeader = try await self.deps.backupArchiveManager.backupCdnInfo(
backupKey: backupKey,
backupAuth: backupServiceAuth,
logger: .empty(), // TODO [Registration+Backups Logging]
logger: self.logger,
).metadataHeader
self.inMemoryState.backupMetadataHeader = metadataHeader
nonceSource = .svrB(header: metadataHeader, auth: identity.chatServiceAuth)
@ -653,7 +656,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
isPrimaryDevice: true,
source: .remote(key: backupKey, nonceSource: nonceSource),
progress: importProgress,
logger: .empty(), // TODO [Registration+Backups Logging]
logger: self.logger,
)
}
}
@ -661,7 +664,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
private func finalizeRestoreFromMessageBackup(
identity: AccountIdentity,
) async {
Logger.info("")
logger.info("")
return await _doBackupRestoreStep {
try await self.deps.backupArchiveManager.finalizeBackupImport(progress: nil)
}
@ -681,7 +684,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
case .none, .unfinalized:
throw OWSAssertionError("Hasn't restored despite no thrown error!")
case .finalized:
Logger.info("Finished restore")
logger.info("Finished restore")
return
}
} catch {
@ -716,7 +719,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func setPhoneNumberDiscoverability(_ phoneNumberDiscoverability: PhoneNumberDiscoverability) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
guard let accountIdentity = persistedState.accountIdentity else {
owsFailBeta("Shouldn't be setting phone number discoverability prior to registration.")
return .value(.showErrorSheet(.genericError))
@ -736,7 +739,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
avatarData: Data?,
phoneNumberDiscoverability: PhoneNumberDiscoverability,
) -> Guarantee<RegistrationStep> {
Logger.info("")
logger.info("")
guard let accountIdentity = persistedState.accountIdentity else {
owsFailBeta("Shouldn't be setting phone number discoverability prior to registration.")
@ -754,7 +757,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
public func acknowledgeReglockTimeout() -> AcknowledgeReglockResult {
Logger.info("")
logger.info("")
switch reglockTimeoutAcknowledgeAction {
case .resetPhoneNumber:
@ -789,6 +792,9 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
private let deps: RegistrationCoordinatorDependencies
private let kvStore: KeyValueStore
public private(set) var logger: PrefixedLogger
private let baseLogger: PrefixedLogger
// Shortcuts for the commonly used ones.
private var db: any DB { deps.db }
@ -1301,7 +1307,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
await withTaskGroup { group in
group.addTask {
let session = await self.deps.sessionManager.restoreSession()
let session = await self.deps.sessionManager.restoreSession(logger: self.logger)
await self.db.awaitableWrite { self.processSession(session, $0) }
}
group.addTask {
@ -1322,7 +1328,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
accountEntropyPool: SignalServiceKit.AccountEntropyPool,
accountIdentity: AccountIdentity,
) async -> RegistrationStep {
Logger.info("")
logger.info("")
switch mode {
case .registering:
@ -1452,7 +1458,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// releaseRestrictedWebSocket needs to be called before this happens.
try await deps.remoteConfigManager.refreshIfNeeded()
} catch {
Logger.warn("Failed to fetch remote config: \(error)")
logger.warn("Failed to fetch remote config: \(error)")
}
// Start syncing system contacts now that we have set up tsAccountManager.
@ -1471,7 +1477,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
accountEntropyPool: SignalServiceKit.AccountEntropyPool,
accountIdentity: AccountIdentity,
) async -> RegistrationStep {
Logger.info("")
logger.info("")
do {
// For manual restore, fetch the backup info
@ -1483,7 +1489,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
let cdnInfo = try await self.deps.backupArchiveManager.backupCdnInfo(
backupKey: backupKey,
backupAuth: backupServiceAuth,
logger: .empty(), // TODO [Registration+Backups Logging]
logger: logger,
)
self.inMemoryState.backupMetadataHeader = cdnInfo.metadataHeader
return .confirmRestoreFromBackup(
@ -1496,7 +1502,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
)
} catch {
let errorType = self.deps.registrationBackupErrorPresenter.mapToRegistrationError(error: error)
Logger.error("Can't fetch backup info: \(error.localizedDescription)")
logger.error("Can't fetch backup info: \(error.localizedDescription)")
let step = await self.deps.registrationBackupErrorPresenter.presentError(
error: errorType,
isQuickRestore: self.persistedState.restoreMode == .quickRestore,
@ -1530,14 +1536,14 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
accountIdentity: AccountIdentity,
) async throws -> BackupServiceAuth {
let backupKey = try MessageRootBackupKey(accountEntropyPool: accountEntropyPool, aci: accountIdentity.aci)
Logger.info("Fetching backup auth [\(accountEntropyPool.getLoggingKey())]")
logger.info("Fetching backup auth [\(accountEntropyPool.getLoggingKey())]")
func fetchBackupServiceAuth() async throws -> BackupServiceAuth {
return try await self.deps.backupRequestManager.fetchBackupServiceAuthForRegistration(
key: backupKey,
localAci: accountIdentity.aci,
chatServiceAuth: accountIdentity.chatServiceAuth,
logger: .empty(), // TODO [Registration+Backups Logging]
logger: logger,
)
}
@ -1547,7 +1553,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
try await self.deps.backupIdService.updateMessageBackupIdForRegistration(
key: backupKey,
auth: accountIdentity.chatServiceAuth,
logger: .empty(), // TODO [Registration+Backups Logging]
logger: logger,
)
return try await fetchBackupServiceAuth()
}
@ -1560,7 +1566,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
) async -> RegistrationStep {
let maxAutomaticRetries = Constants.networkErrorRetries
Logger.info("")
logger.info("")
let error = await self.updateAccountAttributes(accountIdentity)
@ -1575,7 +1581,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// If we have a deregistration error, it doesn't matter. We are finished
// and cleaning up anyway; the main app will discover the issue.
if let error {
Logger.warn("Failed account attributes update, finishing registration anyway: \(error)")
logger.warn("Failed account attributes update, finishing registration anyway: \(error)")
}
// We are done! Wipe everything
self.inMemoryState = InMemoryState()
@ -1590,7 +1596,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
private func wipePersistedState(_ tx: DBWriteTransaction) {
Logger.info("")
logger.info("")
self.kvStore.removeValue(forKey: Constants.persistedStateKey, transaction: tx)
self.loader.clearPersistedMode(transaction: tx)
@ -1743,7 +1749,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
@MainActor
private func nextStep(pathway: Pathway) async -> RegistrationStep {
Logger.info("Going to next step for \(pathway.logSafeString) pathway")
logger.info("Going to next step for \(pathway.logSafeString) pathway")
switch pathway {
case .opening:
@ -1935,7 +1941,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
let pinFromDisk = inMemoryState.pinFromDisk,
pinFromDisk != pinFromUser
{
Logger.warn("PIN mismatch; should be prevented at submission time.")
logger.warn("PIN mismatch; should be prevented at submission time.")
return .pinEntry(RegistrationPinState(
operation: .enteringExistingPin(skippability: .canSkip, remainingAttempts: nil),
error: .wrongPin(wrongPin: pinFromUser),
@ -2132,7 +2138,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// session path. Reg recovery password based recovery is best effort
// anyway. Besides since this is always our first attempt at registering,
// this lockout should never happen.
Logger.error("Rate limited when registering via recovery password; falling back to session.")
logger.error("Rate limited when registering via recovery password; falling back to session.")
wipeInMemoryStateToPreventSVRPathAttempts()
return await startSession(e164: e164, failureCount: 0)
@ -2279,6 +2285,12 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
private func updateMasterKeyAndLocalState(masterKey: MasterKey?, tx: DBWriteTransaction) {
let localMasterKey = masterKey
let logSuffix = if let masterKey {
"[\(String(masterKey.data(for: .loggingKey).canonicalStringRepresentation.suffix(4)))]"
} else {
"[NoKey]"
}
self.logger = baseLogger.suffixed(with: logSuffix)
let regRecoveryPw = localMasterKey?.data(
for: .registrationRecoveryPassword,
).canonicalStringRepresentation
@ -2323,6 +2335,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
e164: e164,
candidateCredentials: svr2AuthCredentialCandidates,
signalService: deps.signalService,
logger: logger,
)
return await self.handleSVR2AuthCredentialCheckResponse(
response,
@ -2822,6 +2835,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
let response = await deps.sessionManager.beginOrRestoreSession(
e164: e164,
apnsToken: apnsToken,
logger: logger,
)
switch response {
@ -2887,6 +2901,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
let result = await self.deps.sessionManager.requestVerificationCode(
for: session,
transport: transport,
logger: logger,
)
switch result {
@ -2897,7 +2912,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
return await nextStep()
case .rejectedArgument(let session):
Logger.error("Should never get rejected argument error from requesting code. E164 already set on session.")
logger.error("Should never get rejected argument error from requesting code. E164 already set on session.")
// Wipe the pending code request, so we don't retry.
inMemoryState.pendingCodeTransport = nil
db.write {
@ -3021,12 +3036,12 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
) {
switch persistedState.sessionState?.pushChallengeState {
case nil, .notRequested, .waitingForPush, .rejected:
Logger.info("No pre-auth challenge token will arrive. Noting that")
logger.info("No pre-auth challenge token will arrive. Noting that")
updatePersistedSessionState(session: session, transaction) {
$0.pushChallengeState = .ineligible
}
case .ineligible, .unfulfilledPush, .fulfilled:
Logger.info("No pre-auth challenge token will arrive, but we don't need to update our state")
logger.info("No pre-auth challenge token will arrive, but we don't need to update our state")
}
}
@ -3039,12 +3054,12 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// It's unlikely but possible to go from ineligible -> waiting if the user denied
// notification permissions, closed the app, re-enabled them in settings, and then
// relaunched. It's much more likely that we'd be in the "not requested" state.
Logger.info("Started waiting for a pre-auth challenge token")
logger.info("Started waiting for a pre-auth challenge token")
self.updatePersistedSessionState(session: session, transaction) {
$0.pushChallengeState = .waitingForPush(requestedAt: deps.dateProvider())
}
case .waitingForPush, .unfulfilledPush, .fulfilled:
Logger.info("Already waiting for a pre-auth challenge token, presumably from a prior launch")
logger.info("Already waiting for a pre-auth challenge token, presumably from a prior launch")
}
// There is no timeout on this promise. That's deliberate. If we get a push challenge token
@ -3065,7 +3080,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
transaction: DBWriteTransaction,
) {
deps.pushRegistrationManager.clearPreAuthChallengeToken()
Logger.info("Received a push challenge token")
logger.info("Received a push challenge token")
updatePersistedSessionState(session: session, transaction) {
$0.pushChallengeState = .unfulfilledPush(challengeToken: pushChallengeToken)
}
@ -3075,7 +3090,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
private func attemptToFulfillAvailableChallengesWaitingIfNeeded(
for session: RegistrationSession,
) async -> RegistrationStep {
Logger.info("Found \(session.requestedInformation.count) challenge(s)")
logger.info("Found \(session.requestedInformation.count) challenge(s)")
var requestsPushChallenge = false
var requestsCaptchaChallenge = false
@ -3097,7 +3112,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}()
if requestsPushChallenge, let unfulfilledPushChallengeToken {
Logger.info("Attempting to fulfill push challenge with a token we already have")
logger.info("Attempting to fulfill push challenge with a token we already have")
return await submit(
challengeFulfillment: .pushChallenge(unfulfilledPushChallengeToken),
for: session,
@ -3110,7 +3125,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
timeout: TimeInterval,
failChallengeIfTimedOut: Bool,
) async -> RegistrationStep {
Logger.info("Attempting to fulfill push challenge with a token we don't have yet")
logger.info("Attempting to fulfill push challenge with a token we don't have yet")
do {
let challengeToken = try await withUncooperativeTimeout(seconds: timeout) {
return await self.deps.pushRegistrationManager.receivePreAuthChallengeToken()
@ -3130,11 +3145,11 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
} catch {
switch error {
case is UncooperativeTimeoutError where failChallengeIfTimedOut:
Logger.warn("No challenge token received in time. Resetting")
logger.warn("No challenge token received in time. Resetting")
db.write { self.resetSession($0) }
return .showErrorSheet(.sessionInvalidated)
default:
Logger.warn("No challenge token received in time, falling back to next challenge")
logger.warn("No challenge token received in time, falling back to next challenge")
return await tryNonImmediatePushChallenge()
}
}
@ -3144,7 +3159,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
func tryNonImmediatePushChallenge() async -> RegistrationStep {
// Our third choice: a captcha challenge
if requestsCaptchaChallenge {
Logger.info("Showing the CAPTCHA challenge to the user")
logger.info("Showing the CAPTCHA challenge to the user")
db.write { transaction in
SupportKeyValueStore().setLastChallengeDate(value: Date(), transaction: transaction)
}
@ -3166,14 +3181,14 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// We're out of luck.
if session.hasUnknownChallengeRequiringAppUpdate {
Logger.warn("An unknown challenge was found")
logger.warn("An unknown challenge was found")
inMemoryState.pendingCodeTransport = nil
db.write { tx in
self.processSession(session, initialCodeRequestState: .failedToRequest, tx)
}
return .appUpdateBanner
} else {
Logger.warn("Couldn't fulfill any challenges. Resetting the session")
logger.warn("Couldn't fulfill any challenges. Resetting the session")
db.write { resetSession($0) }
return await nextStep()
}
@ -3212,14 +3227,15 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
switch fulfillment {
case .captcha:
Logger.info("Submitting CAPTCHA challenge fulfillment")
logger.info("Submitting CAPTCHA challenge fulfillment")
case .pushChallenge:
Logger.info("Submitting push challenge fulfillment")
logger.info("Submitting push challenge fulfillment")
}
let result = await deps.sessionManager.fulfillChallenge(
for: session,
fulfillment: fulfillment,
logger: logger,
)
switch result {
@ -3249,7 +3265,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
return .showErrorSheet(.genericError)
case .disallowed(let session):
Logger.warn("Disallowed to complete a challenge which should be impossible.")
logger.warn("Disallowed to complete a challenge which should be impossible.")
// Don't keep trying to send a code.
inMemoryState.pendingCodeTransport = nil
db.write { self.processSession(session, initialCodeRequestState: .failedToRequest, $0) }
@ -3264,7 +3280,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
return .showErrorSheet(.networkError)
}
case .retryAfterTimeout(let session, retryAfterHeader: _):
Logger.error("Should not have to retry a captcha challenge request")
logger.error("Should not have to retry a captcha challenge request")
// Clear the pending code; we want the user to press again
// once the timeout expires.
inMemoryState.pendingCodeTransport = nil
@ -3281,7 +3297,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
return .showErrorSheet(.networkError)
case .transportError(let session):
Logger.error("Should not get a transport error for a challenge request")
logger.error("Should not get a transport error for a challenge request")
// Clear the pending code; we want the user to press again
// once the timeout expires.
inMemoryState.pendingCodeTransport = nil
@ -3300,7 +3316,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
) async -> RegistrationStep {
let maxAutomaticRetries = Constants.networkErrorRetries
Logger.info("")
logger.info("")
db.write { tx in
self.updatePersistedSessionState(session: session, tx) {
@ -3311,6 +3327,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
let result = await deps.sessionManager.submitVerificationCode(
for: session,
code: code,
logger: logger,
)
switch result {
@ -3386,7 +3403,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
return .showErrorSheet(.networkError)
case .transportError(let session):
Logger.error("Should not get transport error when submitting verification code")
logger.error("Should not get transport error when submitting verification code")
db.write { self.processSession(session, $0) }
return .showErrorSheet(.genericError)
case .genericError:
@ -3404,7 +3421,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
) async -> RegistrationStep {
let maxAutomaticRetries = Constants.networkErrorRetries
Logger.info("")
logger.info("")
let result = await deps.svr.restoreKeys(
pin: pin,
@ -3525,7 +3542,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
if error.isPostRegDeregisteredError {
return await becameDeregisteredBeforeCompleting(accountIdentity: accountIdentity)
}
Logger.error("Failed to create prekeys: \(error)")
logger.error("Failed to create prekeys: \(error)")
// Note this is undismissable; the user will be on whatever
// screen they were on but with the error sheet atop which retries
// via `nextStep()` when tapped.
@ -3778,7 +3795,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
private func showPinEntryIfNeeded(
accountIdentity: AccountIdentity,
) -> RegistrationStep? {
Logger.info("")
logger.info("")
let isRestoringPinBackup: Bool = (
accountIdentity.hasPreviouslyUsedSVR &&
@ -3824,7 +3841,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
return nil
}
Logger.info("")
logger.info("")
guard let pin = inMemoryState.pinFromUser ?? inMemoryState.pinFromDisk else {
return showPinEntryIfNeeded(accountIdentity: accountIdentity)
}
@ -3846,7 +3863,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
accountEntropyPool: SignalServiceKit.AccountEntropyPool,
accountIdentity: AccountIdentity,
) async -> RegistrationStep? {
Logger.info("")
logger.info("")
guard let pin = inMemoryState.pinFromUser ?? inMemoryState.pinFromDisk else {
return showPinEntryIfNeeded(accountIdentity: accountIdentity)
@ -3869,7 +3886,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
return await self.enableReglock(accountIdentity: accountIdentity, reglockToken: reglockToken)
}
} else {
Logger.info("Not enabling reglock because it wasn't enabled to begin with")
logger.info("Not enabling reglock because it wasn't enabled to begin with")
}
}
return nil
@ -3883,7 +3900,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
) async -> RegistrationStep {
let maxAutomaticRetries = Constants.networkErrorRetries
Logger.info("")
logger.info("")
let backupAuthMethod = SVR.AuthMethod.chatServerAuth(accountIdentity.authedAccount)
let authMethod: SVR.AuthMethod
@ -3972,7 +3989,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
) async -> RegistrationStep {
let maxAutomaticRetries = Constants.networkErrorRetries
Logger.info("")
logger.info("")
let authMethod: SVR.AuthMethod
let backupAuthMethod = SVR.AuthMethod.chatServerAuth(accountIdentity.authedAccount)
@ -3992,7 +4009,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
inMemoryState.hasBackedUpToSVR = true
await db.awaitableWrite { tx in
Logger.info("Setting pin code after SVR backup")
logger.info("Setting pin code after SVR backup")
updateMasterKeyAndLocalState(
masterKey: backedUpMasterKey,
tx: tx,
@ -4020,7 +4037,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
return .showErrorSheet(.networkError)
}
Logger.error("Failed to back up to SVR with error: \(error)")
logger.error("Failed to back up to SVR with error: \(error)")
// We want to let people get through registration even if backups
// go wrong. Show an error but let the user continue when they try the next step.
inMemoryState.didSkipSVRBackup = true
@ -4167,13 +4184,14 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
accountIdentity: AccountIdentity,
reglockToken: String,
) async -> RegistrationStep {
Logger.info("Attempting to enable reglock")
logger.info("Attempting to enable reglock")
do {
try await Service.makeEnableReglockRequest(
reglockToken: reglockToken,
auth: accountIdentity.chatServiceAuth,
networkManager: deps.networkManager,
logger: logger,
)
} catch {
// This isn't immediately catastrophic; this user already had reglock
@ -4181,7 +4199,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// preventing others from getting in. We defer updating this until
// later (when we update account attributes).
// This matches legacy registration behavior.
Logger.error("Unable to set reglock, so old reglock password will remain enforced.")
logger.error("Unable to set reglock, so old reglock password will remain enforced.")
}
self.inMemoryState.hasSetReglock = true
@ -4193,7 +4211,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
private func scheduleReuploadProfileStateAsync(accountIdentity: AccountIdentity) {
Logger.debug("restored local profile name. Uploading...")
logger.debug("restored local profile name. Uploading...")
// if we don't have a `localGivenName`, there's nothing to upload, and trying
// to upload would fail.
@ -4204,7 +4222,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
private func loadProfileState() {
Logger.info("")
logger.info("")
db.read { tx in
let localProfile = deps.profileManager.localUserProfile(tx: tx)
@ -4222,7 +4240,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
private func updateAccountAttributes(_ accountIdentity: AccountIdentity) async -> Error? {
Logger.info("")
logger.info("")
do {
try await Service.makeUpdateAccountAttributesRequest(
makeAccountAttributes(
@ -4231,6 +4249,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
),
auth: accountIdentity.chatServiceAuth,
networkManager: deps.networkManager,
logger: logger,
)
return nil
} catch {
@ -4239,7 +4258,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
private func updatePhoneNumberDiscoverability(accountIdentity: AccountIdentity, phoneNumberDiscoverability: PhoneNumberDiscoverability) {
Logger.info("")
logger.info("")
self.inMemoryState.phoneNumberDiscoverability = phoneNumberDiscoverability
@ -4265,7 +4284,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
pniState: Mode.ChangeNumberState.PendingPniState,
accountIdentity: AccountIdentity,
) async -> FinalizeChangeNumberResult {
Logger.info("")
logger.info("")
do {
try await self.db.awaitableWrite { tx in
@ -4282,7 +4301,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
transaction: tx,
))
Logger.info(
logger.info(
"""
Recording new phone number
localAci: \(changeNumberState.localAci),
@ -4306,7 +4325,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
return .success
} catch {
Logger.error("Failed to finalize change number state: \(error)")
logger.error("Failed to finalize change number state: \(error)")
return .genericError
}
}
@ -4340,7 +4359,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
reglockToken: String?,
responseHandler: @escaping @MainActor (AccountResponse) async -> RegistrationStep,
) async -> RegistrationStep {
Logger.info("")
logger.info("")
switch mode {
case .reRegistering(let state):
@ -4380,11 +4399,11 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
isManualMessageFetchEnabled = false
apnRegistrationId = tokens
case .pushUnsupported:
Logger.info("Push unsupported; enabling manual message fetch.")
logger.info("Push unsupported; enabling manual message fetch.")
isManualMessageFetchEnabled = true
apnRegistrationId = nil
case .timeout:
Logger.error("Timed out waiting for apns token")
logger.error("Timed out waiting for apns token")
return .showErrorSheet(.genericError)
case .genericError:
return .showErrorSheet(.genericError)
@ -4458,7 +4477,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
// We don't know what went wrong, so PNI state
// may be set server side. Don't wipe PNI state
// so we try and recover.
Logger.error("Unknown error when changing number; preserving pni state")
logger.error("Unknown error when changing number; preserving pni state")
}
return await responseHandler(accountResponse)
}
@ -4536,6 +4555,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
apnRegistrationId: apnRegistrationId,
prekeyBundles: prekeyBundles,
signalService: signalService,
logger: logger,
)
let isPrekeyUploadSuccess = switch accountResponse {
case .success: true
@ -4565,7 +4585,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
reglockToken: String?,
changeNumberState: RegistrationCoordinatorLoaderImpl.Mode.ChangeNumberState,
) async -> ChangeNumberResult {
Logger.info("")
logger.info("")
let pniResult = await deps.changeNumberPniManager.generatePniIdentity(
forNewE164: e164,
@ -4597,7 +4617,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
pniPendingState: ChangePhoneNumberPni.PendingState,
pniParams: PniDistribution.Parameters,
) async -> ChangeNumberResult {
Logger.info("")
logger.info("")
// Process all messages first. The caller doesn't invoke this method when
// "pniState" is set, and message processing is only suspended when
@ -4623,6 +4643,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
authPassword: changeNumberState.oldAuthToken,
pniChangeNumberParameters: pniParams,
networkManager: deps.networkManager,
logger: logger,
))
}
@ -4631,7 +4652,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
changeNumberState: Mode.ChangeNumberState,
pniState: Mode.ChangeNumberState.PendingPniState,
) async -> RegistrationStep {
Logger.info("")
logger.info("")
let whoAmIResult = await Service.makeWhoAmIRequest(
auth: ChatServiceAuth.explicit(
@ -4698,7 +4719,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
private func becameDeregisteredBeforeCompleting(
accountIdentity: AccountIdentity,
) async -> RegistrationStep {
Logger.info("")
logger.info("")
switch mode {
case .registering, .reRegistering:
@ -4713,7 +4734,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
}
}
Logger.warn("Got deregistered while completing registration; starting over with re-registration.")
logger.warn("Got deregistered while completing registration; starting over with re-registration.")
db.write { tx in
wipePersistedState(tx)
}

View File

@ -19,7 +19,11 @@ public protocol RegistrationCoordinatorLoader {
/// `desiredMode` may not be the mode we end up in; for example if we
/// were in the middle of re-registration and try to change number, that will
/// be disallowed and we will fall back to re-registration.
func coordinator(forDesiredMode: RegistrationMode, transaction: DBWriteTransaction) -> RegistrationCoordinator
func coordinator(
forDesiredMode: RegistrationMode,
transaction: DBWriteTransaction,
logger: PrefixedLogger,
) -> RegistrationCoordinator
/// If true, message processing should be paused due to an in-progress change number.
func hasPendingChangeNumber(transaction: DBReadTransaction) -> Bool
@ -104,6 +108,7 @@ public class RegistrationCoordinatorLoaderImpl: RegistrationCoordinatorLoader {
public func coordinator(
forDesiredMode desiredMode: RegistrationMode,
transaction: DBWriteTransaction,
logger: PrefixedLogger,
) -> RegistrationCoordinator {
let mode = loadMode(transaction: transaction) ?? desiredMode.asInternalMode()
do {
@ -118,7 +123,7 @@ public class RegistrationCoordinatorLoaderImpl: RegistrationCoordinatorLoader {
}
let delegate = CoordinatorDelegate(loader: self)
Logger.info("Starting registration, mode: \(mode.logString)")
return RegistrationCoordinatorImpl(mode: mode, loader: delegate, dependencies: deps)
return RegistrationCoordinatorImpl(mode: mode, loader: delegate, dependencies: deps, logger: logger)
}
public func hasPendingChangeNumber(transaction: DBReadTransaction) -> Bool {

View File

@ -92,7 +92,8 @@ public class RegistrationUtils {
}
private class func showReRegistration(e164: E164, aci: Aci, appReadiness: AppReadinessSetter) {
Logger.info("Attempting to start re-registration")
let logger = PrefixedLogger(prefix: "[ReReg]")
logger.info("Attempting to start re-registration")
let dependencies = RegistrationCoordinatorDependencies.from(NSObject())
let desiredMode = RegistrationMode.reRegistering(.init(e164: e164, aci: aci))
let loader = RegistrationCoordinatorLoaderImpl(dependencies: dependencies)
@ -100,6 +101,7 @@ public class RegistrationUtils {
return loader.coordinator(
forDesiredMode: desiredMode,
transaction: $0,
logger: logger,
)
}
let navController = RegistrationNavigationController.withCoordinator(coordinator, appReadiness: appReadiness)

View File

@ -10,6 +10,7 @@ public class RegistrationNavigationController: OWSNavigationController {
private let appReadiness: AppReadinessSetter
private let coordinator: RegistrationCoordinator
private var logger: PrefixedLogger { coordinator.logger }
public static func withCoordinator(
_ coordinator: RegistrationCoordinator,
@ -37,7 +38,7 @@ public class RegistrationNavigationController: OWSNavigationController {
super.viewWillAppear(animated)
if viewControllers.isEmpty, !isLoading {
Logger.info("Performing initial load")
logger.info("Performing initial load")
pushNextController(Guarantee.wrapAsync { await self.coordinator.nextStep() })
}
@ -57,12 +58,12 @@ public class RegistrationNavigationController: OWSNavigationController {
loadingMode: RegistrationLoadingViewController.RegistrationLoadingMode? = .generic,
) {
guard !isLoading else {
owsFailDebug("Parallel loads not allowed")
owsFailDebug("Parallel loads not allowed", logger: logger)
return
}
if let loadingMode, step.isSealed.negated {
Logger.info("Pushing loading controller")
logger.info("Pushing loading controller")
isLoading = true
switch loadingMode {
@ -82,7 +83,7 @@ public class RegistrationNavigationController: OWSNavigationController {
}
}
} else {
Logger.info("Skipping loading controller for \(String(describing: try? step.result?.get().logSafeString))")
logger.info("Skipping loading controller for \(String(describing: try? step.result?.get().logSafeString))")
_pushNextController(step)
}
}
@ -93,15 +94,15 @@ public class RegistrationNavigationController: OWSNavigationController {
let step = await step.awaitable()
if let progressModal = self.presentedViewController as? BackupRestoreProgressModal {
Logger.info("Dismissing progress view")
logger.info("Dismissing progress view")
await progressModal.completeAndDismiss()
}
Logger.info("Pushing registration step: \(step.logSafeString)")
logger.info("Pushing registration step: \(step.logSafeString)")
self.isLoading = false
guard let controller = self.controller(for: step) else {
Logger.info("No controller for \(step.logSafeString)")
logger.info("No controller for \(step.logSafeString)")
return
}
var controllerToPush: UIViewController?
@ -109,10 +110,10 @@ public class RegistrationNavigationController: OWSNavigationController {
// If we already have this controller available, update it and pop to it.
if type(of: viewController) == controller.viewType {
if let newController = controller.updateViewController(viewController) {
Logger.info("Pushing new version of existing controller for \(step.logSafeString)")
logger.info("Pushing new version of existing controller for \(step.logSafeString)")
controllerToPush = newController
} else {
Logger.info("Popping to existing controller for \(step.logSafeString)")
logger.info("Popping to existing controller for \(step.logSafeString)")
let animatePop = !(self.topViewController is RegistrationLoadingViewController)
self.popToViewController(viewController, animated: animatePop)
return
@ -128,14 +129,14 @@ public class RegistrationNavigationController: OWSNavigationController {
!self.viewControllers.contains(where: { $0 is RegistrationSplashViewController })
{
// Cancellable controllers need to have a splash view behind
Logger.info("Pushing splash view and controller for \(step.logSafeString)")
logger.info("Pushing splash view and controller for \(step.logSafeString)")
let splashController = self.registrationSplashController()
let newViewControllers = [splashController.makeViewController(self), vc]
self.setViewControllers(self.viewControllers + newViewControllers, animated: true)
return
}
Logger.info("Pushing controller for \(step.logSafeString)")
logger.info("Pushing controller for \(step.logSafeString)")
self.pushViewController(vc, animated: true)
}
}
@ -450,7 +451,7 @@ public class RegistrationNavigationController: OWSNavigationController {
present(UIAlertController.registrationAppUpdateBanner(), animated: true)
return nil
case .done:
Logger.info("Finished with registration!")
logger.info("Finished with registration!")
SignalApp.shared.showConversationSplitView(appReadiness: appReadiness)
return nil
}
@ -512,7 +513,7 @@ extension RegistrationNavigationController: RegistrationSplashPresenter {
}
public func switchToDeviceLinkingMode() {
Logger.info("Pushing device linking")
logger.info("Pushing device linking")
let controller = RegistrationConfirmModeSwitchViewController(presenter: self)
pushViewController(controller, animated: true)
}
@ -550,7 +551,7 @@ extension RegistrationNavigationController: RegistrationPhoneNumberPresenter {
owsFailBeta("Unable to exit registration")
return
}
Logger.info("Early exiting registration")
logger.info("Early exiting registration")
SignalApp.shared.showConversationSplitView(appReadiness: appReadiness)
}
}
@ -666,10 +667,10 @@ extension RegistrationNavigationController: RegistrationReglockTimeoutPresenter
func acknowledgeReglockTimeout() {
switch coordinator.acknowledgeReglockTimeout() {
case .cannotExit:
Logger.warn("Tried to exit registration from reglock timeout when unable.")
logger.warn("Tried to exit registration from reglock timeout when unable.")
return
case .exitRegistration:
Logger.info("Exiting registration after reglock timeout")
logger.info("Exiting registration after reglock timeout")
SignalApp.shared.showConversationSplitView(appReadiness: appReadiness)
case .restartRegistration(let nextStepGuarantee):
pushNextController(nextStepGuarantee)

View File

@ -303,7 +303,8 @@ class AccountSettingsViewController: OWSTableViewController2 {
}
private func changePhoneNumber(_ params: RegistrationMode.ChangeNumberParams) {
Logger.info("Attempting to start change number from settings")
let logger = PrefixedLogger(prefix: "[ChangeNum]")
logger.info("Attempting to start change number from settings")
let dependencies = RegistrationCoordinatorDependencies.from(NSObject())
let desiredMode = RegistrationMode.changingNumber(params)
let loader = RegistrationCoordinatorLoaderImpl(dependencies: dependencies)
@ -311,6 +312,7 @@ class AccountSettingsViewController: OWSTableViewController2 {
return loader.coordinator(
forDesiredMode: desiredMode,
transaction: $0,
logger: logger,
)
}
let navController = RegistrationNavigationController.withCoordinator(coordinator, appReadiness: appReadiness)
@ -394,7 +396,7 @@ class AccountSettingsViewController: OWSTableViewController2 {
Task {
do {
try await ModalActivityIndicatorViewController.presentAndPropagateResult(from: self) {
try await SSKEnvironment.shared.ows2FAManagerRef.enableRegistrationLockV2()
try await SSKEnvironment.shared.ows2FAManagerRef.enableRegistrationLockV2(logger: PrefixedLogger(prefix: "[Settings]"))
}
} catch where error.isNetworkFailureOrTimeout {
owsFailDebug("Network error enabling reglock.")

View File

@ -223,6 +223,7 @@ public class RegistrationCoordinatorTest {
return registrationCoordinatorLoader.coordinator(
forDesiredMode: testCase.mode,
transaction: $0,
logger: .empty(),
) as! RegistrationCoordinatorImpl
}
}
@ -394,7 +395,10 @@ public class RegistrationCoordinatorTest {
if wasReglockEnabled {
// If we had reglock before registration, it should be re-enabled.
let expectedReglockRequest = OWSRequestFactory.enableRegistrationLockV2Request(token: finalMasterKey.reglockToken)
let expectedReglockRequest = OWSRequestFactory.enableRegistrationLockV2Request(
token: finalMasterKey.reglockToken,
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedReglockRequest.url {
#expect(finalMasterKey.reglockToken == request.parameters["registrationLock"] as! String)
@ -446,6 +450,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(finalMasterKey),
auth: .implicit(), // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -575,6 +580,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(finalMasterKey),
auth: .implicit(), // // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -962,6 +968,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(finalMasterKey),
auth: .implicit(), // // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -1182,6 +1189,7 @@ public class RegistrationCoordinatorTest {
let expectedSVR2CheckRequest = RegistrationRequestFactory.svr2AuthCredentialCheckRequest(
e164: Stubs.e164,
credentials: svr2CredentialCandidates,
logger: .empty(),
)
mockURLSession.addResponse(TSRequestOWSURLSessionMock.Response(
urlSuffix: expectedSVR2CheckRequest.url.absoluteString,
@ -1270,7 +1278,10 @@ public class RegistrationCoordinatorTest {
})
// If we had reglock before registration, it should be re-enabled.
let expectedReglockRequest = OWSRequestFactory.enableRegistrationLockV2Request(token: finalMasterKey.reglockToken)
let expectedReglockRequest = OWSRequestFactory.enableRegistrationLockV2Request(
token: finalMasterKey.reglockToken,
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedReglockRequest.url {
#expect(finalMasterKey.reglockToken == request.parameters["registrationLock"] as! String)
@ -1324,6 +1335,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(finalMasterKey),
auth: .implicit(), // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -1393,6 +1405,7 @@ public class RegistrationCoordinatorTest {
let expectedSVR2CheckRequest = RegistrationRequestFactory.svr2AuthCredentialCheckRequest(
e164: Stubs.e164,
credentials: svr2CredentialCandidates,
logger: .empty(),
)
mockURLSession.addResponse(TSRequestOWSURLSessionMock.Response(
urlSuffix: expectedSVR2CheckRequest.url.absoluteString,
@ -1647,6 +1660,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(finalMasterKey),
auth: .implicit(), // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -1779,6 +1793,7 @@ public class RegistrationCoordinatorTest {
var expectedSVRCheckRequest = RegistrationRequestFactory.svr2AuthCredentialCheckRequest(
e164: originalE164,
credentials: credentialCandidates,
logger: .empty(),
)
mockURLSession.addResponse(
TSRequestOWSURLSessionMock.Response(
@ -1810,6 +1825,7 @@ public class RegistrationCoordinatorTest {
expectedSVRCheckRequest = RegistrationRequestFactory.svr2AuthCredentialCheckRequest(
e164: changedE164,
credentials: credentialCandidates,
logger: .empty(),
)
mockURLSession.addResponse(
TSRequestOWSURLSessionMock.Response(
@ -1941,6 +1957,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(newMasterKey),
auth: .implicit(), // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -2950,6 +2967,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(newMasterKey),
auth: .implicit(), // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -3090,6 +3108,7 @@ public class RegistrationCoordinatorTest {
let expectedAttributesRequest = RegistrationRequestFactory.updatePrimaryDeviceAccountAttributesRequest(
Stubs.accountAttributes(newMasterKey),
auth: .implicit(), // doesn't matter for url matching
logger: .empty(),
)
networkManagerMock.asyncRequestHandlers.append({ request, _ in
if request.url == expectedAttributesRequest.url {
@ -3192,6 +3211,7 @@ public class RegistrationCoordinatorTest {
skipDeviceTransfer: true,
apnRegistrationId: Stubs.apnsRegistrationId,
prekeyBundles: Stubs.prekeyBundles(),
logger: .empty(),
)
}
@ -3206,6 +3226,7 @@ public class RegistrationCoordinatorTest {
skipDeviceTransfer: true,
apnRegistrationId: Stubs.apnsRegistrationId,
prekeyBundles: Stubs.prekeyBundles(),
logger: .empty(),
)
}
@ -3375,6 +3396,7 @@ public class RegistrationCoordinatorTest {
let expectedSVR2CheckRequest = RegistrationRequestFactory.svr2AuthCredentialCheckRequest(
e164: Stubs.e164,
credentials: svr2CredentialCandidates,
logger: .empty(),
)
mockURLSession.addResponse(TSRequestOWSURLSessionMock.Response(
urlSuffix: expectedSVR2CheckRequest.url.absoluteString,

View File

@ -15,7 +15,7 @@ public class RegistrationSessionManagerMock: RegistrationSessionManager {
public var sessionToRestore: RegistrationSession?
public func restoreSession() -> RegistrationSession? {
public func restoreSession(logger: PrefixedLogger) -> RegistrationSession? {
return sessionToRestore
}
@ -30,7 +30,7 @@ public class RegistrationSessionManagerMock: RegistrationSessionManager {
beginSessionResponseMocks.append(mock)
}
public func beginOrRestoreSession(e164: E164, apnsToken: String?) async -> Registration.BeginSessionResponse {
public func beginOrRestoreSession(e164: E164, apnsToken: String?, logger: PrefixedLogger) async -> Registration.BeginSessionResponse {
// TODO: Append step to known steps
return beginSessionResponseMocks.removeFirst()
}
@ -46,6 +46,7 @@ public class RegistrationSessionManagerMock: RegistrationSessionManager {
public func fulfillChallenge(
for session: RegistrationSession,
fulfillment: Registration.ChallengeFulfillment,
logger: PrefixedLogger,
) async -> Registration.UpdateSessionResponse {
latestChallengeFulfillment = fulfillment
return fulfillChallengeResponseMocks.removeFirst()
@ -62,6 +63,7 @@ public class RegistrationSessionManagerMock: RegistrationSessionManager {
public func requestVerificationCode(
for session: RegistrationSession,
transport: Registration.CodeTransport,
logger: PrefixedLogger,
) async -> Registration.UpdateSessionResponse {
didRequestCode = true
// TODO: Append step to known steps
@ -78,6 +80,7 @@ public class RegistrationSessionManagerMock: RegistrationSessionManager {
public func submitVerificationCode(
for session: RegistrationSession,
code: String,
logger: PrefixedLogger,
) async -> Registration.UpdateSessionResponse {
return submitCodeResponseMocks.removeFirst()
}

View File

@ -172,7 +172,7 @@ public enum OWSRequestFactory {
// MARK: - Registration
public static func enableRegistrationLockV2Request(token: String) -> TSRequest {
public static func enableRegistrationLockV2Request(token: String, logger: PrefixedLogger) -> TSRequest {
owsAssertDebug(nil != token.nilIfEmpty)
let url = URL(string: textSecureRegistrationLockV2API)!
@ -182,6 +182,7 @@ public enum OWSRequestFactory {
parameters: [
"registrationLock": token,
],
logger: logger,
)
}

View File

@ -15,6 +15,7 @@ public enum RegistrationRequestFactory {
pushToken: String?,
mcc: String?,
mnc: String?,
logger: PrefixedLogger,
) -> TSRequest {
let urlPathComponents = URLPathComponents(
["v1", "verification", "session"],
@ -38,7 +39,7 @@ public enum RegistrationRequestFactory {
parameters["mnc"] = mnc
}
var result = TSRequest(url: url, method: "POST", parameters: parameters)
var result = TSRequest(url: url, method: "POST", parameters: parameters, logger: logger)
result.auth = .registration(nil)
return result
}
@ -46,6 +47,7 @@ public enum RegistrationRequestFactory {
/// See `RegistrationServiceResponses.FetchSessionResponseCodes` for possible responses.
public static func fetchSessionRequest(
sessionId: String,
logger: PrefixedLogger,
) -> TSRequest {
owsAssertDebug(sessionId.isEmpty.negated)
@ -56,7 +58,7 @@ public enum RegistrationRequestFactory {
urlComponents.percentEncodedPath = urlPathComponents.percentEncoded
let url = urlComponents.url!
var result = TSRequest(url: url, method: "GET", parameters: nil)
var result = TSRequest(url: url, method: "GET", parameters: nil, logger: logger)
result.auth = .registration(nil)
redactSessionIdFromLogs(sessionId, in: &result)
return result
@ -69,6 +71,7 @@ public enum RegistrationRequestFactory {
sessionId: String,
captchaToken: String?,
pushChallengeToken: String?,
logger: PrefixedLogger,
) -> TSRequest {
owsAssertDebug(sessionId.isEmpty.negated)
owsAssertDebug(!captchaToken.isEmptyOrNil || !pushChallengeToken.isEmptyOrNil)
@ -88,7 +91,7 @@ public enum RegistrationRequestFactory {
parameters["pushChallenge"] = pushChallengeToken
}
var result = TSRequest(url: url, method: "PATCH", parameters: parameters)
var result = TSRequest(url: url, method: "PATCH", parameters: parameters, logger: logger)
result.auth = .registration(nil)
redactSessionIdFromLogs(sessionId, in: &result)
return result
@ -109,6 +112,7 @@ public enum RegistrationRequestFactory {
languageCode: String?,
countryCode: String?,
transport: VerificationCodeTransport,
logger: PrefixedLogger,
) -> TSRequest {
owsAssertDebug(sessionId.isEmpty.negated)
@ -137,7 +141,7 @@ public enum RegistrationRequestFactory {
let languageHeader: String = HttpHeaders.formatAcceptLanguageHeader(languageCodes)
var result = TSRequest(url: url, method: "POST", parameters: parameters)
var result = TSRequest(url: url, method: "POST", parameters: parameters, logger: logger)
result.auth = .registration(nil)
result.headers[HttpHeaders.acceptLanguageHeaderKey] = languageHeader
redactSessionIdFromLogs(sessionId, in: &result)
@ -148,6 +152,7 @@ public enum RegistrationRequestFactory {
public static func submitVerificationCodeRequest(
sessionId: String,
code: String,
logger: PrefixedLogger,
) -> TSRequest {
owsAssertDebug(sessionId.isEmpty.negated)
owsAssertDebug(code.isEmpty.negated)
@ -163,7 +168,7 @@ public enum RegistrationRequestFactory {
"code": code,
]
var result = TSRequest(url: url, method: "PUT", parameters: parameters)
var result = TSRequest(url: url, method: "PUT", parameters: parameters, logger: logger)
result.auth = .registration(nil)
redactSessionIdFromLogs(sessionId, in: &result)
return result
@ -174,6 +179,7 @@ public enum RegistrationRequestFactory {
public static func svr2AuthCredentialCheckRequest(
e164: E164,
credentials: [SVR2AuthCredential],
logger: PrefixedLogger,
) -> TSRequest {
owsAssertDebug(!credentials.isEmpty)
@ -191,7 +197,7 @@ public enum RegistrationRequestFactory {
},
]
var result = TSRequest(url: url, method: "POST", parameters: parameters)
var result = TSRequest(url: url, method: "POST", parameters: parameters, logger: logger)
result.auth = .registration(nil)
return result
}
@ -240,6 +246,7 @@ public enum RegistrationRequestFactory {
skipDeviceTransfer: Bool,
apnRegistrationId: ApnRegistrationId?,
prekeyBundles: RegistrationPreKeyUploadBundles,
logger: PrefixedLogger,
) -> TSRequest {
owsAssertDebug((apnRegistrationId != nil) != accountAttributes.isManualMessageFetchEnabled)
@ -278,7 +285,7 @@ public enum RegistrationRequestFactory {
parameters["apnToken"] = apnRegistrationIdDict
}
var result = TSRequest(url: url, method: "POST", parameters: parameters)
var result = TSRequest(url: url, method: "POST", parameters: parameters, logger: logger)
// As odd as this is, it is to spec.
result.auth = .registration((username: e164.stringValue, password: authPassword))
result.headers["X-Signal-Agent"] = "OWI"
@ -323,16 +330,17 @@ public enum RegistrationRequestFactory {
parameters.merge(
pniChangeNumberParameters.requestParameters(),
uniquingKeysWith: { _, _ in
owsFail("Unexpectedly encountered duplicate keys!")
owsFail("Unexpectedly encountered duplicate keys!", logger: logger)
},
)
return TSRequest(url: url, method: "PUT", parameters: parameters)
return TSRequest(url: url, method: "PUT", parameters: parameters, logger: logger)
}
public static func updatePrimaryDeviceAccountAttributesRequest(
_ accountAttributes: AccountAttributes,
auth: ChatServiceAuth,
logger: PrefixedLogger,
) -> TSRequest {
let urlPathComponents = URLPathComponents(
["v1", "accounts", "attributes"],
@ -346,7 +354,7 @@ public enum RegistrationRequestFactory {
let data = try! JSONEncoder().encode(accountAttributes)
let parameters = try! JSONSerialization.jsonObject(with: data, options: .fragmentsAllowed) as! [String: Any]
var result = TSRequest(url: url, method: "PUT", parameters: parameters)
var result = TSRequest(url: url, method: "PUT", parameters: parameters, logger: logger)
result.headers["X-Signal-Agent"] = "OWI"
result.auth = .identified(auth)
return result

View File

@ -9,23 +9,23 @@ public protocol RegistrationSessionManager {
/// Restore any existing registration session that has not been completed and validate it with the server.
/// If there is no session, or if the session is invalid, returns nil.
func restoreSession() async -> RegistrationSession?
func restoreSession(logger: PrefixedLogger) async -> RegistrationSession?
/// Begins a new session, first attempting to restore any existing valid session for the same number.
/// See `Registration.BeginSessionResponse` for possible responses, including errors.
func beginOrRestoreSession(e164: E164, apnsToken: String?) async -> Registration.BeginSessionResponse
func beginOrRestoreSession(e164: E164, apnsToken: String?, logger: PrefixedLogger) async -> Registration.BeginSessionResponse
/// Fulfill a challenge for the session (e.g. a captcha).
/// See `Registration.UpdateSessionResponse` for possible responses, including errors.
func fulfillChallenge(for session: RegistrationSession, fulfillment: Registration.ChallengeFulfillment) async -> Registration.UpdateSessionResponse
func fulfillChallenge(for session: RegistrationSession, fulfillment: Registration.ChallengeFulfillment, logger: PrefixedLogger) async -> Registration.UpdateSessionResponse
/// Request a verification code be sent to the session's phone number, for some transport.
/// See `Registration.UpdateSessionResponse` for possible responses, including errors.
func requestVerificationCode(for session: RegistrationSession, transport: Registration.CodeTransport) async -> Registration.UpdateSessionResponse
func requestVerificationCode(for session: RegistrationSession, transport: Registration.CodeTransport, logger: PrefixedLogger) async -> Registration.UpdateSessionResponse
/// Submit a verification code that was previously requested.
/// See `Registration.UpdateSessionResponse` for possible responses, including errors.
func submitVerificationCode(for session: RegistrationSession, code: String) async -> Registration.UpdateSessionResponse
func submitVerificationCode(for session: RegistrationSession, code: String, logger: PrefixedLogger) async -> Registration.UpdateSessionResponse
/// Completes a session, wiping it from future restoration.
/// Typically called once the session is verified and is used to complete registration.

View File

@ -26,14 +26,14 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
// TODO: make this and other methods resilient to transient network failures by adding
// basic retrying logic.
public func restoreSession() async -> RegistrationSession? {
public func restoreSession(logger: PrefixedLogger) async -> RegistrationSession? {
// Just get the most recent one, don't validate against any e164.
return await restoreSession(forE164: nil)
return await restoreSession(forE164: nil, logger: logger)
}
public func beginOrRestoreSession(e164: E164, apnsToken: String?) async -> Registration.BeginSessionResponse {
public func beginOrRestoreSession(e164: E164, apnsToken: String?, logger: PrefixedLogger) async -> Registration.BeginSessionResponse {
// Verify the session is still valid.
let restoredSession = await restoreSession(forE164: e164)
let restoredSession = await restoreSession(forE164: e164, logger: logger)
guard let restoredSession, restoredSession.e164 == e164 else {
// We only keep one session at a time, wipe any if we change the e164.
await db.awaitableWrite { self.clearPersistedSession($0) }
@ -45,6 +45,7 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
apnsToken: apnsToken,
mcc: mcc,
mnc: mnc,
logger: logger,
)
return await persistSessionFromResponse(response)
}
@ -54,18 +55,19 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
public func fulfillChallenge(
for session: RegistrationSession,
fulfillment: Registration.ChallengeFulfillment,
logger: PrefixedLogger,
) async -> Registration.UpdateSessionResponse {
let response = await makeFulfillChallengeRequest(session, fulfillment)
let response = await makeFulfillChallengeRequest(session, fulfillment, logger: logger)
return await persistSessionFromResponse(response)
}
public func requestVerificationCode(for session: RegistrationSession, transport: Registration.CodeTransport) async -> Registration.UpdateSessionResponse {
let response = await makeRequestVerificationCodeRequest(session, transport)
public func requestVerificationCode(for session: RegistrationSession, transport: Registration.CodeTransport, logger: PrefixedLogger) async -> Registration.UpdateSessionResponse {
let response = await makeRequestVerificationCodeRequest(session, transport, logger: logger)
return await persistSessionFromResponse(response)
}
public func submitVerificationCode(for session: RegistrationSession, code: String) async -> Registration.UpdateSessionResponse {
let response = await makeSubmitVerificationCodeRequest(session, code: code)
public func submitVerificationCode(for session: RegistrationSession, code: String, logger: PrefixedLogger) async -> Registration.UpdateSessionResponse {
let response = await makeSubmitVerificationCodeRequest(session, code: code, logger: logger)
return await persistSessionFromResponse(response)
}
@ -157,7 +159,7 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
// TODO: make this and other methods resilient to transient network failures by adding
// basic retrying logic.
private func restoreSession(forE164 e164: E164?) async -> RegistrationSession? {
private func restoreSession(forE164 e164: E164?, logger: PrefixedLogger) async -> RegistrationSession? {
guard let existingSession = db.read(block: { self.getPersistedSession($0) }) else {
return nil
}
@ -167,7 +169,7 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
return nil
}
// Verify the session is still valid.
let fetchSessionResponse = await makeFetchSessionRequest(existingSession)
let fetchSessionResponse = await makeFetchSessionRequest(existingSession, logger: logger)
_ = await self.persistSessionFromResponse(fetchSessionResponse)
switch fetchSessionResponse {
case .success(let session):
@ -184,12 +186,14 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
apnsToken: String?,
mcc: String?,
mnc: String?,
logger: PrefixedLogger,
) async -> Registration.BeginSessionResponse {
let request = RegistrationRequestFactory.beginSessionRequest(
e164: e164,
pushToken: apnsToken,
mcc: mcc,
mnc: mnc,
logger: logger,
)
return await makeRequest(
request,
@ -227,6 +231,7 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
private func makeFulfillChallengeRequest(
_ session: RegistrationSession,
_ fulfillment: Registration.ChallengeFulfillment,
logger: PrefixedLogger,
) async -> Registration.UpdateSessionResponse {
let captchaToken: String?
let pushChallengeToken: String?
@ -242,6 +247,7 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
sessionId: session.id,
captchaToken: captchaToken,
pushChallengeToken: pushChallengeToken,
logger: logger,
)
return await makeUpdateRequest(
request,
@ -284,6 +290,7 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
private func makeRequestVerificationCodeRequest(
_ session: RegistrationSession,
_ transport: Registration.CodeTransport,
logger: PrefixedLogger,
) async -> Registration.UpdateSessionResponse {
let wireTransport: RegistrationRequestFactory.VerificationCodeTransport
switch transport {
@ -312,6 +319,7 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
languageCode: languageCode,
countryCode: countryCode,
transport: wireTransport,
logger: logger,
)
return await makeUpdateRequest(
request,
@ -363,10 +371,12 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
private func makeSubmitVerificationCodeRequest(
_ session: RegistrationSession,
code: String,
logger: PrefixedLogger,
) async -> Registration.UpdateSessionResponse {
let request = RegistrationRequestFactory.submitVerificationCodeRequest(
sessionId: session.id,
code: code,
logger: logger,
)
return await makeUpdateRequest(
request,
@ -448,8 +458,9 @@ public class RegistrationSessionManagerImpl: RegistrationSessionManager {
private func makeFetchSessionRequest(
_ session: RegistrationSession,
logger: PrefixedLogger,
) async -> FetchSessionResponse {
let request = RegistrationRequestFactory.fetchSessionRequest(sessionId: session.id)
let request = RegistrationRequestFactory.fetchSessionRequest(sessionId: session.id, logger: logger)
do {
let response = try await signalService.urlSessionForMainSignalService().performRequest(request)
return handleFetchSessionResponse(

View File

@ -248,7 +248,7 @@ public class OWS2FAManager {
// MARK: -
public func enableRegistrationLockV2() async throws {
public func enableRegistrationLockV2(logger: PrefixedLogger) async throws {
let token = db.read { tx in
let masterKey = accountKeyStore.getMasterKey(tx: tx)
return masterKey?.data(
@ -259,7 +259,7 @@ public class OWS2FAManager {
throw OWSAssertionError("Cannot enable registration lock without an existing PIN")
}
let request = OWSRequestFactory.enableRegistrationLockV2Request(token: token)
let request = OWSRequestFactory.enableRegistrationLockV2Request(token: token, logger: logger)
_ = try await networkManager.asyncRequest(request)
await db.awaitableWrite { transaction in

View File

@ -25,6 +25,7 @@ public class RegistrationRequestFactoryTest: XCTestCase {
languageCode: languageCode,
countryCode: countryCode,
transport: .sms,
logger: .empty(),
)
XCTAssertEqual(request.url.relativeString, "v1/verification/session/123/code")
XCTAssertEqual(request.parameters["transport"] as? String, "sms")

View File

@ -44,6 +44,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let expectedRequest = RegistrationRequestFactory.submitVerificationCodeRequest(
sessionId: oldSession.id,
code: code,
logger: .empty(),
)
// A standard response
@ -69,6 +70,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.requestVerificationCode(
for: oldSession,
transport: [Registration.CodeTransport.sms, .voice].randomElement()!,
logger: .empty(),
)
XCTAssertEqual(result, .success(RegistrationSession(
@ -105,6 +107,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.requestVerificationCode(
for: oldSession,
transport: [Registration.CodeTransport.sms, .voice].randomElement()!,
logger: .empty(),
)
XCTAssertEqual(result, .success(RegistrationSession(
@ -144,6 +147,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.requestVerificationCode(
for: oldSession,
transport: [Registration.CodeTransport.sms, .voice].randomElement()!,
logger: .empty(),
)
XCTAssertEqual(result, .success(RegistrationSession(
@ -170,6 +174,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
pushToken: apnsToken,
mcc: nil,
mnc: nil,
logger: .empty(),
)
// Without any setup, we should try and begin a new session.
@ -185,6 +190,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.beginOrRestoreSession(
e164: e164,
apnsToken: apnsToken,
logger: .empty(),
)
XCTAssertEqual(result, .success(responseSession))
}
@ -201,7 +207,10 @@ public class RegistrationSessionManagerTest: XCTestCase {
// Now we should get back the same session if we try again, with a request
// only to check its validity.
var fetchSessionRequest = RegistrationRequestFactory.fetchSessionRequest(sessionId: responseSession.id)
var fetchSessionRequest = RegistrationRequestFactory.fetchSessionRequest(
sessionId: responseSession.id,
logger: .empty(),
)
// Make a new instance, which shuffles the id
responseBody = stubWireSession()
@ -215,6 +224,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.beginOrRestoreSession(
e164: e164,
apnsToken: apnsToken,
logger: .empty(),
)
XCTAssertEqual(result, .success(responseSession))
}
@ -231,7 +241,10 @@ public class RegistrationSessionManagerTest: XCTestCase {
// If we have the service respond that the session is invalid, we should get a fresh
// session.
fetchSessionRequest = RegistrationRequestFactory.fetchSessionRequest(sessionId: responseSession.id)
fetchSessionRequest = RegistrationRequestFactory.fetchSessionRequest(
sessionId: responseSession.id,
logger: .empty(),
)
// Make a new instance, which shuffles the id
responseBody = stubWireSession()
@ -249,6 +262,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.beginOrRestoreSession(
e164: e164,
apnsToken: apnsToken,
logger: .empty(),
)
XCTAssertEqual(result, .success(responseSession))
}
@ -288,6 +302,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.beginOrRestoreSession(
e164: e164,
apnsToken: apnsToken,
logger: .empty(),
)
XCTAssertEqual(result, .success(responseSession))
}
@ -315,6 +330,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.beginOrRestoreSession(
e164: newE164,
apnsToken: apnsToken,
logger: .empty(),
)
XCTAssertEqual(result, .success(responseSession))
}
@ -338,6 +354,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
sessionId: oldSession.id,
captchaToken: captchaToken, // Put both, doesn't matter cuz we just match the url.
pushChallengeToken: pushChallengeToken,
logger: .empty(),
)
// will have a new id, which is fine cuz it lets us differentiate.
@ -367,6 +384,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
Registration.ChallengeFulfillment.captcha(captchaToken),
.pushChallenge(pushChallengeToken),
].randomElement()!,
logger: .empty(),
)
XCTAssertEqual(result, expectedResponse)
}
@ -379,6 +397,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
sessionId: oldSession.id,
captchaToken: captchaToken,
pushChallengeToken: nil,
logger: .empty(),
)
mockURLSession.addResponse(
@ -390,6 +409,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.fulfillChallenge(
for: oldSession,
fulfillment: .captcha(captchaToken),
logger: .empty(),
)
XCTAssertEqual(result, Registration.UpdateSessionResponse.genericError)
}
@ -402,6 +422,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
languageCode: nil,
countryCode: nil,
transport: .sms,
logger: .empty(),
)
// will have a new id, which is fine cuz it lets us differentiate.
@ -428,6 +449,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.requestVerificationCode(
for: oldSession,
transport: [Registration.CodeTransport.sms, .voice].randomElement()!,
logger: .empty(),
)
XCTAssertEqual(result, expectedResponse)
}
@ -440,6 +462,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
languageCode: nil,
countryCode: nil,
transport: .sms,
logger: .empty(),
)
var errorResponseJSON = """
@ -459,6 +482,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.requestVerificationCode(
for: oldSession,
transport: [Registration.CodeTransport.sms, .voice].randomElement()!,
logger: .empty(),
)
XCTAssertEqual(result, .serverFailure(Registration.ServerFailureResponse(
session: oldSession,
@ -484,6 +508,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.requestVerificationCode(
for: oldSession,
transport: [Registration.CodeTransport.sms, .voice].randomElement()!,
logger: .empty(),
)
XCTAssertEqual(result, .serverFailure(Registration.ServerFailureResponse(
session: oldSession,
@ -499,6 +524,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let expectedRequest = RegistrationRequestFactory.submitVerificationCodeRequest(
sessionId: oldSession.id,
code: code,
logger: .empty(),
)
// will have a new ids, which is fine cuz it lets us differentiate.
@ -533,6 +559,7 @@ public class RegistrationSessionManagerTest: XCTestCase {
let result = await registrationSessionManager.submitVerificationCode(
for: oldSession,
code: code,
logger: .empty(),
)
XCTAssertEqual(result, expectedResponse)
}