Merge branch 'mkirk/sharing-vs-sn'

pull/1/head
sdkjfhsdkjhfsdlkjhfsdf 7 years ago
commit eefd66e4a6

@ -54,10 +54,6 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(flippedKey.length == currentKey.length); OWSAssert(flippedKey.length == currentKey.length);
[identityManager saveRemoteIdentity:flippedKey recipientId:recipientId]; [identityManager saveRemoteIdentity:flippedKey recipientId:recipientId];
}], }],
[OWSTableItem itemWithTitle:@"Set Verification State"
actionBlock:^{
[DebugUISessionState presentVerificationStatePickerForContactThread:thread];
}],
[OWSTableItem itemWithTitle:@"Delete all sessions" [OWSTableItem itemWithTitle:@"Delete all sessions"
actionBlock:^{ actionBlock:^{
dispatch_async([OWSDispatch sessionStoreQueue], ^{ dispatch_async([OWSDispatch sessionStoreQueue], ^{
@ -81,56 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
]]; ]];
} }
+ (void)presentVerificationStatePickerForContactThread:(TSContactThread *)contactThread
{
DDLogError(@"%@ Choosing verification state.", self.logTag);
NSString *title = [NSString stringWithFormat:@"Choose verification state for %@", contactThread.name];
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
NSString *recipientId = [contactThread contactIdentifier];
OWSIdentityManager *identityManger = [OWSIdentityManager sharedManager];
[alertController addAction:[UIAlertAction actionWithTitle:@"Default"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
NSData *identityKey =
[identityManger identityKeyForRecipientId:recipientId];
[[OWSIdentityManager sharedManager]
setVerificationState:OWSVerificationStateDefault
identityKey:identityKey
recipientId:recipientId
isUserInitiatedChange:NO];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"Verified"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
NSData *identityKey =
[identityManger identityKeyForRecipientId:recipientId];
[[OWSIdentityManager sharedManager]
setVerificationState:OWSVerificationStateVerified
identityKey:identityKey
recipientId:recipientId
isUserInitiatedChange:NO];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"No Longer Verified"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
NSData *identityKey =
[identityManger identityKeyForRecipientId:recipientId];
[[OWSIdentityManager sharedManager]
setVerificationState:OWSVerificationStateNoLongerVerified
identityKey:identityKey
recipientId:recipientId
isUserInitiatedChange:NO];
}]];
[[UIApplication sharedApplication].frontmostViewController presentViewController:alertController
animated:YES
completion:nil];
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -1540,6 +1540,9 @@
/* action sheet item */ /* action sheet item */
"SHARE_ACTION_TWEET" = "Twitter"; "SHARE_ACTION_TWEET" = "Twitter";
/* alert body when sharing file failed because of untrusted/changed identity keys */
"SHARE_EXTENSION_FAILED_SENDING_BECAUSE_UNTRUSTED_IDENTITY_FORMAT" = "Your safety number with %@ has recently changed. You may wish to verify it in the main app before resending.";
/* Indicates that the share extension is still loading. */ /* Indicates that the share extension is still loading. */
"SHARE_EXTENSION_LOADING" = "Loading..."; "SHARE_EXTENSION_LOADING" = "Loading...";

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
import Foundation import Foundation
@ -17,6 +17,12 @@ public class AttachmentApprovalViewController: OWSViewController, CaptioningTool
let TAG = "[AttachmentApprovalViewController]" let TAG = "[AttachmentApprovalViewController]"
weak var delegate: AttachmentApprovalViewControllerDelegate? weak var delegate: AttachmentApprovalViewControllerDelegate?
// We sometimes shrink the attachment view so that it remains somewhat visible
// when the keyboard is presented.
enum AttachmentViewScale {
case fullsize, compact
}
// MARK: Properties // MARK: Properties
let attachment: SignalAttachment let attachment: SignalAttachment
@ -206,11 +212,11 @@ public class AttachmentApprovalViewController: OWSViewController, CaptioningTool
// MARK: CaptioningToolbarDelegate // MARK: CaptioningToolbarDelegate
func captioningToolbarDidBeginEditing(_ captioningToolbar: CaptioningToolbar) { func captioningToolbarDidBeginEditing(_ captioningToolbar: CaptioningToolbar) {
self.shouldShrinkAttachment = true self.scaleAttachmentView(.compact)
} }
func captioningToolbarDidEndEditing(_ captioningToolbar: CaptioningToolbar) { func captioningToolbarDidEndEditing(_ captioningToolbar: CaptioningToolbar) {
self.shouldShrinkAttachment = false self.scaleAttachmentView(.fullsize)
} }
func captioningToolbarDidTapSend(_ captioningToolbar: CaptioningToolbar, captionText: String?) { func captioningToolbarDidTapSend(_ captioningToolbar: CaptioningToolbar, captionText: String?) {
@ -231,36 +237,49 @@ public class AttachmentApprovalViewController: OWSViewController, CaptioningTool
// Toolbar flickers in and out if there are errors // Toolbar flickers in and out if there are errors
// and remains visible momentarily after share extension is dismissed. // and remains visible momentarily after share extension is dismissed.
// It's easiest to just hide it at this point since we're done with it. // It's easiest to just hide it at this point since we're done with it.
self.bottomToolbar.isUserInteractionEnabled = false shouldAllowAttachmentViewResizing = false
self.bottomToolbar.isHidden = true bottomToolbar.isUserInteractionEnabled = false
bottomToolbar.isHidden = true
attachment.captionText = captionText attachment.captionText = captionText
self.delegate?.attachmentApproval(self, didApproveAttachment: attachment) delegate?.attachmentApproval(self, didApproveAttachment: attachment)
} }
// When the keyboard is popped, it can obscure the attachment view. // When the keyboard is popped, it can obscure the attachment view.
private var shouldShrinkAttachment: Bool = false { // so we sometimes allow resizing the attachment.
didSet { private var shouldAllowAttachmentViewResizing: Bool = true
private func scaleAttachmentView(_ fit: AttachmentViewScale) {
guard shouldAllowAttachmentViewResizing else {
if self.scrollView.transform != CGAffineTransform.identity {
UIView.animate(withDuration: 0.2) {
self.scrollView.transform = CGAffineTransform.identity
}
}
return
}
switch fit {
case .fullsize:
UIView.animate(withDuration: 0.2) {
self.scrollView.transform = CGAffineTransform.identity
}
case .compact:
UIView.animate(withDuration: 0.2) { UIView.animate(withDuration: 0.2) {
if self.shouldShrinkAttachment { let kScaleFactor: CGFloat = 0.7
let kScaleFactor: CGFloat = 0.7 let scale = CGAffineTransform(scaleX: kScaleFactor, y: kScaleFactor)
let scale = CGAffineTransform(scaleX: kScaleFactor, y: kScaleFactor)
let originalHeight = self.scrollView.bounds.size.height let originalHeight = self.scrollView.bounds.size.height
// Position the new scaled item to be centered with respect // Position the new scaled item to be centered with respect
// to it's new size. // to it's new size.
let heightDelta = originalHeight * (1 - kScaleFactor) let heightDelta = originalHeight * (1 - kScaleFactor)
let translate = CGAffineTransform(translationX: 0, y: -heightDelta / 2) let translate = CGAffineTransform(translationX: 0, y: -heightDelta / 2)
self.scrollView.transform = scale.concatenating(translate) self.scrollView.transform = scale.concatenating(translate)
} else {
self.scrollView.transform = CGAffineTransform.identity
}
} }
} }
} }
} }
extension AttachmentApprovalViewController: UIScrollViewDelegate { extension AttachmentApprovalViewController: UIScrollViewDelegate {

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "SharingThreadPickerViewController.h" #import "SharingThreadPickerViewController.h"
@ -11,6 +11,8 @@
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
#import "UIView+OWS.h" #import "UIView+OWS.h"
#import <SignalMessaging/SignalMessaging-Swift.h> #import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/OWSDispatch.h>
#import <SignalServiceKit/OWSError.h>
#import <SignalServiceKit/OWSMessageSender.h> #import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/TSThread.h> #import <SignalServiceKit/TSThread.h>
@ -124,26 +126,6 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(thread); OWSAssert(thread);
self.thread = thread; self.thread = thread;
__weak typeof(self) weakSelf = self;
// FIXME SHARINGEXTENSION
// Handling safety number changes brings in a lot of machinery.
// How do we want to handle this?
// e.g. fingerprint scanning, etc. in the SAE or just redirect the user to the main app?
// BOOL didShowSNAlert =
// [SafetyNumberConfirmationAlert presentAlertIfNecessaryWithRecipientIds:thread.recipientIdentifiers
// confirmationText:[SafetyNumberStrings
// confirmSendButton]
// contactsManager:self.contactsManager
// completion:^(BOOL didConfirm) {
// if (didConfirm) {
// [weakSelf threadWasSelected:thread];
// }
// }];
// if (didShowSNAlert) {
// return;
// }
AttachmentApprovalViewController *approvalVC = AttachmentApprovalViewController *approvalVC =
[[AttachmentApprovalViewController alloc] initWithAttachment:self.attachment delegate:self]; [[AttachmentApprovalViewController alloc] initWithAttachment:self.attachment delegate:self];
@ -211,7 +193,8 @@ NS_ASSUME_NONNULL_BEGIN
} }
#endif #endif
void (^sendCompletion)(NSError *_Nullable) = ^(NSError *_Nullable error) { void (^sendCompletion)(NSError *_Nullable, TSOutgoingMessage *message) = ^(
NSError *_Nullable error, TSOutgoingMessage *message) {
AssertIsOnMainThread(); AssertIsOnMainThread();
if (error) { if (error) {
@ -220,7 +203,7 @@ NS_ASSUME_NONNULL_BEGIN
completion:^(void) { completion:^(void) {
DDLogInfo(@"%@ Sending attachment failed with error: %@", self.logTag, error); DDLogInfo(@"%@ Sending attachment failed with error: %@", self.logTag, error);
[self showSendFailureAlertWithError:error [self showSendFailureAlertWithError:error
attachment:attachment message:message
fromViewController:fromViewController]; fromViewController:fromViewController];
}]; }];
return; return;
@ -233,44 +216,183 @@ NS_ASSUME_NONNULL_BEGIN
[fromViewController presentViewController:progressAlert [fromViewController presentViewController:progressAlert
animated:YES animated:YES
completion:^(void) { completion:^(void) {
TSOutgoingMessage *outgoingMessage = __block TSOutgoingMessage *outgoingMessage =
[ThreadUtil sendMessageWithAttachment:self.attachment [ThreadUtil sendMessageWithAttachment:self.attachment
inThread:self.thread inThread:self.thread
messageSender:self.messageSender messageSender:self.messageSender
completion:sendCompletion]; completion:^(NSError *_Nullable error) {
sendCompletion(error, outgoingMessage);
}];
self.outgoingMessage = outgoingMessage; self.outgoingMessage = outgoingMessage;
}]; }];
} }
- (void)showSendFailureAlertWithError:(NSError *)error - (void)showSendFailureAlertWithError:(NSError *)error
attachment:(SignalAttachment *)attachment message:(TSOutgoingMessage *)message
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
OWSAssert(error);
OWSAssert(message);
OWSAssert(fromViewController);
NSString *failureTitle = NSLocalizedString(@"SHARE_EXTENSION_SENDING_FAILURE_TITLE", @"Alert title"); NSString *failureTitle = NSLocalizedString(@"SHARE_EXTENSION_SENDING_FAILURE_TITLE", @"Alert title");
UIAlertController *failureAlert = [UIAlertController alertControllerWithTitle:failureTitle if ([error.domain isEqual:OWSSignalServiceKitErrorDomain] && error.code == OWSErrorCodeUntrustedIdentity) {
message:error.localizedDescription NSString *_Nullable untrustedRecipientId = error.userInfo[OWSErrorRecipientIdentifierKey];
preferredStyle:UIAlertControllerStyleAlert];
NSString *failureFormat = NSLocalizedString(@"SHARE_EXTENSION_FAILED_SENDING_BECAUSE_UNTRUSTED_IDENTITY_FORMAT",
UIAlertAction *failureCancelAction = [UIAlertAction actionWithTitle:[CommonStrings cancelButton] @"alert body when sharing file failed because of untrusted/changed identity keys");
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *_Nonnull action) { NSString *displayName = [self.contactsManager displayNameForPhoneIdentifier:untrustedRecipientId];
[self.shareViewDelegate shareViewWasCancelled]; NSString *failureMessage = [NSString stringWithFormat:failureFormat, displayName];
}];
[failureAlert addAction:failureCancelAction]; UIAlertController *failureAlert = [UIAlertController alertControllerWithTitle:failureTitle
message:failureMessage
UIAlertAction *retryAction = preferredStyle:UIAlertControllerStyleAlert];
[UIAlertAction actionWithTitle:[CommonStrings retryButton]
style:UIAlertActionStyleDefault UIAlertAction *failureCancelAction = [UIAlertAction actionWithTitle:[CommonStrings cancelButton]
handler:^(UIAlertAction *action) { style:UIAlertActionStyleCancel
[self tryToSendAttachment:attachment fromViewController:fromViewController]; handler:^(UIAlertAction *_Nonnull action) {
}]; [self.shareViewDelegate shareViewWasCancelled];
[failureAlert addAction:retryAction]; }];
[failureAlert addAction:failureCancelAction];
[fromViewController presentViewController:failureAlert animated:YES completion:nil];
if (untrustedRecipientId.length > 0) {
UIAlertAction *confirmAction =
[UIAlertAction actionWithTitle:[SafetyNumberStrings confirmSendButton]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self confirmIdentityAndResendMessage:message
recipientId:untrustedRecipientId
fromViewController:fromViewController];
}];
[failureAlert addAction:confirmAction];
} else {
// This shouldn't happen, but if it does we won't offer the user the ability to confirm.
// They may have to return to the main app to accept the identity change.
OWSFail(@"%@ Untrusted recipient error is missing recipient id.", self.logTag);
}
[fromViewController presentViewController:failureAlert animated:YES completion:nil];
} else {
// Non-identity failure, e.g. network offline, rate limit
UIAlertController *failureAlert = [UIAlertController alertControllerWithTitle:failureTitle
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *failureCancelAction = [UIAlertAction actionWithTitle:[CommonStrings cancelButton]
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *_Nonnull action) {
[self.shareViewDelegate shareViewWasCancelled];
}];
[failureAlert addAction:failureCancelAction];
UIAlertAction *retryAction =
[UIAlertAction actionWithTitle:[CommonStrings retryButton]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self resendMessage:message fromViewController:fromViewController];
}];
[failureAlert addAction:retryAction];
[fromViewController presentViewController:failureAlert animated:YES completion:nil];
}
}
- (void)confirmIdentityAndResendMessage:(TSOutgoingMessage *)message
recipientId:(NSString *)recipientId
fromViewController:(UIViewController *)fromViewController
{
AssertIsOnMainThread();
OWSAssert(message);
OWSAssert(recipientId.length > 0);
OWSAssert(fromViewController);
DDLogDebug(@"%@ Confirming identity for recipient: %@", self.logTag, recipientId);
dispatch_async([OWSDispatch sessionStoreQueue], ^(void) {
OWSVerificationState verificationState =
[[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId];
switch (verificationState) {
case OWSVerificationStateVerified: {
OWSFail(@"%@ Shouldn't need to confirm identity if it was already verified", self.logTag);
break;
}
case OWSVerificationStateDefault: {
// If we learned of a changed SN during send, then we've already recorded the new identity
// and there's nothing else we need to do for the resend to succeed.
// We don't want to redundantly set status to "default" because we would create a
// "You marked Alice as unverified" notice, which wouldn't make sense if Alice was never
// marked as "Verified".
DDLogInfo(@"%@ recipient has acceptable verification status. Next send will succeed.", self.logTag);
break;
}
case OWSVerificationStateNoLongerVerified: {
DDLogInfo(@"%@ marked recipient: %@ as default verification status.", self.logTag, recipientId);
NSData *identityKey = [[OWSIdentityManager sharedManager] identityKeyForRecipientId:recipientId];
OWSAssert(identityKey);
[[OWSIdentityManager sharedManager] setVerificationState:OWSVerificationStateDefault
identityKey:identityKey
recipientId:recipientId
isUserInitiatedChange:YES];
break;
}
}
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self resendMessage:message fromViewController:fromViewController];
});
});
}
- (void)resendMessage:(TSOutgoingMessage *)message fromViewController:(UIViewController *)fromViewController
{
AssertIsOnMainThread();
OWSAssert(message);
OWSAssert(fromViewController);
NSString *progressTitle = NSLocalizedString(@"SHARE_EXTENSION_SENDING_IN_PROGRESS_TITLE", @"Alert title");
UIAlertController *progressAlert = [UIAlertController alertControllerWithTitle:progressTitle
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *progressCancelAction = [UIAlertAction actionWithTitle:[CommonStrings cancelButton]
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *_Nonnull action) {
[self.shareViewDelegate shareViewWasCancelled];
}];
[progressAlert addAction:progressCancelAction];
[fromViewController
presentViewController:progressAlert
animated:YES
completion:^(void) {
[self.messageSender enqueueMessage:message
success:^(void) {
DDLogInfo(@"%@ Resending attachment succeeded.", self.logTag);
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.shareViewDelegate shareViewWasCompleted];
});
}
failure:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
[fromViewController
dismissViewControllerAnimated:YES
completion:^(void) {
DDLogInfo(@"%@ Sending attachment failed with error: %@",
self.logTag,
error);
[self showSendFailureAlertWithError:error
message:message
fromViewController:fromViewController];
}];
});
}];
}];
} }
- (void)attachmentUploadProgress:(NSNotification *)notification - (void)attachmentUploadProgress:(NSNotification *)notification

