Unify backup logging through a common logger
This commit is contained in:
parent
ddec512bb0
commit
f4f4696650
@ -714,7 +714,7 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
guard let localIdentifiers = tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else {
|
||||
throw OWSAssertionError("never registered")
|
||||
}
|
||||
try await backupRefreshManager.refreshBackup(localIdentifiers: localIdentifiers)
|
||||
try await backupRefreshManager.refreshBackup(localIdentifiers: localIdentifiers, logger: PrefixedLogger(prefix: "[Backups][Refresh]"))
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@ -254,6 +254,7 @@ public class AppEnvironment: NSObject {
|
||||
try await backupIdService.registerBackupIDIfNecessary(
|
||||
localAci: localIdentifiers.aci,
|
||||
auth: .implicit(),
|
||||
logger: PrefixedLogger(prefix: "[Launch]"),
|
||||
)
|
||||
} catch {
|
||||
// Do nothing, we'll try again on the next app launch.
|
||||
|
||||
@ -181,6 +181,7 @@ final class BackupDisablingManager {
|
||||
try await backupKeyService.deleteBackupKey(
|
||||
localIdentifiers: localIdentifiers,
|
||||
auth: .implicit(),
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -113,6 +113,7 @@ final class BackupEnablingManager {
|
||||
_ = try await self.backupKeyService.registerBackupKey(
|
||||
localIdentifiers: localIdentifiers,
|
||||
auth: .implicit(),
|
||||
logger: logger,
|
||||
)
|
||||
} catch where error.isNetworkFailureOrTimeout {
|
||||
throw .networkError
|
||||
|
||||
@ -47,7 +47,7 @@ final class BackupRefreshManager {
|
||||
}
|
||||
}
|
||||
|
||||
func refreshBackup(localIdentifiers: LocalIdentifiers) async throws {
|
||||
func refreshBackup(localIdentifiers: LocalIdentifiers, logger: PrefixedLogger) async throws {
|
||||
let backupPlan = db.read(block: backupSettingsStore.backupPlan(tx:))
|
||||
switch backupPlan {
|
||||
case .disabled:
|
||||
@ -61,15 +61,17 @@ final class BackupRefreshManager {
|
||||
for: messageBackupKey,
|
||||
localAci: localIdentifiers.aci,
|
||||
auth: .implicit(),
|
||||
logger: logger,
|
||||
)
|
||||
try await api.refreshBackup(auth: messageBackupAuth)
|
||||
try await api.refreshBackup(auth: messageBackupAuth, logger: logger)
|
||||
|
||||
let mediaBackupAuth = try await backupRequestManager.fetchBackupServiceAuth(
|
||||
for: mediaBackupKey,
|
||||
localAci: localIdentifiers.aci,
|
||||
auth: .implicit(),
|
||||
logger: logger,
|
||||
)
|
||||
try await api.refreshBackup(auth: mediaBackupAuth)
|
||||
try await api.refreshBackup(auth: mediaBackupAuth, logger: logger)
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
@ -81,8 +83,8 @@ final class BackupRefreshManager {
|
||||
self.networkManager = networkManager
|
||||
}
|
||||
|
||||
func refreshBackup(auth: BackupServiceAuth) async throws {
|
||||
_ = try await networkManager.asyncRequest(.refreshBackup(auth: auth))
|
||||
func refreshBackup(auth: BackupServiceAuth, logger: PrefixedLogger) async throws {
|
||||
_ = try await networkManager.asyncRequest(.refreshBackup(auth: auth, logger: logger))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,11 +92,12 @@ final class BackupRefreshManager {
|
||||
// MARK: -
|
||||
|
||||
private extension TSRequest {
|
||||
static func refreshBackup(auth: BackupServiceAuth) -> TSRequest {
|
||||
static func refreshBackup(auth: BackupServiceAuth, logger: PrefixedLogger) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives")!,
|
||||
method: "POST",
|
||||
parameters: [:],
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
|
||||
@ -1168,7 +1168,7 @@ class BackupSettingsViewController:
|
||||
|
||||
// Check if we've hit the limit for registering new backupIDs and warn the user
|
||||
if
|
||||
let limits = try? await backupIdService.fetchBackupIDLimits(auth: .implicit()),
|
||||
let limits = try? await backupIdService.fetchBackupIDLimits(auth: .implicit(), logger: PrefixedLogger(prefix: "[Settings]")),
|
||||
!limits.hasPermitsRemaining
|
||||
{
|
||||
let bodyText = String(
|
||||
|
||||
@ -174,6 +174,7 @@ extension RegistrationCoordinatorImpl {
|
||||
e164: e164,
|
||||
reglockToken: reglockToken,
|
||||
pniChangeNumberParameters: pniChangeNumberParameters,
|
||||
logger: .empty(), // TODO [Registration+Backups Logging]
|
||||
)
|
||||
return await makeRequest(
|
||||
{ try await networkManager.asyncRequest(request) },
|
||||
|
||||
@ -596,6 +596,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
|
||||
backupKey: backupKey,
|
||||
backupAuth: backupServiceAuth,
|
||||
progress: downloadProgress,
|
||||
logger: .empty(), // TODO [Registration+Backups Logging]
|
||||
)
|
||||
}
|
||||
|
||||
@ -640,6 +641,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
|
||||
let metadataHeader = try await self.deps.backupArchiveManager.backupCdnInfo(
|
||||
backupKey: backupKey,
|
||||
backupAuth: backupServiceAuth,
|
||||
logger: .empty(), // TODO [Registration+Backups Logging]
|
||||
).metadataHeader
|
||||
self.inMemoryState.backupMetadataHeader = metadataHeader
|
||||
nonceSource = .svrB(header: metadataHeader, auth: identity.chatServiceAuth)
|
||||
@ -651,6 +653,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
|
||||
isPrimaryDevice: true,
|
||||
source: .remote(key: backupKey, nonceSource: nonceSource),
|
||||
progress: importProgress,
|
||||
logger: .empty(), // TODO [Registration+Backups Logging]
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1480,6 +1483,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
|
||||
let cdnInfo = try await self.deps.backupArchiveManager.backupCdnInfo(
|
||||
backupKey: backupKey,
|
||||
backupAuth: backupServiceAuth,
|
||||
logger: .empty(), // TODO [Registration+Backups Logging]
|
||||
)
|
||||
self.inMemoryState.backupMetadataHeader = cdnInfo.metadataHeader
|
||||
return .confirmRestoreFromBackup(
|
||||
@ -1533,6 +1537,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
|
||||
key: backupKey,
|
||||
localAci: accountIdentity.aci,
|
||||
chatServiceAuth: accountIdentity.chatServiceAuth,
|
||||
logger: .empty(), // TODO [Registration+Backups Logging]
|
||||
)
|
||||
}
|
||||
|
||||
@ -1542,6 +1547,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator {
|
||||
try await self.deps.backupIdService.updateMessageBackupIdForRegistration(
|
||||
key: backupKey,
|
||||
auth: accountIdentity.chatServiceAuth,
|
||||
logger: .empty(), // TODO [Registration+Backups Logging]
|
||||
)
|
||||
return try await fetchBackupServiceAuth()
|
||||
}
|
||||
|
||||
@ -380,6 +380,7 @@ class DeleteAccountConfirmationViewController: OWSTableViewController2 {
|
||||
try await backupKeyService.deleteBackupKey(
|
||||
localIdentifiers: localIdentifiers,
|
||||
auth: .implicit(),
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -445,6 +445,7 @@ private extension InternalSettingsViewController {
|
||||
localIdentifiers: localIdentifiers,
|
||||
backupPurpose: .remoteExport(key: messageBackupKey, chatAuth: .implicit()),
|
||||
progress: nil,
|
||||
logger: PrefixedLogger(prefix: "[Backups]"),
|
||||
)
|
||||
|
||||
return (backupKey, exportMetadata)
|
||||
|
||||
@ -48,7 +48,7 @@ struct BackupRefreshManagerTest {
|
||||
mockNetworkManager.asyncRequestHandlers.append(refreshSuccessResponse)
|
||||
mockNetworkManager.asyncRequestHandlers.append(refreshSuccessResponse)
|
||||
|
||||
try await mockBackupRefreshManager.refreshBackup(localIdentifiers: LocalIdentifiers.forUnitTests)
|
||||
try await mockBackupRefreshManager.refreshBackup(localIdentifiers: LocalIdentifiers.forUnitTests, logger: .empty())
|
||||
|
||||
#expect(mockNetworkManager.asyncRequestHandlers.isEmpty)
|
||||
}
|
||||
@ -61,6 +61,6 @@ struct BackupRefreshManagerTest {
|
||||
accountKeyStore.setAccountEntropyPool(AccountEntropyPool(), tx: tx)
|
||||
}
|
||||
|
||||
try await mockBackupRefreshManager.refreshBackup(localIdentifiers: LocalIdentifiers.forUnitTests)
|
||||
try await mockBackupRefreshManager.refreshBackup(localIdentifiers: LocalIdentifiers.forUnitTests, logger: .empty())
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ public protocol BackupArchiveManager {
|
||||
func backupCdnInfo(
|
||||
backupKey: MessageRootBackupKey,
|
||||
backupAuth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupCdnInfo
|
||||
|
||||
/// Download the encrypted backup for the current user to a local file.
|
||||
@ -35,6 +36,7 @@ public protocol BackupArchiveManager {
|
||||
backupKey: MessageRootBackupKey,
|
||||
backupAuth: BackupServiceAuth,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> URL
|
||||
|
||||
/// Upload the local encrypted backup identified by the given metadata for
|
||||
@ -44,6 +46,7 @@ public protocol BackupArchiveManager {
|
||||
metadata: Upload.EncryptedBackupUploadMetadata,
|
||||
auth: ChatServiceAuth,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Result<Upload.EncryptedBackupUploadMetadata>
|
||||
|
||||
// MARK: - Export
|
||||
@ -54,6 +57,7 @@ public protocol BackupArchiveManager {
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
backupPurpose: BackupExportPurpose,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.EncryptedBackupUploadMetadata
|
||||
|
||||
#if TESTABLE_BUILD
|
||||
@ -78,6 +82,7 @@ public protocol BackupArchiveManager {
|
||||
isPrimaryDevice: Bool,
|
||||
source: BackupImportSource,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws
|
||||
|
||||
#if TESTABLE_BUILD
|
||||
|
||||
@ -159,8 +159,9 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
backupKey: MessageRootBackupKey,
|
||||
backupAuth: BackupServiceAuth,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> URL {
|
||||
let metadata = try await backupRequestManager.fetchBackupRequestMetadata(auth: backupAuth)
|
||||
let metadata = try await backupRequestManager.fetchBackupRequestMetadata(auth: backupAuth, logger: logger)
|
||||
let tmpFileUrl = try await attachmentDownloadManager.downloadBackup(
|
||||
metadata: metadata,
|
||||
progress: progress,
|
||||
@ -175,8 +176,9 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
public func backupCdnInfo(
|
||||
backupKey: MessageRootBackupKey,
|
||||
backupAuth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupCdnInfo {
|
||||
let metadata = try await backupRequestManager.fetchBackupRequestMetadata(auth: backupAuth)
|
||||
let metadata = try await backupRequestManager.fetchBackupRequestMetadata(auth: backupAuth, logger: logger)
|
||||
return try await attachmentDownloadManager.backupCdnInfo(metadata: metadata)
|
||||
}
|
||||
|
||||
@ -185,6 +187,7 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
metadata: Upload.EncryptedBackupUploadMetadata,
|
||||
auth: ChatServiceAuth,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Result<Upload.EncryptedBackupUploadMetadata> {
|
||||
guard db.read(block: { tsAccountManager.registrationState(tx: $0).isPrimaryDevice }) == true else {
|
||||
throw OWSAssertionError("Backing up not on a registered primary!")
|
||||
@ -194,12 +197,14 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
for: backupKey,
|
||||
localAci: backupKey.aci,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
let form: Upload.Form
|
||||
do {
|
||||
form = try await backupRequestManager.fetchBackupUploadForm(
|
||||
backupByteLength: metadata.encryptedDataLength,
|
||||
auth: backupAuth,
|
||||
logger: logger,
|
||||
)
|
||||
} catch let error {
|
||||
switch error as? BackupArchive.Response.BackupUploadFormError {
|
||||
@ -227,7 +232,7 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
backupFileSizeBytes = UInt64(metadata.encryptedDataLength)
|
||||
backupMediaSizeBytes = 0
|
||||
case .disabled, .disabling:
|
||||
owsFailDebug("Shouldn't generate backup when backups is disabled")
|
||||
owsFailDebug("Shouldn't generate backup when backups is disabled", logger: logger)
|
||||
backupFileSizeBytes = 0
|
||||
backupMediaSizeBytes = 0
|
||||
}
|
||||
@ -262,6 +267,7 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
backupPurpose: BackupExportPurpose,
|
||||
progress progressSink: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.EncryptedBackupUploadMetadata {
|
||||
let attachmentByteCounter = BackupArchiveAttachmentByteCounter()
|
||||
let startDate = dateProvider()
|
||||
@ -279,12 +285,12 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
// can't be recovered using the material in SVRB.
|
||||
if db.read(block: { needsRestoreFromSVRBBeforeRemoteExport(tx: $0) }) {
|
||||
do {
|
||||
try await fetchRemoteSVRBForwardSecrecyToken(key: key, auth: chatAuth)
|
||||
try await fetchRemoteSVRBForwardSecrecyToken(key: key, auth: chatAuth, logger: logger)
|
||||
} catch SVRBError.unrecoverable {
|
||||
// Not found, so consider a success and fallthrough
|
||||
Logger.info("SVRB not found, skipping restore.")
|
||||
logger.info("SVRB not found, skipping restore.")
|
||||
} catch {
|
||||
Logger.warn("Encountered error restoring SVRB: \(error)")
|
||||
logger.warn("Encountered error restoring SVRB: \(error)")
|
||||
throw error
|
||||
}
|
||||
|
||||
@ -754,6 +760,7 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
isPrimaryDevice: Bool,
|
||||
source: BackupImportSource,
|
||||
progress progressSink: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
|
||||
let backupEncryptionKey = try await source.deriveBackupEncryptionKeyWithSVRBIfNeeded(
|
||||
@ -761,6 +768,7 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: backupNonceMetadataStore,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
try await _importBackup(
|
||||
@ -1520,11 +1528,13 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
private func fetchRemoteSVRBForwardSecrecyToken(
|
||||
key: MessageRootBackupKey,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let backupServiceAuth = try await backupRequestManager.fetchBackupServiceAuthForRegistration(
|
||||
key: key,
|
||||
localAci: key.aci,
|
||||
chatServiceAuth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
let metadataHeader: BackupNonce.MetadataHeader
|
||||
@ -1532,6 +1542,7 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
metadataHeader = try await backupCdnInfo(
|
||||
backupKey: key,
|
||||
backupAuth: backupServiceAuth,
|
||||
logger: logger,
|
||||
).metadataHeader
|
||||
} catch let error as OWSHTTPError where error.responseStatusCode == 404 {
|
||||
// If no backup is found, treat this as unrecoverable
|
||||
@ -1545,6 +1556,7 @@ public class BackupArchiveManagerImpl: BackupArchiveManager {
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: backupNonceMetadataStore,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ open class BackupArchiveManagerMock: BackupArchiveManager {
|
||||
public func backupCdnInfo(
|
||||
backupKey: MessageRootBackupKey,
|
||||
backupAuth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupCdnInfo {
|
||||
return BackupCdnInfo(
|
||||
fileInfo: AttachmentDownloads.CdnInfo(contentLength: 0, lastModified: Date()),
|
||||
@ -23,6 +24,7 @@ open class BackupArchiveManagerMock: BackupArchiveManager {
|
||||
backupKey: MessageRootBackupKey,
|
||||
backupAuth: BackupServiceAuth,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> URL {
|
||||
return URL(string: "file://")!
|
||||
}
|
||||
@ -32,6 +34,7 @@ open class BackupArchiveManagerMock: BackupArchiveManager {
|
||||
metadata: Upload.EncryptedBackupUploadMetadata,
|
||||
auth: ChatServiceAuth,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Result<Upload.EncryptedBackupUploadMetadata> {
|
||||
return Upload.Result(
|
||||
cdnKey: "cdnKey",
|
||||
@ -46,6 +49,7 @@ open class BackupArchiveManagerMock: BackupArchiveManager {
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
backupPurpose: BackupExportPurpose,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.EncryptedBackupUploadMetadata {
|
||||
let source = await progress?.addSource(withLabel: "", unitCount: 1)
|
||||
source?.incrementCompletedUnitCount(by: 1)
|
||||
@ -75,6 +79,7 @@ open class BackupArchiveManagerMock: BackupArchiveManager {
|
||||
isPrimaryDevice: Bool,
|
||||
source: BackupImportSource,
|
||||
progress: OWSProgressSink?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let source = await progress?.addSource(withLabel: "", unitCount: 1)
|
||||
source?.incrementCompletedUnitCount(by: 1)
|
||||
|
||||
@ -127,6 +127,7 @@ extension BackupImportSource {
|
||||
db: any DB,
|
||||
libsignalNet: LibSignalClient.Net,
|
||||
nonceStore: BackupNonceMetadataStore,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> MessageBackupKey {
|
||||
switch self {
|
||||
case let .remote(key, noneSource):
|
||||
@ -149,6 +150,7 @@ extension BackupImportSource {
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
logger: logger,
|
||||
)
|
||||
} catch .cancellationError {
|
||||
throw CancellationError()
|
||||
@ -184,6 +186,7 @@ extension BackupImportSource {
|
||||
db: any DB,
|
||||
libsignalNet: LibSignalClient.Net,
|
||||
nonceStore: BackupNonceMetadataStore,
|
||||
logger: PrefixedLogger,
|
||||
) async throws(SVRBError) -> BackupForwardSecrecyToken {
|
||||
let svrBAuth: LibSignalClient.Auth
|
||||
do {
|
||||
@ -193,6 +196,7 @@ extension BackupImportSource {
|
||||
// Force fetch new credentials on retries to make sure
|
||||
// it wasn't stale credentials that caused the problem.
|
||||
forceRefresh: isRetry,
|
||||
logger: logger,
|
||||
)
|
||||
} catch is CancellationError {
|
||||
throw .cancellationError
|
||||
@ -245,6 +249,7 @@ extension BackupImportSource {
|
||||
db: db,
|
||||
libsignalNet: libsignalNet,
|
||||
nonceStore: nonceStore,
|
||||
logger: logger,
|
||||
)
|
||||
case .connectionFailed, .connectionTimeoutError, .ioError, .webSocketError:
|
||||
// Network-level failures mostly end up in these buckets;
|
||||
@ -362,6 +367,7 @@ extension BackupExportPurpose {
|
||||
// Force fetch new credentials on retries to make sure
|
||||
// it wasn't stale credentials that caused the problem.
|
||||
forceRefresh: isRetry,
|
||||
logger: logger,
|
||||
)
|
||||
} catch let error {
|
||||
if error is CancellationError {
|
||||
|
||||
@ -145,7 +145,7 @@ class BackupAttachmentUploadQueueRunnerImpl: BackupAttachmentUploadQueueRunner {
|
||||
}
|
||||
|
||||
guard let backupKey else {
|
||||
Logger.info("Skipping \(logString) attachment backups while media backup key is missing")
|
||||
logger.info("Skipping \(logString) attachment backups while media backup key is missing")
|
||||
return
|
||||
}
|
||||
|
||||
@ -167,6 +167,7 @@ class BackupAttachmentUploadQueueRunnerImpl: BackupAttachmentUploadQueueRunner {
|
||||
localAci: localAci,
|
||||
auth: .implicit(),
|
||||
forceRefreshUnlessCachedPaidCredential: true,
|
||||
logger: logger,
|
||||
)
|
||||
} catch let error as BackupAuthCredentialFetchError {
|
||||
switch error {
|
||||
@ -376,7 +377,7 @@ class BackupAttachmentUploadQueueRunnerImpl: BackupAttachmentUploadQueueRunner {
|
||||
}
|
||||
|
||||
guard let backupKey else {
|
||||
owsFailDebug("Missing media backup key. Unable to upload attachments.")
|
||||
owsFailDebug("Missing media backup key. Unable to upload attachments.", logger: logger)
|
||||
return .cancelled
|
||||
}
|
||||
|
||||
@ -450,6 +451,7 @@ class BackupAttachmentUploadQueueRunnerImpl: BackupAttachmentUploadQueueRunner {
|
||||
// can change _after_ this queue has already started running, so we
|
||||
// do need to handle that case).
|
||||
forceRefreshUnlessCachedPaidCredential: false,
|
||||
logger: logger,
|
||||
)
|
||||
} catch let error {
|
||||
try? await loader.stop(reason: error)
|
||||
@ -538,6 +540,7 @@ class BackupAttachmentUploadQueueRunnerImpl: BackupAttachmentUploadQueueRunner {
|
||||
localAci: localAci,
|
||||
auth: .implicit(),
|
||||
forceRefreshUnlessCachedPaidCredential: true,
|
||||
logger: logger,
|
||||
)
|
||||
switch credential?.backupLevel {
|
||||
case .free, nil:
|
||||
@ -724,10 +727,10 @@ class BackupAttachmentUploadQueueRunnerImpl: BackupAttachmentUploadQueueRunner {
|
||||
func didDrainQueue() async {
|
||||
switch mode {
|
||||
case .fullsize:
|
||||
Logger.info("Did drain fullsize upload queue")
|
||||
logger.info("Did drain fullsize upload queue")
|
||||
await progress.didEmptyFullsizeUploadQueue()
|
||||
case .thumbnail:
|
||||
Logger.info("Did drain thumbnail upload queue")
|
||||
logger.info("Did drain thumbnail upload queue")
|
||||
}
|
||||
await statusManager.didEmptyQueue(for: mode)
|
||||
}
|
||||
|
||||
@ -328,7 +328,7 @@ class BackupListMediaManagerImpl: BackupListMediaManager {
|
||||
}
|
||||
|
||||
if !hasCompletedListingMedia {
|
||||
try await makeListMediaRequest(backupKey: backupKey, localAci: localAci)
|
||||
try await makeListMediaRequest(backupKey: backupKey, localAci: localAci, logger: logger)
|
||||
}
|
||||
|
||||
let hasCompletedEnumeratingAttchments: Bool = db.read { tx in
|
||||
@ -595,11 +595,13 @@ class BackupListMediaManagerImpl: BackupListMediaManager {
|
||||
private func makeListMediaRequest(
|
||||
backupKey: MediaRootBackupKey,
|
||||
localAci: Aci,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let backupAuth: BackupServiceAuth = try await backupRequestManager.fetchBackupServiceAuth(
|
||||
for: backupKey,
|
||||
localAci: localAci,
|
||||
auth: .implicit(),
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
var nextCursor: String? = db.read { tx in
|
||||
@ -613,6 +615,7 @@ class BackupListMediaManagerImpl: BackupListMediaManager {
|
||||
cursor: nextCursor,
|
||||
limit: nil, /* let the server determine the page size */
|
||||
auth: backupAuth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
await persistListedMediaPage(page)
|
||||
|
||||
@ -201,6 +201,7 @@ public class OrphanedBackupAttachmentQueueRunnerImpl: OrphanedBackupAttachmentQu
|
||||
for: mediaRootBackupKey,
|
||||
localAci: localAci,
|
||||
auth: .implicit(),
|
||||
logger: .empty(), // TODO: [Logging]
|
||||
)
|
||||
} catch let error {
|
||||
try? await loader.stop(reason: error)
|
||||
@ -214,6 +215,7 @@ public class OrphanedBackupAttachmentQueueRunnerImpl: OrphanedBackupAttachmentQu
|
||||
mediaId: mediaId,
|
||||
)],
|
||||
auth: backupAuth,
|
||||
logger: .empty(), // TODO: [Logging]
|
||||
)
|
||||
} catch let error {
|
||||
if error.isNetworkFailureOrTimeout {
|
||||
|
||||
@ -218,6 +218,7 @@ class BackupExportJobImpl: BackupExportJob {
|
||||
chatAuth: .implicit(),
|
||||
),
|
||||
progress: progress?.child(for: .backupFileExport),
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
logger.info("Uploading backup...")
|
||||
@ -232,6 +233,7 @@ class BackupExportJobImpl: BackupExportJob {
|
||||
metadata: uploadMetadata,
|
||||
auth: .implicit(),
|
||||
progress: progress?.child(for: .backupFileUpload),
|
||||
logger: logger,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@ -95,6 +95,7 @@ public protocol BackupRequestManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth
|
||||
|
||||
/// Passthrough API for ``BackupAuthCredentialManager/fetchBackupServiceAuth``.
|
||||
@ -103,49 +104,62 @@ public protocol BackupRequestManager {
|
||||
localAci: Aci,
|
||||
auth: ChatServiceAuth,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth
|
||||
|
||||
/// - parameter backupByteLength: length in bytes of the encrypted backup file we will upload
|
||||
func fetchBackupUploadForm(
|
||||
backupByteLength: UInt32,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Form
|
||||
|
||||
func fetchBackupMediaAttachmentUploadForm(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Form
|
||||
|
||||
func fetchMediaTierCdnRequestMetadata(cdn: Int32, auth: BackupServiceAuth) async throws -> MediaTierReadCredential
|
||||
func fetchMediaTierCdnRequestMetadata(
|
||||
cdn: Int32,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> MediaTierReadCredential
|
||||
|
||||
func fetchBackupRequestMetadata(auth: BackupServiceAuth) async throws -> BackupReadCredential
|
||||
func fetchBackupRequestMetadata(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupReadCredential
|
||||
|
||||
func copyToMediaTier(
|
||||
item: BackupArchive.Request.MediaItem,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger?,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> UInt32
|
||||
|
||||
func copyToMediaTier(
|
||||
items: [BackupArchive.Request.MediaItem],
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> [BackupArchive.Response.BatchedBackupMediaResult]
|
||||
|
||||
func listMediaObjects(
|
||||
cursor: String?,
|
||||
limit: UInt32?,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupArchive.Response.ListMediaResult
|
||||
|
||||
func deleteMediaObjects(
|
||||
objects: [BackupArchive.Request.DeleteMediaTarget],
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws
|
||||
|
||||
func fetchSVRBAuthCredential(
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth
|
||||
}
|
||||
|
||||
@ -154,12 +168,14 @@ extension BackupRequestManager {
|
||||
for key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
return try await self.fetchBackupServiceAuth(
|
||||
for: key,
|
||||
localAci: localAci,
|
||||
auth: auth,
|
||||
forceRefreshUnlessCachedPaidCredential: false,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -197,11 +213,13 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
return try await backupAuthCredentialManager.fetchBackupServiceAuthForRegistration(
|
||||
key: key,
|
||||
localAci: localAci,
|
||||
chatServiceAuth: chatServiceAuth,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
@ -210,12 +228,14 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
localAci: Aci,
|
||||
auth: ChatServiceAuth,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
return try await backupAuthCredentialManager.fetchBackupServiceAuth(
|
||||
key: key,
|
||||
localAci: localAci,
|
||||
chatServiceAuth: auth,
|
||||
forceRefreshUnlessCachedPaidCredential: forceRefreshUnlessCachedPaidCredential,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
@ -225,6 +245,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
public func fetchBackupUploadForm(
|
||||
backupByteLength: UInt32,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Form {
|
||||
owsAssertDebug(auth.type == .messages)
|
||||
do {
|
||||
@ -234,6 +255,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
OWSRequestFactory.backupUploadFormRequest(
|
||||
backupByteLength: backupByteLength,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -252,7 +274,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
/// CDN upload form for uploading backup media
|
||||
public func fetchBackupMediaAttachmentUploadForm(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger? = nil,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Form {
|
||||
owsAssertDebug(auth.type == .media)
|
||||
return try await executeBackupService(
|
||||
@ -268,7 +290,10 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
|
||||
// MARK: - Backup Info
|
||||
|
||||
private func fetchBackupCDNMetadata(auth: BackupServiceAuth) async throws -> BackupCDNMetadata {
|
||||
private func fetchBackupCDNMetadata(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupCDNMetadata {
|
||||
if
|
||||
let cachedCDNMetadata = db.read(block: { tx in
|
||||
backupCDNCredentialStore.backupCDNMetadata(
|
||||
@ -283,7 +308,9 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
|
||||
let cdnMetadata: BackupCDNMetadata = try await executeBackupService(
|
||||
auth: auth,
|
||||
requestFactory: OWSRequestFactory.backupInfoRequest(auth:),
|
||||
requestFactory: {
|
||||
OWSRequestFactory.backupInfoRequest(auth: $0, logger: logger)
|
||||
},
|
||||
)
|
||||
|
||||
await db.awaitableWrite { tx in
|
||||
@ -301,10 +328,15 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
|
||||
// TODO: [Backups] Call this regularly, or move it somewhere it is called regularly
|
||||
/// Backup keep-alive request. If not called, the backup may be deleted after 30 days.
|
||||
private func refreshBackupInfo(auth: BackupServiceAuth) async throws {
|
||||
private func refreshBackupInfo(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
_ = try await executeBackupServiceRequest(
|
||||
auth: auth,
|
||||
requestFactory: OWSRequestFactory.backupRefreshInfoRequest(auth:),
|
||||
requestFactory: {
|
||||
OWSRequestFactory.backupRefreshInfoRequest(auth: $0, logger: logger)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ -314,6 +346,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
private func fetchCDNReadCredentials(
|
||||
cdn: Int32,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupCDNReadCredential {
|
||||
if
|
||||
let cachedCDNReadCredential = db.read(block: { tx in
|
||||
@ -330,7 +363,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
|
||||
let cdnReadCredential: BackupCDNReadCredential = try await executeBackupService(
|
||||
auth: auth,
|
||||
requestFactory: { OWSRequestFactory.fetchBackupCDNCredentials(auth: $0, cdn: cdn) },
|
||||
requestFactory: { OWSRequestFactory.fetchBackupCDNCredentials(auth: $0, cdn: cdn, logger: logger) },
|
||||
)
|
||||
|
||||
await db.awaitableWrite { tx in
|
||||
@ -346,26 +379,30 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
return cdnReadCredential
|
||||
}
|
||||
|
||||
public func fetchBackupRequestMetadata(auth: BackupServiceAuth) async throws -> BackupReadCredential {
|
||||
let metadata = try await fetchBackupCDNMetadata(auth: auth)
|
||||
let authCredential = try await fetchCDNReadCredentials(cdn: metadata.cdn, auth: auth)
|
||||
public func fetchBackupRequestMetadata(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupReadCredential {
|
||||
let metadata = try await fetchBackupCDNMetadata(auth: auth, logger: logger)
|
||||
let authCredential = try await fetchCDNReadCredentials(cdn: metadata.cdn, auth: auth, logger: logger)
|
||||
return BackupReadCredential(credential: authCredential, metadata: metadata)
|
||||
}
|
||||
|
||||
public func fetchMediaTierCdnRequestMetadata(
|
||||
cdn: Int32,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> MediaTierReadCredential {
|
||||
owsAssertDebug(auth.type == .media)
|
||||
let metadata = try await fetchBackupCDNMetadata(auth: auth)
|
||||
let authCredential = try await fetchCDNReadCredentials(cdn: cdn, auth: auth)
|
||||
let metadata = try await fetchBackupCDNMetadata(auth: auth, logger: logger)
|
||||
let authCredential = try await fetchCDNReadCredentials(cdn: cdn, auth: auth, logger: logger)
|
||||
return MediaTierReadCredential(cdn: cdn, credential: authCredential, metadata: metadata)
|
||||
}
|
||||
|
||||
public func copyToMediaTier(
|
||||
item: BackupArchive.Request.MediaItem,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger? = nil,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> UInt32 {
|
||||
owsAssertDebug(auth.type == .media)
|
||||
do {
|
||||
@ -405,6 +442,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
public func copyToMediaTier(
|
||||
items: [BackupArchive.Request.MediaItem],
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> [BackupArchive.Response.BatchedBackupMediaResult] {
|
||||
owsAssertDebug(auth.type == .media)
|
||||
return try await executeBackupService(
|
||||
@ -413,6 +451,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
OWSRequestFactory.archiveMedia(
|
||||
auth: $0,
|
||||
items: items,
|
||||
logger: logger,
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -422,6 +461,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
cursor: String?,
|
||||
limit: UInt32?,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupArchive.Response.ListMediaResult {
|
||||
owsAssertDebug(auth.type == .media)
|
||||
return try await executeBackupService(
|
||||
@ -431,12 +471,17 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
auth: $0,
|
||||
cursor: cursor,
|
||||
limit: limit,
|
||||
logger: logger,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
public func deleteMediaObjects(objects: [BackupArchive.Request.DeleteMediaTarget], auth: BackupServiceAuth) async throws {
|
||||
public func deleteMediaObjects(
|
||||
objects: [BackupArchive.Request.DeleteMediaTarget],
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
owsAssertDebug(auth.type == .media)
|
||||
_ = try await executeBackupServiceRequest(
|
||||
auth: auth,
|
||||
@ -444,6 +489,7 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
OWSRequestFactory.deleteMedia(
|
||||
auth: $0,
|
||||
objects: objects,
|
||||
logger: logger,
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -453,11 +499,13 @@ public struct BackupRequestManagerImpl: BackupRequestManager {
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
return try await backupAuthCredentialManager.fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: auth,
|
||||
forceRefresh: forceRefresh,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
@ -556,6 +604,7 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
return BackupServiceAuth.mock(type: .media, backupLevel: .paid)
|
||||
}
|
||||
@ -565,6 +614,7 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
localAci: LibSignalClient.Aci,
|
||||
auth: SignalServiceKit.ChatServiceAuth,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> SignalServiceKit.BackupServiceAuth {
|
||||
return BackupServiceAuth.mock(type: .media, backupLevel: .paid)
|
||||
}
|
||||
@ -572,13 +622,14 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
public func fetchBackupUploadForm(
|
||||
backupByteLength: UInt32,
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> SignalServiceKit.Upload.Form {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
|
||||
public func fetchBackupMediaAttachmentUploadForm(
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger? = nil,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> SignalServiceKit.Upload.Form {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
@ -586,12 +637,14 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
public func fetchMediaTierCdnRequestMetadata(
|
||||
cdn: Int32,
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> SignalServiceKit.MediaTierReadCredential {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
|
||||
public func fetchBackupRequestMetadata(
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> SignalServiceKit.BackupReadCredential {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
@ -599,7 +652,7 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
public func copyToMediaTier(
|
||||
item: SignalServiceKit.BackupArchive.Request.MediaItem,
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger? = nil,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> UInt32 {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
@ -607,6 +660,7 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
public func copyToMediaTier(
|
||||
items: [SignalServiceKit.BackupArchive.Request.MediaItem],
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> [SignalServiceKit.BackupArchive.Response.BatchedBackupMediaResult] {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
@ -617,6 +671,7 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
cursor: String?,
|
||||
limit: UInt32?,
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> SignalServiceKit.BackupArchive.Response.ListMediaResult {
|
||||
return listMediaResults.popFirst()!
|
||||
}
|
||||
@ -624,6 +679,7 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
public func deleteMediaObjects(
|
||||
objects: [SignalServiceKit.BackupArchive.Request.DeleteMediaTarget],
|
||||
auth: SignalServiceKit.BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
fatalError("Unimplemented")
|
||||
}
|
||||
@ -636,6 +692,7 @@ public class BackupRequestManagerMock: BackupRequestManager {
|
||||
key: SignalServiceKit.MessageRootBackupKey,
|
||||
chatServiceAuth auth: SignalServiceKit.ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
return LibSignalClient.Auth(username: "", password: "")
|
||||
}
|
||||
|
||||
@ -12,19 +12,21 @@ public struct MessageRootBackupKey: BackupKeyMaterial {
|
||||
public let backupId: Data
|
||||
|
||||
public let aci: Aci
|
||||
public let loggingKey: String
|
||||
|
||||
public init(accountEntropyPool: AccountEntropyPool, aci: Aci) throws(BackupKeyMaterialError) {
|
||||
do {
|
||||
let backupKey = try LibSignalClient.AccountEntropyPool.deriveBackupKey(accountEntropyPool.rawString)
|
||||
self.init(backupKey: backupKey, aci: aci)
|
||||
self.init(backupKey: backupKey, aci: aci, loggingKey: accountEntropyPool.getLoggingKey())
|
||||
} catch {
|
||||
throw BackupKeyMaterialError.derivationError(error)
|
||||
}
|
||||
}
|
||||
|
||||
init(backupKey: BackupKey, aci: Aci) {
|
||||
init(backupKey: BackupKey, aci: Aci, loggingKey: String = "") {
|
||||
self.backupKey = backupKey
|
||||
self.backupId = backupKey.deriveBackupId(aci: aci)
|
||||
self.aci = aci
|
||||
self.loggingKey = loggingKey
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,15 +16,18 @@ public protocol BackupIdService {
|
||||
func registerBackupIDIfNecessary(
|
||||
localAci: Aci,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws
|
||||
|
||||
func updateMessageBackupIdForRegistration(
|
||||
key: MessageRootBackupKey,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws
|
||||
|
||||
func fetchBackupIDLimits(
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupIdLimits
|
||||
}
|
||||
|
||||
@ -74,6 +77,7 @@ final class BackupIdServiceImpl: BackupIdService {
|
||||
func registerBackupIDIfNecessary(
|
||||
localAci: Aci,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let (
|
||||
haveSetBackupId,
|
||||
@ -104,6 +108,7 @@ final class BackupIdServiceImpl: BackupIdService {
|
||||
messageBackupKey: messageBackupKey,
|
||||
mediaBackupKey: mediaBackupKey,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
await db.awaitableWrite { tx in
|
||||
@ -114,19 +119,27 @@ final class BackupIdServiceImpl: BackupIdService {
|
||||
func updateMessageBackupIdForRegistration(
|
||||
key: MessageRootBackupKey,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
try await registerBackupId(
|
||||
localAci: key.aci,
|
||||
messageBackupKey: key,
|
||||
mediaBackupKey: nil,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
func fetchBackupIDLimits(
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupIdLimits {
|
||||
let response = try await networkManager.asyncRequest(.fetchBackupIdLimits(auth: auth))
|
||||
let response = try await networkManager.asyncRequest(
|
||||
.fetchBackupIdLimits(
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
),
|
||||
)
|
||||
guard let jsonData = response.responseBodyData else {
|
||||
throw OWSAssertionError("Missing or invalid JSON!")
|
||||
}
|
||||
@ -141,6 +154,7 @@ final class BackupIdServiceImpl: BackupIdService {
|
||||
messageBackupKey: MessageRootBackupKey,
|
||||
mediaBackupKey: MediaRootBackupKey?,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let messageBackupRequestContext: BackupAuthCredentialRequestContext = .create(
|
||||
backupKey: messageBackupKey.serialize(),
|
||||
@ -160,6 +174,7 @@ final class BackupIdServiceImpl: BackupIdService {
|
||||
backupId: base64MessageRequestContext,
|
||||
mediaBackupId: base64MediaRequestContext,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -172,6 +187,7 @@ private extension TSRequest {
|
||||
backupId: String,
|
||||
mediaBackupId: String?,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var parameters = ["messagesBackupAuthCredentialRequest": backupId]
|
||||
if let mediaBackupId {
|
||||
@ -182,6 +198,7 @@ private extension TSRequest {
|
||||
url: URL(string: "v1/archives/backupid")!,
|
||||
method: "PUT",
|
||||
parameters: parameters,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .identified(auth)
|
||||
return request
|
||||
@ -189,11 +206,13 @@ private extension TSRequest {
|
||||
|
||||
static func fetchBackupIdLimits(
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/backupid/limits")!,
|
||||
method: "GET",
|
||||
parameters: nil,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .identified(auth)
|
||||
return request
|
||||
@ -205,15 +224,15 @@ private extension TSRequest {
|
||||
#if TESTABLE_BUILD
|
||||
|
||||
class MockBackupIdService: BackupIdService {
|
||||
func fetchBackupIDLimits(auth: ChatServiceAuth) async throws -> BackupIdLimits {
|
||||
func fetchBackupIDLimits(auth: ChatServiceAuth, logger: PrefixedLogger) async throws -> BackupIdLimits {
|
||||
fatalError("Not implemented")
|
||||
}
|
||||
|
||||
func updateMessageBackupIdForRegistration(key: MessageRootBackupKey, auth: ChatServiceAuth) async throws {
|
||||
func updateMessageBackupIdForRegistration(key: MessageRootBackupKey, auth: ChatServiceAuth, logger: PrefixedLogger) async throws {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
func registerBackupIDIfNecessary(localAci: Aci, auth: ChatServiceAuth) async throws {
|
||||
func registerBackupIDIfNecessary(localAci: Aci, auth: ChatServiceAuth, logger: PrefixedLogger) async throws {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ public protocol BackupKeyService {
|
||||
func registerBackupKey(
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws
|
||||
|
||||
/// De-initialize Backups by deleting a previously-registered BackupKey.
|
||||
@ -32,13 +33,7 @@ public protocol BackupKeyService {
|
||||
func deleteBackupKey(
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
auth: ChatServiceAuth,
|
||||
) async throws
|
||||
|
||||
/// See ``deleteBackupKey(localIdentifiers:auth:)``. Similar, but with
|
||||
/// Backup auth prepared ahead of time.
|
||||
func deleteBackupKey(
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
backupAuth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws
|
||||
}
|
||||
|
||||
@ -85,11 +80,13 @@ final class BackupKeyServiceImpl: BackupKeyService {
|
||||
func registerBackupKey(
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
try await _registerBackupKey(
|
||||
localIdentifiers: localIdentifiers,
|
||||
auth: auth,
|
||||
retryOnFail: true,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
@ -97,6 +94,7 @@ final class BackupKeyServiceImpl: BackupKeyService {
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
auth: ChatServiceAuth,
|
||||
retryOnFail: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let (messageBackupKey, mediaBackupKey) = try await db.awaitableWrite { tx in
|
||||
try rootBackupKeys(localIdentifiers: localIdentifiers, tx: tx)
|
||||
@ -107,6 +105,7 @@ final class BackupKeyServiceImpl: BackupKeyService {
|
||||
for: messageBackupKey,
|
||||
localAci: localIdentifiers.aci,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
_ = try await networkManager.asyncRequest(
|
||||
@ -117,6 +116,7 @@ final class BackupKeyServiceImpl: BackupKeyService {
|
||||
for: mediaBackupKey,
|
||||
localAci: localIdentifiers.aci,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
_ = try await networkManager.asyncRequest(
|
||||
@ -136,6 +136,7 @@ final class BackupKeyServiceImpl: BackupKeyService {
|
||||
localIdentifiers: localIdentifiers,
|
||||
auth: auth,
|
||||
retryOnFail: false,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -145,6 +146,7 @@ final class BackupKeyServiceImpl: BackupKeyService {
|
||||
func deleteBackupKey(
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let (
|
||||
messageBackupKey,
|
||||
@ -159,6 +161,7 @@ final class BackupKeyServiceImpl: BackupKeyService {
|
||||
for: key,
|
||||
localAci: localIdentifiers.aci,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
try await deleteBackupKey(
|
||||
@ -235,18 +238,18 @@ private extension TSRequest {
|
||||
#if TESTABLE_BUILD
|
||||
|
||||
class MockBackupKeyService: BackupKeyService {
|
||||
func registerBackupKey(localIdentifiers: LocalIdentifiers, auth: ChatServiceAuth) async throws {
|
||||
func registerBackupKey(localIdentifiers: LocalIdentifiers, auth: ChatServiceAuth, logger: PrefixedLogger) async throws {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
var deleteBackupKeyMock: (() async throws -> Void)?
|
||||
func deleteBackupKey(localIdentifiers: LocalIdentifiers, auth: ChatServiceAuth) async throws {
|
||||
func deleteBackupKey(localIdentifiers: LocalIdentifiers, auth: ChatServiceAuth, logger: PrefixedLogger) async throws {
|
||||
if let deleteBackupKeyMock {
|
||||
return try await deleteBackupKeyMock()
|
||||
}
|
||||
}
|
||||
|
||||
func deleteBackupKey(localIdentifiers: LocalIdentifiers, backupAuth: BackupServiceAuth) async throws {
|
||||
func deleteBackupKey(localIdentifiers: LocalIdentifiers, backupAuth: BackupServiceAuth, logger: PrefixedLogger) async throws {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,6 +119,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
private let db: any DB
|
||||
private let deviceSleepManager: (any DeviceSleepManager)?
|
||||
private let kvStore: KeyValueStore
|
||||
private let logger: PrefixedLogger
|
||||
private let messagePipelineSupervisor: MessagePipelineSupervisor
|
||||
private let networkManager: NetworkManager
|
||||
private let tsAccountManager: TSAccountManager
|
||||
@ -143,6 +144,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
self.db = db
|
||||
self.deviceSleepManager = deviceSleepManager
|
||||
self.kvStore = KeyValueStore(collection: "LinkAndSyncManagerImpl")
|
||||
self.logger = PrefixedLogger(prefix: "[LNS]")
|
||||
self.messagePipelineSupervisor = messagePipelineSupervisor
|
||||
self.networkManager = networkManager
|
||||
self.tsAccountManager = tsAccountManager
|
||||
@ -166,7 +168,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
registeredState = try tsAccountManager.registeredStateWithMaybeSneakyTransaction()
|
||||
} catch {
|
||||
// TODO: Throw an error to indicate this failed because we're not registered.
|
||||
Logger.warn("Couldn't wait for linking because we're no longer registered")
|
||||
logger.warn("Couldn't wait for linking because we're no longer registered")
|
||||
return
|
||||
}
|
||||
owsPrecondition(registeredState.isPrimary, "Can't wait for linking unless we're a primary")
|
||||
@ -182,11 +184,11 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
do {
|
||||
try checkCancelledOrAppBackgrounded()
|
||||
} catch {
|
||||
Logger.info("Cancelled!")
|
||||
logger.info("Cancelled!")
|
||||
throw .cancelled(linkedDeviceId: nil)
|
||||
}
|
||||
|
||||
Logger.info("Beginning link'n'sync")
|
||||
logger.info("Beginning link'n'sync")
|
||||
|
||||
let waitForLinkResponse = try await waitForDeviceToLink(
|
||||
tokenId: tokenId,
|
||||
@ -282,10 +284,10 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
switch restoreState {
|
||||
case .finalized:
|
||||
// Assume this was from a link'n'sync that was subsequently interrupted
|
||||
Logger.info("Skipping link'n'sync; already restored from backup")
|
||||
logger.info("Skipping link'n'sync; already restored from backup")
|
||||
return
|
||||
case .unfinalized:
|
||||
Logger.info("Finalizing unfinished link'n'sync")
|
||||
logger.info("Finalizing unfinished link'n'sync")
|
||||
let blockObject = DeviceSleepBlockObject(blockReason: Constants.sleepBlockingDescription)
|
||||
deviceSleepManager?.addBlock(blockObject: blockObject)
|
||||
defer { deviceSleepManager?.removeBlock(blockObject: blockObject) }
|
||||
@ -301,7 +303,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
} catch let error as CancellationError {
|
||||
throw error
|
||||
} catch {
|
||||
owsFailDebug("Unable to finalize link'n'sync backup restore: \(error)")
|
||||
owsFailDebug("Unable to finalize link'n'sync backup restore: \(error)", logger: logger)
|
||||
throw SecondaryLinkNSyncError.errorRestoringBackup
|
||||
}
|
||||
case .none:
|
||||
@ -350,6 +352,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
localIdentifiers: localIdentifiers,
|
||||
ephemeralBackupKey: ephemeralBackupKey,
|
||||
progress: progress.child(for: .importingBackup),
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
@ -375,7 +378,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
private func _waitForDeviceToLink(
|
||||
tokenId: DeviceProvisioningTokenId,
|
||||
) async throws(PrimaryLinkNSyncError) -> Requests.WaitForDeviceToLinkResponse {
|
||||
Logger.info("Waiting for device to link")
|
||||
logger.info("Waiting for device to link")
|
||||
var numNetworkErrors = 0
|
||||
whileLoop: while true {
|
||||
do {
|
||||
@ -384,7 +387,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
)
|
||||
switch Requests.WaitForDeviceToLinkResponseCodes(rawValue: response.responseStatusCode) {
|
||||
case .success:
|
||||
Logger.info("Device linked!")
|
||||
logger.info("Device linked!")
|
||||
guard
|
||||
let data = response.responseBodyData,
|
||||
let response = try? JSONDecoder().decode(
|
||||
@ -408,7 +411,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
// retry
|
||||
continue whileLoop
|
||||
case nil:
|
||||
owsFailDebug("Unexpected response")
|
||||
owsFailDebug("Unexpected response", logger: logger)
|
||||
throw PrimaryLinkNSyncError.errorWaitingForLinkedDevice
|
||||
}
|
||||
} catch let error as PrimaryLinkNSyncError {
|
||||
@ -439,13 +442,14 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
localIdentifiers: localIdentifiers,
|
||||
backupPurpose: .linkNsync(ephemeralKey: ephemeralBackupKey.backupKey, aci: localIdentifiers.aci),
|
||||
progress: progress,
|
||||
logger: logger,
|
||||
)
|
||||
return metadata
|
||||
} catch let error {
|
||||
if error is CancellationError {
|
||||
throw .cancelled(linkedDeviceId: waitForDeviceToLinkResponse.id)
|
||||
}
|
||||
owsFailDebug("Unable to generate link'n'sync backup: \(error)")
|
||||
owsFailDebug("Unable to generate link'n'sync backup: \(error)", logger: logger)
|
||||
throw .errorGeneratingBackup
|
||||
}
|
||||
}
|
||||
@ -502,7 +506,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
} catch let error as PrimaryLinkNSyncError {
|
||||
throw error
|
||||
} catch {
|
||||
owsFailDebug("Invalid error!")
|
||||
owsFailDebug("Invalid error!", logger: logger)
|
||||
throw .errorMarkingBackupUploaded(PrimaryLinkNSyncErrorRetryHandler(
|
||||
waitForDeviceToLinkResponse: waitForDeviceToLinkResponse,
|
||||
linkNSyncManager: self,
|
||||
@ -611,7 +615,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
if let error = rawResponse.error {
|
||||
return .error(error)
|
||||
}
|
||||
owsFailDebug("Unexpected server response!")
|
||||
owsFailDebug("Unexpected server response!", logger: logger)
|
||||
return .error(.continueWithoutUpload)
|
||||
case .timeout:
|
||||
let elapsedTime = (MonotonicDate() - startDate).seconds
|
||||
@ -648,6 +652,7 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
ephemeralBackupKey: MessageRootBackupKey,
|
||||
progress: OWSProgressSink,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
do {
|
||||
try await backupArchiveManager.importEncryptedBackup(
|
||||
@ -656,9 +661,10 @@ public class LinkAndSyncManagerImpl: LinkAndSyncManager {
|
||||
isPrimaryDevice: false,
|
||||
source: .linkNsync(ephemeralKey: ephemeralBackupKey.backupKey, aci: localIdentifiers.aci),
|
||||
progress: progress,
|
||||
logger: logger,
|
||||
)
|
||||
} catch {
|
||||
Logger.warn("Unable to restore link'n'sync backup: \(error)")
|
||||
logger.warn("Unable to restore link'n'sync backup: \(error)")
|
||||
switch error {
|
||||
case BackupImportError.unsupportedVersion:
|
||||
throw error
|
||||
|
||||
@ -795,7 +795,11 @@ public class AttachmentDownloadManagerImpl: AttachmentDownloadManager {
|
||||
let mediaName = attachment.mediaName,
|
||||
let backupKey = db.read(block: { accountKeyStore.getMediaRootBackupKey(tx: $0) }),
|
||||
let encryptionMetadata = buildCdnEncryptionMetadata(mediaName: mediaName, backupKey: backupKey, type: .outerLayerFullsizeOrThumbnail),
|
||||
let cdnCredential = await fetchBackupCdnReadCredential(for: cdnNumber, backupKey: backupKey)
|
||||
let cdnCredential = await fetchBackupCdnReadCredential(
|
||||
for: cdnNumber,
|
||||
backupKey: backupKey,
|
||||
logger: PrefixedLogger(prefix: "[Backups]"),
|
||||
)
|
||||
else {
|
||||
return .unretryableError(OWSAssertionError("Attempting to download an attachment without cdn info"))
|
||||
}
|
||||
@ -833,7 +837,11 @@ public class AttachmentDownloadManagerImpl: AttachmentDownloadManager {
|
||||
backupKey: backupKey,
|
||||
type: .transitTierThumbnail,
|
||||
),
|
||||
let cdnReadCredential = await fetchBackupCdnReadCredential(for: cdnNumber, backupKey: backupKey)
|
||||
let cdnReadCredential = await fetchBackupCdnReadCredential(
|
||||
for: cdnNumber,
|
||||
backupKey: backupKey,
|
||||
logger: PrefixedLogger(prefix: "[Backups]"),
|
||||
)
|
||||
else {
|
||||
return .unretryableError(OWSAssertionError("Attempting to download an attachment without cdn info"))
|
||||
}
|
||||
@ -1016,6 +1024,7 @@ public class AttachmentDownloadManagerImpl: AttachmentDownloadManager {
|
||||
private func fetchBackupCdnReadCredential(
|
||||
for cdn: UInt32,
|
||||
backupKey: MediaRootBackupKey,
|
||||
logger: PrefixedLogger,
|
||||
) async -> MediaTierReadCredential? {
|
||||
guard
|
||||
let localAci = db.read(block: { tx in
|
||||
@ -1031,6 +1040,7 @@ public class AttachmentDownloadManagerImpl: AttachmentDownloadManager {
|
||||
for: backupKey,
|
||||
localAci: localAci,
|
||||
auth: .implicit(),
|
||||
logger: logger,
|
||||
)
|
||||
else {
|
||||
owsFailDebug("Failed to fetch backup credential")
|
||||
@ -1041,6 +1051,7 @@ public class AttachmentDownloadManagerImpl: AttachmentDownloadManager {
|
||||
let metadata = try? await backupRequestManager.fetchMediaTierCdnRequestMetadata(
|
||||
cdn: Int32(cdn),
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
else {
|
||||
owsFailDebug("Failed to fetch backup credential")
|
||||
|
||||
@ -12,10 +12,16 @@ extension OWSRequestFactory {
|
||||
from fromRedemptionSeconds: UInt64,
|
||||
to toRedemptionSeconds: UInt64,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
owsAssertDebug(fromRedemptionSeconds > 0)
|
||||
owsAssertDebug(toRedemptionSeconds > 0)
|
||||
var request = TSRequest(url: URL(string: "v1/archives/auth?redemptionStartSeconds=\(fromRedemptionSeconds)&redemptionEndSeconds=\(toRedemptionSeconds)")!, method: "GET", parameters: nil)
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/auth?redemptionStartSeconds=\(fromRedemptionSeconds)&redemptionEndSeconds=\(toRedemptionSeconds)")!,
|
||||
method: "GET",
|
||||
parameters: nil,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .identified(auth)
|
||||
return request
|
||||
}
|
||||
@ -24,6 +30,7 @@ extension OWSRequestFactory {
|
||||
public static func backupUploadFormRequest(
|
||||
backupByteLength: UInt32,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var urlComps = URLComponents(string: "v1/archives/upload/form")!
|
||||
urlComps.queryItems = [URLQueryItem(name: "uploadLength", value: "\(backupByteLength)")]
|
||||
@ -31,6 +38,7 @@ extension OWSRequestFactory {
|
||||
url: urlComps.url!,
|
||||
method: "GET",
|
||||
parameters: nil,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
@ -38,7 +46,7 @@ extension OWSRequestFactory {
|
||||
|
||||
public static func backupMediaUploadFormRequest(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger? = nil,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/media/upload/form")!,
|
||||
@ -50,31 +58,44 @@ extension OWSRequestFactory {
|
||||
return request
|
||||
}
|
||||
|
||||
public static func backupInfoRequest(auth: BackupServiceAuth) -> TSRequest {
|
||||
public static func backupInfoRequest(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives")!,
|
||||
method: "GET",
|
||||
parameters: nil,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
}
|
||||
|
||||
public static func backupRefreshInfoRequest(auth: BackupServiceAuth) -> TSRequest {
|
||||
public static func backupRefreshInfoRequest(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives")!,
|
||||
method: "PUT",
|
||||
parameters: nil,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
}
|
||||
|
||||
public static func fetchBackupCDNCredentials(auth: BackupServiceAuth, cdn: Int32) -> TSRequest {
|
||||
public static func fetchBackupCDNCredentials(
|
||||
auth: BackupServiceAuth,
|
||||
cdn: Int32,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/auth/read?cdn=\(cdn)")!,
|
||||
method: "GET",
|
||||
parameters: nil,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
@ -83,7 +104,7 @@ extension OWSRequestFactory {
|
||||
public static func copyToMediaTier(
|
||||
auth: BackupServiceAuth,
|
||||
item: BackupArchive.Request.MediaItem,
|
||||
logger: PrefixedLogger? = nil,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/media")!,
|
||||
@ -98,12 +119,14 @@ extension OWSRequestFactory {
|
||||
public static func archiveMedia(
|
||||
auth: BackupServiceAuth,
|
||||
items: [BackupArchive.Request.MediaItem],
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
let parameters: [String: Any] = ["items": items.map(\.asParameters)]
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/media/batch")!,
|
||||
method: "PUT",
|
||||
parameters: parameters,
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
@ -113,6 +136,7 @@ extension OWSRequestFactory {
|
||||
auth: BackupServiceAuth,
|
||||
cursor: String?,
|
||||
limit: UInt32?,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var urlComponents = URLComponents(string: "v1/archives/media")!
|
||||
var queryItems = [URLQueryItem]()
|
||||
@ -129,6 +153,7 @@ extension OWSRequestFactory {
|
||||
url: urlComponents.url!,
|
||||
method: "GET",
|
||||
parameters: [:],
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
@ -137,11 +162,13 @@ extension OWSRequestFactory {
|
||||
public static func deleteMedia(
|
||||
auth: BackupServiceAuth,
|
||||
objects: [BackupArchive.Request.DeleteMediaTarget],
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/media/delete")!,
|
||||
method: "POST",
|
||||
parameters: ["mediaToDelete": NSArray(array: objects.map(\.asParameters))],
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
@ -149,21 +176,25 @@ extension OWSRequestFactory {
|
||||
|
||||
public static func redeemReceipt(
|
||||
receiptCredentialPresentation: Data,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
return TSRequest(
|
||||
url: URL(string: "v1/archives/redeem-receipt")!,
|
||||
method: "POST",
|
||||
parameters: ["receiptCredentialPresentation": receiptCredentialPresentation.base64EncodedString()],
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
public static func fetchSVRBAuthCredential(
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
var request = TSRequest(
|
||||
url: URL(string: "v1/archives/auth/svrb")!,
|
||||
method: "GET",
|
||||
parameters: [:],
|
||||
logger: logger,
|
||||
)
|
||||
request.auth = .backup(auth)
|
||||
return request
|
||||
|
||||
@ -298,6 +298,7 @@ public enum RegistrationRequestFactory {
|
||||
e164: E164,
|
||||
reglockToken: String?,
|
||||
pniChangeNumberParameters: PniDistribution.Parameters,
|
||||
logger: PrefixedLogger,
|
||||
) -> TSRequest {
|
||||
let urlPathComponents = URLPathComponents(
|
||||
["v2", "accounts", "number"],
|
||||
|
||||
@ -29,6 +29,7 @@ public protocol BackupAuthCredentialManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth
|
||||
|
||||
/// Fetch `BackupServiceAuth`. Callers may assume that tier of the returned
|
||||
@ -45,12 +46,14 @@ public protocol BackupAuthCredentialManager {
|
||||
localAci: Aci,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth
|
||||
|
||||
func fetchSVRBAuthCredential(
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth
|
||||
}
|
||||
|
||||
@ -91,12 +94,14 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
return try await serialTaskQueue.run {
|
||||
try await _fetchBackupServiceAuthForRegistration(
|
||||
key: key,
|
||||
localAci: localAci,
|
||||
chatServiceAuth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -105,13 +110,15 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
try await waitForAuthCredentialDependency(.registerBackupId(localAci: localAci, auth: auth))
|
||||
try await waitForAuthCredentialDependency(.registerBackupId(localAci: localAci, auth: auth), logger: logger)
|
||||
|
||||
let (_, backupServiceAuth) = try await fetchNewAuthCredentials(
|
||||
localAci: localAci,
|
||||
key: key,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
return backupServiceAuth
|
||||
@ -124,6 +131,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
localAci: Aci,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
return try await serialTaskQueue.run {
|
||||
try await _fetchBackupServiceAuth(
|
||||
@ -131,6 +139,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
localAci: localAci,
|
||||
chatServiceAuth: auth,
|
||||
forceRefreshUnlessCachedPaidCredential: forceRefreshUnlessCachedPaidCredential,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -140,17 +149,19 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
localAci: Aci,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
|
||||
try await waitForAuthCredentialDependency(.registerBackupId(localAci: localAci, auth: auth))
|
||||
try await waitForAuthCredentialDependency(.renewBackupEntitlementForTestFlight)
|
||||
try await waitForAuthCredentialDependency(.redeemBackupSubscriptionViaIAP)
|
||||
try await waitForAuthCredentialDependency(.registerBackupId(localAci: localAci, auth: auth), logger: logger)
|
||||
try await waitForAuthCredentialDependency(.renewBackupEntitlementForTestFlight, logger: logger)
|
||||
try await waitForAuthCredentialDependency(.redeemBackupSubscriptionViaIAP, logger: logger)
|
||||
|
||||
if
|
||||
let cachedServiceAuth = readCachedServiceAuth(
|
||||
key: key,
|
||||
localAci: localAci,
|
||||
forceRefreshUnlessCachedPaidCredential: forceRefreshUnlessCachedPaidCredential,
|
||||
logger: logger,
|
||||
)
|
||||
{
|
||||
return cachedServiceAuth
|
||||
@ -159,13 +170,14 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
let (
|
||||
authCredentialsOfKeyType,
|
||||
backupServiceAuth,
|
||||
) = try await fetchNewAuthCredentials(localAci: localAci, key: key, auth: auth)
|
||||
) = try await fetchNewAuthCredentials(localAci: localAci, key: key, auth: auth, logger: logger)
|
||||
|
||||
await db.awaitableWrite { tx in
|
||||
cacheReceivedAuthCredentials(
|
||||
authCredentialsOfKeyType,
|
||||
credentialType: key.credentialType,
|
||||
tx: tx,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
|
||||
@ -178,12 +190,14 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
try await serialTaskQueue.run {
|
||||
try await _fetchSVRBAuthCredential(
|
||||
key: key,
|
||||
chatServiceAuth: auth,
|
||||
forceRefresh: forceRefresh,
|
||||
logger: logger,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -192,6 +206,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
key: MessageRootBackupKey,
|
||||
chatServiceAuth auth: ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
let now = dateProvider()
|
||||
|
||||
@ -209,12 +224,13 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
localAci: key.aci,
|
||||
chatServiceAuth: auth,
|
||||
forceRefreshUnlessCachedPaidCredential: false,
|
||||
logger: logger,
|
||||
)
|
||||
let response = try await networkManager.asyncRequest(
|
||||
OWSRequestFactory.fetchSVRBAuthCredential(auth: backupServiceAuth),
|
||||
OWSRequestFactory.fetchSVRBAuthCredential(auth: backupServiceAuth, logger: logger),
|
||||
)
|
||||
guard let bodyData = response.responseBodyData else {
|
||||
throw OWSAssertionError("Missing body data")
|
||||
throw OWSAssertionError("Missing body data", logger: logger)
|
||||
}
|
||||
let receivedSVRBAuthCredential = try JSONDecoder().decode(ReceivedSVRBAuthCredentials.self, from: bodyData)
|
||||
let svrBAuth = LibSignalClient.Auth(
|
||||
@ -242,6 +258,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
|
||||
private func waitForAuthCredentialDependency(
|
||||
_ dependency: BackupAuthCredentialDependency,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
let label: String
|
||||
let block: () async throws -> Void
|
||||
@ -269,6 +286,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
try await self.backupIdService.registerBackupIDIfNecessary(
|
||||
localAci: localAci,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -293,7 +311,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
do {
|
||||
try await block()
|
||||
} catch {
|
||||
Logger.warn("Failed auth credential dependency step: \(label)! \(error)")
|
||||
logger.warn("Failed auth credential dependency step: \(label)! \(error)")
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@ -302,6 +320,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
|
||||
private func readCachedAuthCredential(
|
||||
key: BackupKeyMaterial,
|
||||
logger: PrefixedLogger,
|
||||
) -> BackupAuthCredential? {
|
||||
return db.read { tx -> BackupAuthCredential? in
|
||||
let redemptionTime = dateProvider().epochSecondsSinceStartOfToday
|
||||
@ -325,7 +344,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
tx: tx,
|
||||
)
|
||||
else {
|
||||
owsFailDebug("Unexpectedly missing auth credential for now, but had one for a future date!")
|
||||
owsFailDebug("Unexpectedly missing auth credential for now, but had one for a future date!", logger: logger)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -338,8 +357,9 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) -> BackupServiceAuth? {
|
||||
guard let cachedAuthCredential = readCachedAuthCredential(key: key) else {
|
||||
guard let cachedAuthCredential = readCachedAuthCredential(key: key, logger: logger) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -371,9 +391,10 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
_ receivedAuthCredentials: [ReceivedBackupAuthCredential],
|
||||
credentialType: BackupAuthCredentialType,
|
||||
tx: DBWriteTransaction,
|
||||
logger: PrefixedLogger,
|
||||
) {
|
||||
if receivedAuthCredentials.isEmpty {
|
||||
owsFailDebug("Attempting to cache credentials, but none present!")
|
||||
owsFailDebug("Attempting to cache credentials, but none present!", logger: logger)
|
||||
return
|
||||
}
|
||||
|
||||
@ -393,6 +414,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
localAci: Aci,
|
||||
key: BackupKeyMaterial,
|
||||
auth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> ([ReceivedBackupAuthCredential], first: BackupServiceAuth) {
|
||||
|
||||
// Always fetch 7d worth of credentials at once.
|
||||
@ -404,6 +426,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
from: startTimestampSeconds,
|
||||
to: endTimestampSeconds,
|
||||
auth: auth,
|
||||
logger: logger,
|
||||
)
|
||||
|
||||
let response: HTTPResponse
|
||||
@ -417,7 +440,7 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
}
|
||||
}
|
||||
guard let data = response.responseBodyData else {
|
||||
throw OWSAssertionError("Missing response body data")
|
||||
throw OWSAssertionError("Missing response body data", logger: logger)
|
||||
}
|
||||
|
||||
let authCredentialRepsonse = try JSONDecoder().decode(BackupCredentialResponse.self, from: data)
|
||||
@ -426,14 +449,14 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
let authCredentialsOfKeyType = authCredentialRepsonse.credentials[key.credentialType],
|
||||
!authCredentialsOfKeyType.isEmpty
|
||||
else {
|
||||
throw OWSAssertionError("Missing auth credentials of type \(key.credentialType) in response!")
|
||||
throw OWSAssertionError("Missing auth credentials of type \(key.credentialType) in response!", logger: logger)
|
||||
}
|
||||
|
||||
let backupServerPublicParams = try GenericServerPublicParams(contents: TSConstants.backupServerPublicParams)
|
||||
|
||||
let receivedAuthCredentials = try authCredentialsOfKeyType.compactMap { credential -> ReceivedBackupAuthCredential? in
|
||||
guard timestampRange.contains(credential.redemptionTime) else {
|
||||
owsFailDebug("Dropping backup credential outside of requested time range! \(key.credentialType)")
|
||||
owsFailDebug("Dropping backup credential outside of requested time range! \(key.credentialType)", logger: logger)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -456,13 +479,13 @@ class BackupAuthCredentialManagerImpl: BackupAuthCredentialManager {
|
||||
credential: receivedCredential,
|
||||
)
|
||||
} catch {
|
||||
Logger.warn("Error creating credential! \(error)")
|
||||
logger.warn("Error creating credential! \(error)")
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
guard let firstAuthCredential = receivedAuthCredentials.first?.credential else {
|
||||
throw OWSAssertionError("Unexpectedly missing auth credentials after parsing!")
|
||||
throw OWSAssertionError("Unexpectedly missing auth credentials after parsing!", logger: logger)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -94,6 +94,7 @@ class _AttachmentUploadManager_BackupRequestManagerMock: BackupRequestManager {
|
||||
key: BackupKeyMaterial,
|
||||
localAci: Aci,
|
||||
chatServiceAuth: ChatServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
fatalError("Unimplemented for tests")
|
||||
}
|
||||
@ -103,6 +104,7 @@ class _AttachmentUploadManager_BackupRequestManagerMock: BackupRequestManager {
|
||||
localAci: Aci,
|
||||
auth: ChatServiceAuth,
|
||||
forceRefreshUnlessCachedPaidCredential: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupServiceAuth {
|
||||
fatalError("Unimplemented for tests")
|
||||
}
|
||||
@ -112,26 +114,27 @@ class _AttachmentUploadManager_BackupRequestManagerMock: BackupRequestManager {
|
||||
func fetchBackupUploadForm(
|
||||
backupByteLength: UInt32,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> Upload.Form {
|
||||
fatalError("Unimplemented for tests")
|
||||
}
|
||||
|
||||
func fetchBackupMediaAttachmentUploadForm(auth: BackupServiceAuth, logger: PrefixedLogger? = nil) async throws -> Upload.Form {
|
||||
func fetchBackupMediaAttachmentUploadForm(auth: BackupServiceAuth, logger: PrefixedLogger) async throws -> Upload.Form {
|
||||
fatalError("Unimplemented for tests")
|
||||
}
|
||||
|
||||
func fetchMediaTierCdnRequestMetadata(cdn: Int32, auth: BackupServiceAuth) async throws -> MediaTierReadCredential {
|
||||
func fetchMediaTierCdnRequestMetadata(cdn: Int32, auth: BackupServiceAuth, logger: PrefixedLogger) async throws -> MediaTierReadCredential {
|
||||
fatalError("Unimplemented for tests")
|
||||
}
|
||||
|
||||
func fetchBackupRequestMetadata(auth: BackupServiceAuth) async throws -> BackupReadCredential {
|
||||
func fetchBackupRequestMetadata(auth: BackupServiceAuth, logger: PrefixedLogger) async throws -> BackupReadCredential {
|
||||
fatalError("Unimplemented for tests")
|
||||
}
|
||||
|
||||
func copyToMediaTier(
|
||||
item: BackupArchive.Request.MediaItem,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger? = nil,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> UInt32 {
|
||||
return 3
|
||||
}
|
||||
@ -139,6 +142,7 @@ class _AttachmentUploadManager_BackupRequestManagerMock: BackupRequestManager {
|
||||
func copyToMediaTier(
|
||||
items: [BackupArchive.Request.MediaItem],
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> [BackupArchive.Response.BatchedBackupMediaResult] {
|
||||
return []
|
||||
}
|
||||
@ -147,6 +151,7 @@ class _AttachmentUploadManager_BackupRequestManagerMock: BackupRequestManager {
|
||||
cursor: String?,
|
||||
limit: UInt32?,
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> BackupArchive.Response.ListMediaResult {
|
||||
fatalError("Unimplemented for tests")
|
||||
}
|
||||
@ -154,16 +159,18 @@ class _AttachmentUploadManager_BackupRequestManagerMock: BackupRequestManager {
|
||||
func deleteMediaObjects(
|
||||
objects: [BackupArchive.Request.DeleteMediaTarget],
|
||||
auth: BackupServiceAuth,
|
||||
logger: PrefixedLogger,
|
||||
) async throws {
|
||||
}
|
||||
|
||||
func redeemReceipt(receiptCredentialPresentation: Data) async throws {
|
||||
func redeemReceipt(receiptCredentialPresentation: Data, logger: PrefixedLogger) async throws {
|
||||
}
|
||||
|
||||
func fetchSVRBAuthCredential(
|
||||
key: SignalServiceKit.MessageRootBackupKey,
|
||||
chatServiceAuth auth: SignalServiceKit.ChatServiceAuth,
|
||||
forceRefresh: Bool,
|
||||
logger: PrefixedLogger,
|
||||
) async throws -> LibSignalClient.Auth {
|
||||
return LibSignalClient.Auth(username: "", password: "")
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user