@ -861,7 +861,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
NSString *localizedErrorDescription = NSString *localizedErrorDescription =
[NSString stringWithFormat:localizedErrorDescriptionFormat, [NSString stringWithFormat:localizedErrorDescriptionFormat,
[self.contactsManager displayNameForPhoneIdentifier:recipient.recipientId]]; [self.contactsManager displayNameForPhoneIdentifier:recipient.recipientId]];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeUntrustedIdentityKey, localizedErrorDescription); NSError *error = OWSErrorMakeUntrustedIdentityError(localizedErrorDescription, recipient.recipientId);
// Key will continue to be unaccepted, so no need to retry. It'll only cause us to hit the Pre-Key request // Key will continue to be unaccepted, so no need to retry. It'll only cause us to hit the Pre-Key request
// rate limit // rate limit
@ -869,7 +869,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
// Avoid the "Too many failures with this contact" error rate limiting. // Avoid the "Too many failures with this contact" error rate limiting.
[error setIsFatal:YES]; [error setIsFatal:YES];
PreKeyBundle *newKeyBundle = exception.userInfo[TSInvalidPreKeyBundleKey]; PreKeyBundle *_Nullable newKeyBundle = exception.userInfo[TSInvalidPreKeyBundleKey];
if (newKeyBundle == nil) {
OWSProdFail([OWSAnalyticsEvents messageSenderErrorMissingNewPreKeyBundle]);
failureHandler(error);
return;
}
if (![newKeyBundle isKindOfClass:[PreKeyBundle class]]) { if (![newKeyBundle isKindOfClass:[PreKeyBundle class]]) {
OWSProdFail([OWSAnalyticsEvents messageSenderErrorUnexpectedKeyBundle]); OWSProdFail([OWSAnalyticsEvents messageSenderErrorUnexpectedKeyBundle]);
failureHandler(error); failureHandler(error);

@ -10,6 +10,12 @@ NS_ASSUME_NONNULL_BEGIN
// The code between these markers is code-generated by: // The code between these markers is code-generated by:
// SignalServiceKit/Utilities/extract_analytics_event_names.py // SignalServiceKit/Utilities/extract_analytics_event_names.py
// To add an event, insert your logging event as a string e.g.:
//
// OWSProdFail(@"messageSenderErrorMissingNewPreKeyBundle");
//
// Then run SignalServiceKit/Utilities/extract_analytics_event_names.py, which
// will extract the string into a named method in this class.
#pragma mark - Code Generation Marker #pragma mark - Code Generation Marker
+ (NSString *)accountsErrorRegisterPushTokensFailed; + (NSString *)accountsErrorRegisterPushTokensFailed;
@ -96,6 +102,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSString *)errorUpdateAttributesRequestFailed; + (NSString *)errorUpdateAttributesRequestFailed;
+ (NSString *)messageSenderErrorMissingNewPreKeyBundle;
+ (NSString *)messageManagerErrorCallMessageNoActionablePayload; + (NSString *)messageManagerErrorCallMessageNoActionablePayload;
+ (NSString *)messageManagerErrorCorruptMessage; + (NSString *)messageManagerErrorCorruptMessage;

@ -222,6 +222,11 @@ NS_ASSUME_NONNULL_BEGIN
return @"error_update_attributes_request_failed"; return @"error_update_attributes_request_failed";
} }
+ (NSString *)messageSenderErrorMissingNewPreKeyBundle
{
return @"messageSenderErrorMissingNewPreKeyBundle";
}
+ (NSString *)messageManagerErrorCallMessageNoActionablePayload + (NSString *)messageManagerErrorCallMessageNoActionablePayload
{ {
return @"message_manager_error_call_message_no_actionable_payload"; return @"message_manager_error_call_message_no_actionable_payload";

@ -13,7 +13,7 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) {
OWSErrorCodeFailedToEncodeJson = 14, OWSErrorCodeFailedToEncodeJson = 14,
OWSErrorCodeFailedToDecodeQR = 15, OWSErrorCodeFailedToDecodeQR = 15,
OWSErrorCodePrivacyVerificationFailure = 20, OWSErrorCodePrivacyVerificationFailure = 20,
OWSErrorCodeUntrustedIdentityKey = 25, OWSErrorCodeUntrustedIdentity = 25,
OWSErrorCodeFailedToSendOutgoingMessage = 30, OWSErrorCodeFailedToSendOutgoingMessage = 30,
OWSErrorCodeFailedToDecryptMessage = 100, OWSErrorCodeFailedToDecryptMessage = 100,
OWSErrorCodeFailedToEncryptMessage = 110, OWSErrorCodeFailedToEncryptMessage = 110,
@ -29,7 +29,10 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) {
OWSErrorCodeMessageDeletedBeforeSent = 777410, OWSErrorCodeMessageDeletedBeforeSent = 777410,
}; };
extern NSString *const OWSErrorRecipientIdentifierKey;
extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description); extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description);
extern NSError *OWSErrorMakeUntrustedIdentityError(NSString *description, NSString *recipientId);
extern NSError *OWSErrorMakeUnableToProcessServerResponseError(void); extern NSError *OWSErrorMakeUnableToProcessServerResponseError(void);
extern NSError *OWSErrorMakeFailedToSendOutgoingMessageError(void); extern NSError *OWSErrorMakeFailedToSendOutgoingMessageError(void);
extern NSError *OWSErrorMakeNoSuchSignalRecipientError(void); extern NSError *OWSErrorMakeNoSuchSignalRecipientError(void);

@ -7,6 +7,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
NSString *const OWSSignalServiceKitErrorDomain = @"OWSSignalServiceKitErrorDomain"; NSString *const OWSSignalServiceKitErrorDomain = @"OWSSignalServiceKitErrorDomain";
NSString *const OWSErrorRecipientIdentifierKey = @"OWSErrorKeyRecipientIdentifier";
NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description) NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description)
{ {
@ -40,6 +41,14 @@ NSError *OWSErrorMakeAssertionError()
NSLocalizedString(@"ERROR_DESCRIPTION_UNKNOWN_ERROR", @"Worst case generic error message")); NSLocalizedString(@"ERROR_DESCRIPTION_UNKNOWN_ERROR", @"Worst case generic error message"));
} }
NSError *OWSErrorMakeUntrustedIdentityError(NSString *description, NSString *recipientId)
{
return [NSError
errorWithDomain:OWSSignalServiceKitErrorDomain
code:OWSErrorCodeUntrustedIdentity
userInfo:@{ NSLocalizedDescriptionKey : description, OWSErrorRecipientIdentifierKey : recipientId }];
}
NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError() NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError()
{ {
return OWSErrorWithCodeDescription(OWSErrorCodeMessageSendDisabledDueToPreKeyUpdateFailures, return OWSErrorWithCodeDescription(OWSErrorCodeMessageSendDisabledDueToPreKeyUpdateFailures,

Loading…
Cancel
Save