Merge branch 'release/v0.11.2'

This commit is contained in:
SBiOSoftWhare 2020-05-01 03:48:04 +02:00
commit 31d04acb09
61 changed files with 1042 additions and 444 deletions

View file

@ -1,3 +1,19 @@
Changes in 0.11.2 (2020-05-01)
===============================================
Improvements:
* Upgrade MatrixKit version ([v0.12.2](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.12.2)).
* Registration / Email addition: Support email verification link from homeserver (#3167).
* Verification requests: Hide incoming request modal when it is no more pending (#3033).
* Self-verification: Do not display incoming self verification requests at the top of the Complete Security screen.
* Verification: Do not talk about QR code if only emoji is possible (#3035).
* Registration: Prefill email field when opened with universal link (PR #3173).
* Cross-signing: Display "Verify this session" modal at every startup if needed (#3179).
* Complete Security: Support SAS verification start (#3183).
Bug fix:
* AuthenticationViewController: Remove fallback to matrix.org when authentication failed (PR #3165).
Changes in 0.11.1 (2020-04-24)
===============================================

View file

@ -7,7 +7,7 @@ use_frameworks!
# Different flavours of pods to MatrixKit
# The current MatrixKit pod version
$matrixKitVersion = '0.12.1'
$matrixKitVersion = '0.12.2'
# The develop branch version
#$matrixKitVersion = 'develop'

View file

@ -50,38 +50,38 @@ PODS:
- MatomoTracker (7.2.0):
- MatomoTracker/Core (= 7.2.0)
- MatomoTracker/Core (7.2.0)
- MatrixKit (0.12.1):
- MatrixKit (0.12.2):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.21)
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.13)
- MatrixKit/Core (= 0.12.1)
- MatrixSDK (= 0.16.1)
- MatrixKit/AppExtension (0.12.1):
- MatrixKit/Core (= 0.12.2)
- MatrixSDK (= 0.16.2)
- MatrixKit/AppExtension (0.12.2):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.21)
- DTCoreText/Extension
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.13)
- MatrixSDK (= 0.16.1)
- MatrixKit/Core (0.12.1):
- MatrixSDK (= 0.16.2)
- MatrixKit/Core (0.12.2):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.21)
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.13)
- MatrixSDK (= 0.16.1)
- MatrixSDK (0.16.1):
- MatrixSDK/Core (= 0.16.1)
- MatrixSDK/Core (0.16.1):
- MatrixSDK (= 0.16.2)
- MatrixSDK (0.16.2):
- MatrixSDK/Core (= 0.16.2)
- MatrixSDK/Core (0.16.2):
- AFNetworking (~> 3.2.0)
- GZIP (~> 1.2.2)
- libbase58 (~> 0.1.4)
- OLMKit (~> 3.1.0)
- Realm (~> 3.17.3)
- MatrixSDK/JingleCallStack (0.16.1):
- MatrixSDK/JingleCallStack (0.16.2):
- JitsiMeetSDK (~> 2.3.1)
- MatrixSDK/Core
- MatrixSDK/SwiftSupport (0.16.1):
- MatrixSDK/SwiftSupport (0.16.2):
- MatrixSDK/Core
- OLMKit (3.1.0):
- OLMKit/olmc (= 3.1.0)
@ -109,8 +109,8 @@ DEPENDENCIES:
- GBDeviceInfo (~> 6.3.0)
- KTCenterFlowLayout (~> 1.3.1)
- MatomoTracker (~> 7.2.0)
- MatrixKit (= 0.12.1)
- MatrixKit/AppExtension (= 0.12.1)
- MatrixKit (= 0.12.2)
- MatrixKit/AppExtension (= 0.12.2)
- MatrixSDK/JingleCallStack
- MatrixSDK/SwiftSupport
- OLMKit
@ -159,8 +159,8 @@ SPEC CHECKSUMS:
libbase58: 7c040313537b8c44b6e2d15586af8e21f7354efd
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
MatomoTracker: 6f89e2561083685a360e223fb663e9ccd57c1d1a
MatrixKit: 5ebf91a3fed5a9d4110d1db53b5da6889fa42dd0
MatrixSDK: 31c4b9d13335cf074aa3d6e90bb4b2a8c5bbb40a
MatrixKit: 93d2c002db0aa0e0b09bd501313fb16122ff4732
MatrixSDK: 613dba898bbeb7823034b7b30418d89be263c20d
OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639
Realm: 5a1d9d47bfc101dd597668b1a8af4288a2557f6d
Reusable: 82be188f29d96dc5eff0db7b2393bcc08d2cdd5b
@ -169,6 +169,6 @@ SPEC CHECKSUMS:
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
PODFILE CHECKSUM: 75ef978c4b52de673fe49d04b0f1c82d51f537a0
PODFILE CHECKSUM: d3b15ac72eb62dce4f4a61be16d91599412be420
COCOAPODS: 1.9.1

View file

@ -127,6 +127,7 @@
6E6F1CB1244E00FD0068B78B /* LocalContactsSectionHeaderContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E6F1CAF244E00FD0068B78B /* LocalContactsSectionHeaderContainerView.m */; };
6E6F1CB324506EC50068B78B /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6F1CB224506EC50068B78B /* UITableViewCell.swift */; };
6E6F1CB524506FA40068B78B /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6F1CB424506FA40068B78B /* UITableView.swift */; };
6E75C3E32458797D00AF497D /* UniversalLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E75C3E22458797D00AF497D /* UniversalLink.m */; };
6E7A9E9C243E10E700FD039E /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E7A9E9B243E10E700FD039E /* UIDevice.swift */; };
926FA53F1F4C132000F826C2 /* MXSession+Riot.m in Sources */ = {isa = PBXBuildFile; fileRef = 926FA53E1F4C132000F826C2 /* MXSession+Riot.m */; };
92726A471F58737A004AD26F /* IntentHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 92726A461F58737A004AD26F /* IntentHandler.m */; };
@ -629,6 +630,7 @@
B1C562E5228C7C8D0037F12A /* RoomContextualMenuViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1C562E0228C7C8C0037F12A /* RoomContextualMenuViewController.storyboard */; };
B1C562E8228C7CF20037F12A /* ContextualMenuItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1C562E6228C7CF10037F12A /* ContextualMenuItemView.swift */; };
B1C562E9228C7CF20037F12A /* ContextualMenuItemView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1C562E7228C7CF20037F12A /* ContextualMenuItemView.xib */; };
B1C960F02458308D00C5704B /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1C960EF2458308D00C5704B /* RoundedButton.swift */; };
B1CA3A2721EF6914000D1D89 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CA3A2621EF6913000D1D89 /* UIViewController.swift */; };
B1CA3A2921EF692B000D1D89 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CA3A2821EF692B000D1D89 /* UIView.swift */; };
B1CE83B62422812100D07506 /* KeyVerificationCoordinatorBridgePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE83B52422812000D07506 /* KeyVerificationCoordinatorBridgePresenter.swift */; };
@ -912,6 +914,8 @@
6E6F1CB0244E00FD0068B78B /* LocalContactsSectionHeaderContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalContactsSectionHeaderContainerView.h; sourceTree = "<group>"; };
6E6F1CB224506EC50068B78B /* UITableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewCell.swift; sourceTree = "<group>"; };
6E6F1CB424506FA40068B78B /* UITableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = "<group>"; };
6E75C3E12458797D00AF497D /* UniversalLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UniversalLink.h; sourceTree = "<group>"; };
6E75C3E22458797D00AF497D /* UniversalLink.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UniversalLink.m; sourceTree = "<group>"; };
6E7A9E9B243E10E700FD039E /* UIDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = "<group>"; };
926FA53D1F4C132000F826C2 /* MXSession+Riot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXSession+Riot.h"; sourceTree = "<group>"; };
926FA53E1F4C132000F826C2 /* MXSession+Riot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MXSession+Riot.m"; sourceTree = "<group>"; };
@ -1609,6 +1613,7 @@
B1C6FFE723954CE70055347B /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
B1C6FFE823954D3B0055347B /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
B1C6FFE923954D4B0055347B /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Vector.strings; sourceTree = "<group>"; };
B1C960EF2458308D00C5704B /* RoundedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = "<group>"; };
B1CA3A2621EF6913000D1D89 /* UIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = "<group>"; };
B1CA3A2821EF692B000D1D89 /* UIView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
B1CE83B52422812000D07506 /* KeyVerificationCoordinatorBridgePresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationCoordinatorBridgePresenter.swift; sourceTree = "<group>"; };
@ -2681,6 +2686,7 @@
isa = PBXGroup;
children = (
B183226B23F59F810035B2E8 /* CloseButton.swift */,
B1C960EF2458308D00C5704B /* RoundedButton.swift */,
);
path = Close;
sourceTree = "<group>";
@ -4336,6 +4342,8 @@
F083BC151E7009EC00A9B29C /* Tools.m */,
B1DB4F0D22316FFF0065DBFA /* UserNameColorGenerator.swift */,
B197B7C5243DE947005ABBF3 /* EncryptionTrustLevelBadgeImageHelper.swift */,
6E75C3E12458797D00AF497D /* UniversalLink.h */,
6E75C3E22458797D00AF497D /* UniversalLink.m */,
);
path = Utils;
sourceTree = "<group>";
@ -5013,6 +5021,7 @@
F083BDEE1E7009ED00A9B29C /* MXRoom+Riot.m in Sources */,
B120863722EF375F001F89E0 /* ReactionHistoryBridgeCoordinatorPresenter.swift in Sources */,
B1B5598620EFC3E000210D55 /* RiotSettings.swift in Sources */,
B1C960F02458308D00C5704B /* RoundedButton.swift in Sources */,
B1CE83D52422817200D07506 /* KeyVerificationVerifyByScanningViewController.swift in Sources */,
3232ABA3225730E100AD6A5C /* DeviceVerificationStartCoordinatorType.swift in Sources */,
3232AB4D2256558300AD6A5C /* TemplateScreenCoordinatorType.swift in Sources */,
@ -5123,6 +5132,7 @@
3232ABC2225B996200AD6A5C /* Themable.swift in Sources */,
32A6001B22C661100042C1D9 /* EditHistoryViewAction.swift in Sources */,
3232ABA7225730E100AD6A5C /* DeviceVerificationStartCoordinator.swift in Sources */,
6E75C3E32458797D00AF497D /* UniversalLink.m in Sources */,
B1D4752721EE4E630067973F /* KeyboardAvoider.swift in Sources */,
B1D4752821EE4E630067973F /* KeyboardNotification.swift in Sources */,
B1D1BDA622BBAFB500831367 /* ReactionsMenuView.swift in Sources */,

View file

@ -26,6 +26,7 @@
#import "Analytics.h"
#import "ThemeService.h"
#import "UniversalLink.h"
#pragma mark - Notifications
/**
@ -42,6 +43,11 @@ extern NSString *const AppDelegateDidValidateEmailNotification;
extern NSString *const AppDelegateDidValidateEmailNotificationSIDKey;
extern NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey;
/**
Posted when the property 'lastHandledUniversalLink' has changed. Notification object and userInfo will be nil.
*/
extern NSString *const AppDelegateUniversalLinkDidChangeNotification;
@interface AppDelegate : UIResponder <UIApplicationDelegate, MXKCallViewControllerDelegate, UISplitViewControllerDelegate, UINavigationControllerDelegate, JitsiViewControllerDelegate, UNUserNotificationCenterDelegate>
{
BOOL isPushRegistered;
@ -65,6 +71,13 @@ extern NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey;
@property (nonatomic) BOOL isAppForeground;
@property (nonatomic) BOOL isOffline;
/**
Let the AppDelegate handle and display self verification requests.
Default is YES;
*/
@property (nonatomic) BOOL handleSelfVerificationRequest;
/**
The navigation controller of the master view controller of the main split view controller.
*/
@ -80,6 +93,11 @@ extern NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey;
// Current selected room id. nil if no room is presently visible.
@property (strong, nonatomic) NSString *visibleRoomId;
/**
Last handled universal link (url will be formatted for several hash keys).
*/
@property (nonatomic, readonly) UniversalLink *lastHandledUniversalLink;
// New message sound id.
@property (nonatomic, readonly) SystemSoundID messageSound;

View file

@ -88,6 +88,8 @@ NSString *const AppDelegateDidValidateEmailNotification = @"AppDelegateDidValida
NSString *const AppDelegateDidValidateEmailNotificationSIDKey = @"AppDelegateDidValidateEmailNotificationSIDKey";
NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDelegateDidValidateEmailNotificationClientSecretKey";
NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUniversalLinkDidChangeNotification";
@interface AppDelegate () <PKPushRegistryDelegate, GDPRConsentViewControllerDelegate, KeyVerificationCoordinatorBridgePresenterDelegate, ServiceTermsModalCoordinatorBridgePresenterDelegate>
{
/**
@ -493,6 +495,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
NSAssert(_masterTabBarController, @"Something wrong in Main.storyboard");
_isAppForeground = NO;
_handleSelfVerificationRequest = YES;
// Configure our analytics. It will indeed start if the option is enabled
[MXSDKOptions sharedInstance].analyticsDelegate = [Analytics sharedInstance];
@ -2037,6 +2040,19 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
// iOS Patch: fix vector.im urls before using it
webURL = [Tools fixURLWithSeveralHashKeys:webURL];
// Extract required parameters from the link
NSArray<NSString*> *pathParams;
NSMutableDictionary *queryParams;
[self parseUniversalLinkFragment:webURL.absoluteString outPathParams:&pathParams outQueryParams:&queryParams];
UniversalLink *newLink = [[UniversalLink alloc] initWithUrl:webURL pathParams:pathParams queryParams:queryParams];
if (![_lastHandledUniversalLink isEqual:newLink])
{
_lastHandledUniversalLink = [[UniversalLink alloc] initWithUrl:webURL pathParams:pathParams queryParams:queryParams];
// notify this change
[[NSNotificationCenter defaultCenter] postNotificationName:AppDelegateUniversalLinkDidChangeNotification object:nil];
}
if ([webURL.path hasPrefix:@"/config"])
{
return [self handleServerProvionningLink:webURL];
@ -2047,8 +2063,39 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
NSString *validateEmailSubmitTokenAPIPathV1 = [NSString stringWithFormat:@"/%@/%@", kMXIdentityAPIPrefixPathV1, validateEmailSubmitTokenPath];
NSString *validateEmailSubmitTokenAPIPathV2 = [NSString stringWithFormat:@"/%@/%@", kMXIdentityAPIPrefixPathV2, validateEmailSubmitTokenPath];
// Manage email validation link
if ([webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV1] || [webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV2])
// Manage email validation links from homeserver for registration (/registration/email/submit_token)
// and email addition (/add_threepid/email/submit_token)
// They look like https://matrix.org/_matrix/client/unstable/registration/email/submit_token?token=vtQjQIZfwdoREDACTEDozrmKYSWlCXsJ&client_secret=53e679ea-oRED-ACTED-92b8-3012c49c6cfa&sid=qlBCREDACTEDEtgxD
if ([webURL.path hasSuffix:@"/email/submit_token"])
{
NSLog(@"[AppDelegate] handleUniversalLink: Validate link");
// We just need to ping the link.
// The app should be in the registration flow at the "waiting for email validation" polling state. The server
// will indicate the email is validated through this polling API. Then, the app will go to the next flow step.
NSURLSessionConfiguration *conf = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:conf];
NSURLSessionDataTask * task = [urlSession dataTaskWithURL:webURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"[AppDelegate] handleUniversalLink: Link validation response: %@\nData: %@", response,
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
if (error)
{
NSLog(@"[AppDelegate] handleUniversalLink: Link validation error: %@", error);
[self showErrorAsAlert:error];
}
}];
[task resume];
return YES;
}
// Manage email validation link from Identity Server v1 or v2
else if ([webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV1]
|| [webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV2])
{
// Validate the email on the passed identity server
NSString *identityServer = [NSString stringWithFormat:@"%@://%@", webURL.scheme, webURL.host];
@ -2066,12 +2113,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
}
MXIdentityService *identityService = [[MXIdentityService alloc] initWithIdentityServer:identityServer accessToken:nil andHomeserverRestClient:homeserverRestClient];
// Extract required parameters from the link
NSArray<NSString*> *pathParams;
NSMutableDictionary *queryParams;
[self parseUniversalLinkFragment:webURL.absoluteString outPathParams:&pathParams outQueryParams:&queryParams];
NSString *clientSecret = queryParams[@"client_secret"];
NSString *sid = queryParams[@"sid"];
@ -4803,7 +4845,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
{
BOOL presented = NO;
if (!keyVerificationCoordinatorBridgePresenter)
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
{
NSLog(@"[AppDelegate] presentIncomingKeyVerificationRequest");
@ -4827,7 +4869,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
NSLog(@"[AppDelegate][MXKeyVerification] presentIncomingKeyVerification: %@", transaction);
BOOL presented = NO;
if (!keyVerificationCoordinatorBridgePresenter)
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
{
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
keyVerificationCoordinatorBridgePresenter.delegate = self;
@ -4848,7 +4890,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
NSLog(@"[AppDelegate][MXKeyVerification] presentUserVerificationForRoomMember: %@", roomMember);
BOOL presented = NO;
if (!keyVerificationCoordinatorBridgePresenter)
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
{
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
keyVerificationCoordinatorBridgePresenter.delegate = self;
@ -4869,7 +4911,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
NSLog(@"[AppDelegate][MXKeyVerification] presentSelfVerificationForOtherDeviceId: %@", deviceId);
BOOL presented = NO;
if (!keyVerificationCoordinatorBridgePresenter)
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
{
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
keyVerificationCoordinatorBridgePresenter.delegate = self;
@ -4965,6 +5007,12 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
{
// Self verification
NSLog(@"[AppDelegate][KeyVerification] keyVerificationNewRequestNotification: Self verification from %@", keyVerificationByToDeviceRequest.otherDevice);
if (!self.handleSelfVerificationRequest)
{
NSLog(@"[AppDelegate][KeyVerification] keyVerificationNewRequestNotification: Self verification handled elsewhere");
return;
}
NSString *myUserId = keyVerificationByToDeviceRequest.otherUser;
MXKAccount *account = [[MXKAccountManager sharedManager] accountForUserId:myUserId];
@ -5006,6 +5054,12 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
senderId:(NSString*)senderId
request:(MXKeyVerificationRequest*)keyVerificationRequest
{
if (keyVerificationRequest.state != MXKeyVerificationRequestStatePending)
{
NSLog(@"[AppDelegate] presentNewKeyVerificationRequest: Request already accepted. Do not display it");
return;
}
if (self.incomingKeyVerificationRequestAlertController)
{
[self.incomingKeyVerificationRequestAlertController dismissViewControllerAnimated:NO completion:nil];
@ -5021,7 +5075,17 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
{
senderInfo = senderId;
}
__block id observer;
void (^removeObserver)(void) = ^() {
if (observer)
{
[[NSNotificationCenter defaultCenter] removeObserver:observer];
observer = nil;
}
};
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"key_verification_tile_request_incoming_title", @"Vector", nil)
message:senderInfo
@ -5031,6 +5095,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
removeObserver();
[self presentIncomingKeyVerificationRequest:keyVerificationRequest inSession:session];
}]];
@ -5038,6 +5103,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
removeObserver();
[keyVerificationRequest cancelWithCancelCode:MXTransactionCancelCode.user success:^{
} failure:^(NSError * _Nonnull error) {
@ -5049,11 +5115,26 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action)
{
removeObserver();
}]];
[self presentViewController:alertController animated:YES completion:nil];
self.incomingKeyVerificationRequestAlertController = alertController;
observer = [[NSNotificationCenter defaultCenter] addObserverForName:MXKeyVerificationRequestDidChangeNotification
object:keyVerificationRequest
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull note)
{
if (keyVerificationRequest.state != MXKeyVerificationRequestStatePending)
{
if (self.incomingKeyVerificationRequestAlertController == alertController)
{
[self.incomingKeyVerificationRequestAlertController dismissViewControllerAnimated:NO completion:nil];
removeObserver();
}
}
}];
}
#pragma mark - New Sign In
@ -5127,14 +5208,14 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"continue", @"Vector", nil)
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"device_verification_self_verify_alert_validate_action", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self presentSelfVerificationForOtherDeviceId:device.deviceId inSession:session];
}]];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"device_verification_self_verify_alert_cancel_action", @"Vector", nil)
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"later", @"Vector", nil)
style:UIAlertActionStyleCancel
handler:nil]];
@ -5150,7 +5231,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
NSLog(@"[AppDelegate][MXKeyVerification] presentCompleteSecurityForSession");
BOOL presented = NO;
if (!keyVerificationCoordinatorBridgePresenter)
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
{
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
keyVerificationCoordinatorBridgePresenter.delegate = self;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 B

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -281,7 +281,7 @@
"room_replacement_information" = "Mae'r ystafell hon wedi'i newid ac nid yw'n weithredol mwyach.";
"room_replacement_link" = "Mae'r sgwrs yn parhau yma.";
"room_predecessor_information" = "Mae'r ystafell hon yn barhad o sgwrs arall.";
"room_predecessor_link" = "Cyffyrddwch yma i weld negeseuon hŷn.";
"room_predecessor_link" = "Tapiwch yma i weld negeseuon hŷn.";
"room_resource_limit_exceeded_message_contact_1" = " Os gwelwch yn dda ";
"room_resource_limit_exceeded_message_contact_2_link" = "cysylltwch â'ch gweinyddwr gwasanaeth";
"room_resource_limit_exceeded_message_contact_3" = " i barhau i ddefnyddio'r gwasanaeth hwn.";
@ -418,7 +418,7 @@
"settings_add_3pid_invalid_password_message" = "Cyfrinair annilys";
"settings_crypto_device_name" = "Enw Sesiwn: ";
"settings_crypto_device_id" = "\nDynodwr y sesiwn: ";
"settings_crypto_device_key" = "Allwedd y sesiwn:\n";
"settings_crypto_device_key" = "\nAllwedd y sesiwn:\n";
"settings_crypto_export" = "Allfudo allweddi";
"settings_crypto_blacklist_unverified_devices" = "Amgryptio i sesiynau wedi'u gwirio yn unig";
"settings_deactivate_my_account" = "Dad-actifadu fy nghyfrif";
@ -984,3 +984,35 @@
"key_verification_verify_qr_code_other_scan_my_code_title" = "A sganwyd y defnyddiwr arall u côd QR yn llwyddianus?";
"key_verification_verify_qr_code_scan_other_code_success_title" = "Côd yn ddilys!";
"key_verification_verify_qr_code_scan_other_code_success_message" = "Mae'r côd QR wedi'i brofi'n ddilys.";
"skip" = "Hepgor";
// MARK: Clients
"client_desktop_name" = "Riot Cyfrifiadur";
"client_web_name" = "Riot Gwê";
"client_ios_name" = "Riot iOS";
"client_android_name" = "Riot X i Android";
"room_participants_action_security_status_complete_security" = "Cwblhewch diogelwch";
"room_participants_action_security_status_loading" = "Yn llwytho…";
"room_member_power_level_admin_in" = "Gweinyddwr yn %@";
"room_member_power_level_moderator_in" = "Cymedrolwrm yn %@";
"room_member_power_level_custom_in" = "Addasiedig (%@) yn %@";
"room_member_power_level_short_admin" = "Gweinyddwr";
"room_member_power_level_short_moderator" = "Cymedrolwr";
"room_member_power_level_short_custom" = "Addasiedig";
"security_settings_crosssigning" = "CROES-LOFNODI";
"security_settings_crosssigning_info_not_bootstrapped" = "Nid yw croes-lofnodi eto wedi ei gyflunio.";
"security_settings_crosssigning_info_exists" = "Mae gan eich cyfrif hunaniaeth croes-lofnodi, ond nid yw'r sesiwn hon yn ymddiried ynddo eto. Cwblhewch diogelwch y sesiwn hon.";
"security_settings_crosssigning_info_trusted" = "Mae croes-lofnodi wedi'i alluogi. Gallwch ymddiried yn defnyddwyr eraill a'ch sesiynau eraill yn seiliedig ar groes-lofnodi ond ni allwch groes-lofnodi o'r sesiwn hon oherwydd nad oes ganddo allweddi preifat traws-lofnodi. Cwblhewch diogelwch y sesiwn hon.";
"security_settings_crosssigning_info_ok" = "Mae croes-lofnodi yn weithredol.";
"security_settings_crosssigning_bootstrap" = "Ymlwytho croes-lofnodi";
"security_settings_crosssigning_reset" = "Ailosod croes-lofnodi";
"security_settings_crosssigning_complete_security" = "Cwblhewch diogelwch";
"security_settings_cryptography" = "CRYPTOGRAFFEG";
"security_settings_complete_security_alert_title" = "Cwblhewch diogelwch";
"security_settings_complete_security_alert_message" = "Dylech gwblhau diogelwch ar eich sesiwn gyfredol yn gyntaf.";
"security_settings_coming_soon" = "Sori. Nid yw'r weithred hon ar gael ar Riot-iOS eto. Defnyddiwch gleient Matrix arall i'w osod. Bydd Riot-iOS yn ei ddefnyddio.";
// Recover from private key
"key_backup_recover_from_private_key_info" = "Yn adfer copi wrth gefn…";
"device_verification_self_verify_alert_title" = "Mewngofnodiad Newydd";
"device_verification_self_verify_alert_message" = "Defnyddiwch y sesiwn hon i wirio'ch un newydd, gan roi mynediad iddo i negeseuon wedi'u hamgryptio :%@\nOs na wnaethoch fewngofnodi i'r sesiwn hon, mae'n bosibl y bydd eich cyfrif mewn perygl..";
"device_verification_self_verify_alert_cancel_action" = "Nid fi oedd hwn";
"device_verification_self_verify_start_verify_action" = "Dechrau gwirio";

View file

@ -1004,3 +1004,6 @@
"device_verification_self_verify_wait_information" = "Benutze diese Sitzung um deine Neue zu verifizieren. Erlaube Zugriff auf die verschlüsselten Nachrichten.";
"device_verification_self_verify_wait_waiting" = "warte…";
"skip" = "Überspringen";
// MARK: Clients
"client_desktop_name" = "Riot Desktop";
"security_settings_crosssigning_info_not_bootstrapped" = "Cross-signing ist bisher nicht konfiguriert.";

View file

@ -1035,10 +1035,12 @@
"sign_out_key_backup_in_progress_alert_cancel_action" = "I'll wait";
// MARK: - Device Verification
"device_verification_title" = "Verify session";
"key_verification_user_title" = "Verify user";
"device_verification_security_advice" = "For maximum security, we recommend you do this in person or use another trusted means of communication";
"key_verification_other_session_title" = "Verify session";
"key_verification_new_session_title" = "Verify your new session";
"key_verification_this_session_title" = "Verify this session";
"key_verification_user_title" = "Verify them";
"device_verification_security_advice_emoji" = "Compare the unique emoji, ensuring they appear in the same order.";
"device_verification_security_advice_number" = "Compare the numbers, ensuring they appear in the same order.";
"device_verification_cancelled" = "The other party cancelled the verification.";
"device_verification_cancelled_by_me" = "The verification has been cancelled. Reason: %@";
"device_verification_error_cannot_load_device" = "Cannot load session information.";
@ -1057,47 +1059,57 @@
// MARK: Self verification start
"device_verification_self_verify_alert_title" = "New Sign In";
"device_verification_self_verify_alert_message" = "Use this session to verify your new one, granting it access to encrypted messages: %@\nIf you didnt sign in to this session, your account may be compromised.";
"device_verification_self_verify_alert_cancel_action" = "This wasn't me";
// New login
"device_verification_self_verify_alert_title" = "New login. Was this you?";
"device_verification_self_verify_alert_message" = "Verify the new login accessing your account: %@";
"device_verification_self_verify_alert_validate_action" = "Verify";
"device_verification_self_verify_start_verify_action" = "Start verification";
"device_verification_self_verify_start_information" = "Use this session to verify your new one, granting it access to encrypted messages.";
"device_verification_self_verify_start_waiting" = "Waiting…";
// Current session
"key_verification_self_verify_current_session_alert_title" = "Verify this session";
"key_verification_self_verify_current_session_alert_message" = "Other users may not trust it.";
"key_verification_self_verify_current_session_alert_validate_action" = "Verify";
// MARK: Self verification wait
"device_verification_self_verify_wait_title" = "Complete security";
"device_verification_self_verify_wait_new_sign_in_title" = "Verify this login";
"device_verification_self_verify_wait_information" = "Verify this session from one of your others sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:";
"device_verification_self_verify_wait_information" = "Verify this session from one of your other sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:";
"device_verification_self_verify_wait_additional_information" = "or another cross-signing capable Matrix client";
// MARK: Verify
"key_verification_verify_sas_title_emoji" = "Compare emoji";
"key_verification_verify_sas_title_number" = "Compare numbers";
"key_verification_verify_sas_cancel_action" = "They don't match";
"key_verification_verify_sas_validate_action" = "They match";
"key_verification_verify_sas_additional_information" = "For ultimate security, use another trusted means of communication or do this in person.";
// Device
"device_verification_verify_title_emoji" = "Verify this session by confirming the following emoji appear on the screen of the partner";
"device_verification_verify_title_number" = "Verify this session by confirming the following numbers appear on the screen of the partner";
"device_verification_verify_wait_partner" = "Waiting for partner to confirm…";
// User
"key_verification_verify_user_title_emoji" = "Verify this user by confirming the following unique emoji appears on their screen, in the same order.";
"key_verification_verify_user_title_number" = "Verify this user by confirming the following numbers appear on their screen, in the same order.";
// MARK: Verified
// Device
"device_verification_verified_title" = "Verified!";
"device_verification_verified_description_1" = "You've successfully verified this session.";
"device_verification_verified_description_2" = "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.";
"device_verification_verified_got_it_button" = "Got it";
"key_verification_verified_new_session_title" = "New session verified!";
"key_verification_verified_other_session_information" = "You can now read secure messages on your other session, and other users will know they can trust it.";
"key_verification_verified_new_session_information" = "You can now read secure messages on your new device, and other users will know they can trust it.";
"key_verification_verified_this_session_information" = "You can now read secure messages on this device, and other users will know they can trust it.";
// User
"key_verification_verified_user_description_1" = "Youve successfully verified this user.";
"key_verification_verified_user_description_2" = "Messages with this user in this room are end-to-end encrypted and cant be read by third parties.";
"key_verification_verified_user_information" = "Messages with this user are end-to-end encrypted and can't be read by third parties.";
// MARK: Emoji
"device_verification_emoji_dog" = "Dog";
@ -1220,8 +1232,10 @@
"key_verification_verify_qr_code_title" = "Verify by scanning";
"key_verification_verify_qr_code_information" = "Scan the code to securely verify each other.";
"key_verification_verify_qr_code_emoji_information" = "Verify by comparing unique emoji.";
"key_verification_verify_qr_code_scan_code_action" = "Scan their code";
"key_verification_verify_qr_code_cannot_scan_action" = "Can't scan?";
"key_verification_verify_qr_code_start_emoji_action" = "Verify by emoji";
"key_verification_verify_qr_code_other_scan_my_code_title" = "Did the other user successfully scan the QR code?";

View file

@ -999,7 +999,7 @@
"security_settings_crosssigning" = "ZEHARKAKO SINATZEA";
"security_settings_cryptography" = "KRIPTOGRAFIA";
"key_verification_bootstrap_not_setup_title" = "Errorea";
"key_verification_bootstrap_not_setup_message" = "Zeharkako sinatzea ezarri behar duzu";
"key_verification_bootstrap_not_setup_message" = "Aurretik zeharkako sinatzea abiatu behar duzu.";
"key_verification_verify_qr_code_title" = "Egiaztatu eskaneatuz";
"key_verification_verify_qr_code_information" = "Eskaneatu kodea elkar egiaztatzeko.";
"key_verification_verify_qr_code_scan_code_action" = "Eskaneatu bestearen kodea";
@ -1024,5 +1024,31 @@
// Recover from private key
"key_backup_recover_from_private_key_info" = "Babes-kopia berrezartzen…";
"device_verification_self_verify_wait_title" = "Segurtasun osoa";
"device_verification_self_verify_wait_information" = "Erabili badagoen beste saio bat berri hau egiaztatzeko, honela mezu zifratuetara sarbidea emanez.";
"device_verification_self_verify_wait_information" = "Erabili badagoen beste saio bat berri hau egiaztatzeko, honela mezu zifratuetara sarbidea emanez.\n\nErabili azken Riot bertsioa zure beste gailuetan:";
"device_verification_self_verify_wait_waiting" = "Itxaroten…";
// MARK: Clients
"client_desktop_name" = "Riot Desktop";
"client_web_name" = "Riot Web";
"client_ios_name" = "Riot iOS";
"client_android_name" = "Riot X Androidentzat";
"room_participants_action_security_status_complete_security" = "Segurtasun osoa";
"security_settings_crosssigning_info_not_bootstrapped" = "Zeharkako sinadura ez dago ezarrita.";
"security_settings_crosssigning_info_exists" = "Zure kontuak zeharkako sinatze identitate bat du biltegi sekretuan, baina saio honek ez du oraindik fidagarritzat. Osatu saio honen segurtasuna.";
"security_settings_crosssigning_info_trusted" = "Zeharkako sinatzea gaituta dago. Beste erabiltzaileak eta zure beste saioak fidagarritzat jo ditzakezu zeharkako sinadurarekin, baina ezin duzu zeharka sinatu saio honekin ez dituzulako zeharkako sinadurarako gako pribatuak. Osatu saio honen segurtasuna.";
"security_settings_crosssigning_info_ok" = "Zeharkako sinadura gaituta dago.";
"security_settings_crosssigning_bootstrap" = "Abiatu zeharkako sinadura";
"security_settings_crosssigning_reset" = "Berrezarri zeharkako sinadura";
"security_settings_crosssigning_complete_security" = "Segurtasun osoa";
"security_settings_complete_security_alert_title" = "Segurtasun osoa";
"security_settings_complete_security_alert_message" = "Aurretik segurtasuna osatu beharko zenuke oraingo saioan.";
"security_settings_coming_soon" = "Sentitzen dugu. Ekintza hau ez dago iOS plataformarako Riot bezeroan eskuragarri oraindik. Erabili beste Matrix bezero bat ezartzeko. Riot-iOS-ek erabili egingo du.";
"device_verification_self_verify_wait_new_sign_in_title" = "Egiaztatu saio hau";
"device_verification_self_verify_wait_additional_information" = "edo zeharkako sinadurarako gai den beste Matrix bezero bat";
// Scanning
"key_verification_scan_confirmation_scanning_title" = "Ia bukatu duzu! Baieztapenaren zain…";
"key_verification_scan_confirmation_scanning_user_waiting_other" = "%@ itxaroten…";
"key_verification_scan_confirmation_scanning_device_waiting_other" = "Beste gailuaren zain…";
// Scanned
"key_verification_scan_confirmation_scanned_title" = "Ia amaitu duzu!";
"key_verification_scan_confirmation_scanned_user_information" = "%@ ezkutu bera erakusten ari da?";
"key_verification_scan_confirmation_scanned_device_information" = "Beste gailuak ezkutu bera erakusten du?";

View file

@ -1012,7 +1012,7 @@
"user_verification_session_details_verify_action_other_user" = "Vérifier manuellement";
"security_settings_crypto_sessions_loading" = "Chargement des sessions…";
"key_verification_bootstrap_not_setup_title" = "Erreur";
"key_verification_bootstrap_not_setup_message" = "Vous devez configurer la signature croisée";
"key_verification_bootstrap_not_setup_message" = "Vous devez dabord configurer la signature croisée.";
"key_verification_verify_qr_code_title" = "Vérifier en scannant";
"key_verification_verify_qr_code_information" = "Scannez le code pour vous vérifier mutuellement de façon sécurisée.";
"key_verification_verify_qr_code_scan_code_action" = "Scannez leur code";
@ -1031,7 +1031,7 @@
"device_verification_self_verify_start_waiting" = "En attente…";
"skip" = "Passer";
"device_verification_self_verify_wait_title" = "Compléter la sécurité";
"device_verification_self_verify_wait_information" = "Utilisez une session existante pour vérifier celle-ci, ce qui lui permettra davoir accès aux messages chiffrés.";
"device_verification_self_verify_wait_information" = "Vérifiez cette session depuis une de vos autres sessions, ce qui lui permettra davoir accès aux messages chiffrés.\n\nUtilisez la dernière version de Riot sur vos autres appareils :";
"device_verification_self_verify_wait_waiting" = "En attente…";
"room_member_power_level_admin_in" = "Administrateur dans %@";
"room_member_power_level_moderator_in" = "Modérateur dans %@";
@ -1059,4 +1059,11 @@
"security_settings_crosssigning_complete_security" = "Compléter la sécurité";
"security_settings_complete_security_alert_title" = "Compléter la sécurité";
"security_settings_complete_security_alert_message" = "Vous devriez dabord compléter la sécurité de votre session actuelle.";
"security_settings_coming_soon" = "Désolé, cette action nest pas encore disponible dans Riot-iOS. Utilisez un autre client Matrix.";
"security_settings_coming_soon" = "Désolé, cette action nest pas encore disponible dans Riot-iOS. Utilisez un autre client Matrix pour le configurer. Riot-iOS lutilisera.";
// MARK: Clients
"client_desktop_name" = "Riot pour ordinateur";
"client_web_name" = "Riot web";
"client_ios_name" = "Riot iOS";
"client_android_name" = "Riot X pour Android";
"device_verification_self_verify_wait_new_sign_in_title" = "Vérifier cette connexion";
"device_verification_self_verify_wait_additional_information" = "ou un autre client Matrix qui prend en charge la signature croisée";

View file

@ -1016,7 +1016,7 @@
"security_settings_crosssigning" = "KERESZT-ALÁÍRÁS";
"security_settings_cryptography" = "TITKOSÍTÁS";
"key_verification_bootstrap_not_setup_title" = "Hiba";
"key_verification_bootstrap_not_setup_message" = "A keresztaláírás beállításait meg kell adni";
"key_verification_bootstrap_not_setup_message" = "A keresztaláírás beállításait először meg kell adni.";
"key_verification_verify_qr_code_title" = "Ellenőrzés kód beolvasással";
"key_verification_verify_qr_code_information" = "Olvasd be a kódot, hogy biztonságosan ellenőrizhessétek egymást.";
"key_verification_verify_qr_code_scan_code_action" = "Kód beolvasása";
@ -1041,7 +1041,7 @@
"device_verification_self_verify_start_information" = "Az új munkamenet ellenőrzéséhez használd ezt, amivel hozzáférést adsz a titkosított üzenetekhez.";
"device_verification_self_verify_start_waiting" = "Várakozik…";
"device_verification_self_verify_wait_title" = "Biztonság beállítása";
"device_verification_self_verify_wait_information" = "Használj egy meglévő munkamenetet ennek az újnak az ellenőrzéséhez, amivel hozzáférést adsz a titkosított üzenetekhez.";
"device_verification_self_verify_wait_information" = "Ennek a munkamenet ellenőrzéséhez használd valamelyik másik munkamenetedet, amivel hozzáférést adsz a titkosított üzenetekhez.\n\nHasználd a legfrissebb Riotot valamelyik eszközödön:";
"device_verification_self_verify_wait_waiting" = "Várakozik…";
// Scanning
"key_verification_scan_confirmation_scanning_title" = "Majdnem kész! Várakozás a megerősítésre…";
@ -1052,3 +1052,20 @@
"key_verification_scan_confirmation_scanned_user_information" = "%s is ugyanazt a pajzsot mutatja?";
"key_verification_scan_confirmation_scanned_device_information" = "A másik eszköz is ugyanazt a pajzsot mutatja?";
"room_participants_action_security_status_complete_security" = "Biztonsági beállítás befejezése";
// MARK: Clients
"client_desktop_name" = "Asztali Riot";
"client_web_name" = "Riot Web";
"client_ios_name" = "Riot iOS";
"client_android_name" = "RiotX Android";
"security_settings_crosssigning_info_not_bootstrapped" = "Az eszközök közötti hitelesítés nincs még beállítva.";
"security_settings_crosssigning_info_exists" = "A fiókodban az eszközök közötti aláírás be van állítva, de ebben a munkamenetben még nem ellenőrizted. Végezd el a munkamenet biztonsági beállításait.";
"security_settings_crosssigning_info_trusted" = "Eszközök közötti hitelesítés engedélyezve van. Megbízhatsz más felhasználókban és a munkameneteidben az aláírást felhasználva de ebből a munkamenetből nem tudsz aláírni mert az eszközök közötti aláíráshoz hiányzik a privát kulcs. Fejezd be a munkamenet biztonsági beállításait.";
"security_settings_crosssigning_info_ok" = "Eszközök közti hitelesítés engedélyezve.";
"security_settings_crosssigning_bootstrap" = "Eszközök közötti hitelesítés beállítása";
"security_settings_crosssigning_reset" = "Eszközök közötti hitelesítés alaphelyzetbe állítása";
"security_settings_crosssigning_complete_security" = "Biztonsági beállítás befejezése";
"security_settings_complete_security_alert_title" = "Biztonsági beállítás befejezése";
"security_settings_complete_security_alert_message" = "Először be kell fejezned ennek a munkamenetnek a biztonsági beállítását.";
"security_settings_coming_soon" = "Bocsánat. Riot-iOS-n ez a művelet egyenlőre nem érhető el. Kérlek használj másik Matrix klienst a beállításához. Riot-iOS használni fogja.";
"device_verification_self_verify_wait_new_sign_in_title" = "Belépés ellenőrzése";
"device_verification_self_verify_wait_additional_information" = "vagy másik eszközök közötti hitelesítésre alkalmas Matrix kliensre";

View file

@ -952,7 +952,7 @@
"room_participants_action_security_status_verify" = "Verifica";
"room_participants_action_security_status_warning" = "Attenzione";
"room_participants_security_loading" = "Caricamento…";
"key_verification_user_title" = "Verifica utente";
"key_verification_user_title" = "verificale";
"room_participants_security_information_room_not_encrypted" = "I messaggi in questa stanza non sono cifrati end-to-end.";
"room_participants_security_information_room_encrypted" = "I messaggi in questa stanza sono cifrati end-to-end.\n\nI tuoi messaggi sono protetti con lucchetti e solo te ed il destinatario avete le chiavi univoche per sbloccarli.";
"key_verification_verify_user_title_emoji" = "Verifica questo utente confermando che le seguenti emoji appaiono sul suo schermo, nello stesso ordine.";
@ -984,7 +984,7 @@
"user_verification_session_details_verify_action_other_user" = "Verifica manualmente";
"security_settings_crypto_sessions_loading" = "Caricamento sessioni…";
"key_verification_bootstrap_not_setup_title" = "Errore";
"key_verification_bootstrap_not_setup_message" = "Devi inizializzare la firma incrociata";
"key_verification_bootstrap_not_setup_message" = "Devi prima inizializzare la firma incrociata.";
"key_verification_verify_qr_code_title" = "Verifica scansionando";
"key_verification_verify_qr_code_information" = "Scansiona il codice per verificarvi in modo sicuro.";
"key_verification_verify_qr_code_scan_code_action" = "Scansiona il suo codice";
@ -1003,7 +1003,7 @@
"device_verification_self_verify_start_waiting" = "In attesa…";
"skip" = "Salta";
"device_verification_self_verify_wait_title" = "Completa la sicurezza";
"device_verification_self_verify_wait_information" = "Usa una sessione esistente per verificare questa nuova, dandole l'accesso ai messaggi cifrati.";
"device_verification_self_verify_wait_information" = "Verifica questa sessione da una delle tue altre sessioni, dandole l'accesso ai messaggi cifrati.\n\nUsa la versione più recente di Riot sui tuoi altri dispositivi:";
"device_verification_self_verify_wait_waiting" = "In attesa…";
"room_member_power_level_admin_in" = "Amministratore in %@";
"room_member_power_level_moderator_in" = "Moderatore in %@";
@ -1031,4 +1031,19 @@
"security_settings_crosssigning_complete_security" = "Completa la sicurezza";
"security_settings_complete_security_alert_title" = "Completa la sicurezza";
"security_settings_complete_security_alert_message" = "Dovresti completare la sicurezza prima sulla tua sessione attuale.";
"security_settings_coming_soon" = "Spiacenti. Questa azione non è ancora disponibile su Riot-iOS. Prova ad usare un altro client Matrix.";
"security_settings_coming_soon" = "Spiacenti. Questa azione non è ancora disponibile su Riot-iOS. Prova ad usare un altro client Matrix per farlo. Riot-iOS lo userà.";
// MARK: Clients
"client_desktop_name" = "Riot Desktop";
"client_web_name" = "Riot Web";
"client_ios_name" = "Riot iOS";
"client_android_name" = "Riot X per Android";
"device_verification_self_verify_wait_new_sign_in_title" = "Verifica questo accesso";
"device_verification_self_verify_wait_additional_information" = "o un altro client Matrix che supporti la firma incrociata";
// MARK: - Device Verification
"key_verification_other_session_title" = "Verifica sessione";
"key_verification_new_session_title" = "Verifica la tua nuova sessione";
"key_verification_this_session_title" = "Verifica questa sessione";
"device_verification_security_advice_emoji" = "Confronta gli emoji univoci, assicurandoti che compaiono nello stesso ordine.";
"device_verification_security_advice_number" = "Confronta i numeri, assicurandoti che compaiono nello stesso ordine.";
"key_verification_verify_title_emoji" = "Confronta emoji";
"key_verification_verify_title_number" = "Confronta numeri";

View file

@ -212,7 +212,7 @@
"room_delete_unsent_messages" = "未送信の文を削除";
"room_event_action_copy" = "複写";
"room_event_action_quote" = "引用";
"room_event_action_redact" = "編集";
"room_event_action_redact" = "移動して削除";
"room_event_action_more" = "さらに";
"room_event_action_share" = "共有";
"room_event_action_permalink" = "直リンク";
@ -568,3 +568,6 @@
// Accessibility
"accessibility_checkbox_label" = "チェックボックス";
"auth_login_single_sign_on" = "シングルサインオン(SSO)でサインイン";
"auth_softlogout_clear_data_sign_out" = "サインアウト";
"room_message_unable_open_link_error_message" = "リンクを開くことができません。";
"user_verification_session_details_verify_action_other_user" = "手動で確認";

View file

@ -810,22 +810,26 @@ internal enum VectorL10n {
internal static var deviceVerificationIncomingTitle: String {
return VectorL10n.tr("Vector", "device_verification_incoming_title")
}
/// For maximum security, we recommend you do this in person or use another trusted means of communication
internal static var deviceVerificationSecurityAdvice: String {
return VectorL10n.tr("Vector", "device_verification_security_advice")
/// Compare the unique emoji, ensuring they appear in the same order.
internal static var deviceVerificationSecurityAdviceEmoji: String {
return VectorL10n.tr("Vector", "device_verification_security_advice_emoji")
}
/// This wasn't me
internal static var deviceVerificationSelfVerifyAlertCancelAction: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_cancel_action")
/// Compare the numbers, ensuring they appear in the same order.
internal static var deviceVerificationSecurityAdviceNumber: String {
return VectorL10n.tr("Vector", "device_verification_security_advice_number")
}
/// Use this session to verify your new one, granting it access to encrypted messages: %@\nIf you didnt sign in to this session, your account may be compromised.
/// Verify the new login accessing your account: %@
internal static func deviceVerificationSelfVerifyAlertMessage(_ p1: String) -> String {
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_message", p1)
}
/// New Sign In
/// New login. Was this you?
internal static var deviceVerificationSelfVerifyAlertTitle: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_title")
}
/// Verify
internal static var deviceVerificationSelfVerifyAlertValidateAction: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_validate_action")
}
/// Use this session to verify your new one, granting it access to encrypted messages.
internal static var deviceVerificationSelfVerifyStartInformation: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_start_information")
@ -842,7 +846,7 @@ internal enum VectorL10n {
internal static var deviceVerificationSelfVerifyWaitAdditionalInformation: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_additional_information")
}
/// Verify this session from one of your others sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:
/// Verify this session from one of your other sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:
internal static var deviceVerificationSelfVerifyWaitInformation: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_information")
}
@ -874,18 +878,6 @@ internal enum VectorL10n {
internal static var deviceVerificationStartWaitPartner: String {
return VectorL10n.tr("Vector", "device_verification_start_wait_partner")
}
/// Verify session
internal static var deviceVerificationTitle: String {
return VectorL10n.tr("Vector", "device_verification_title")
}
/// You've successfully verified this session.
internal static var deviceVerificationVerifiedDescription1: String {
return VectorL10n.tr("Vector", "device_verification_verified_description_1")
}
/// Secure messages with this user are end-to-end encrypted and not able to be read by third parties.
internal static var deviceVerificationVerifiedDescription2: String {
return VectorL10n.tr("Vector", "device_verification_verified_description_2")
}
/// Got it
internal static var deviceVerificationVerifiedGotItButton: String {
return VectorL10n.tr("Vector", "device_verification_verified_got_it_button")
@ -894,14 +886,6 @@ internal enum VectorL10n {
internal static var deviceVerificationVerifiedTitle: String {
return VectorL10n.tr("Vector", "device_verification_verified_title")
}
/// Verify this session by confirming the following emoji appear on the screen of the partner
internal static var deviceVerificationVerifyTitleEmoji: String {
return VectorL10n.tr("Vector", "device_verification_verify_title_emoji")
}
/// Verify this session by confirming the following numbers appear on the screen of the partner
internal static var deviceVerificationVerifyTitleNumber: String {
return VectorL10n.tr("Vector", "device_verification_verify_title_number")
}
/// Waiting for partner to confirm
internal static var deviceVerificationVerifyWaitPartner: String {
return VectorL10n.tr("Vector", "device_verification_verify_wait_partner")
@ -1542,6 +1526,14 @@ internal enum VectorL10n {
internal static func keyVerificationIncomingRequestIncomingAlertMessage(_ p1: String) -> String {
return VectorL10n.tr("Vector", "key_verification_incoming_request_incoming_alert_message", p1)
}
/// Verify your new session
internal static var keyVerificationNewSessionTitle: String {
return VectorL10n.tr("Vector", "key_verification_new_session_title")
}
/// Verify session
internal static var keyVerificationOtherSessionTitle: String {
return VectorL10n.tr("Vector", "key_verification_other_session_title")
}
/// Is the other device showing the same shield?
internal static var keyVerificationScanConfirmationScannedDeviceInformation: String {
return VectorL10n.tr("Vector", "key_verification_scan_confirmation_scanned_device_information")
@ -1566,6 +1558,22 @@ internal enum VectorL10n {
internal static func keyVerificationScanConfirmationScanningUserWaitingOther(_ p1: String) -> String {
return VectorL10n.tr("Vector", "key_verification_scan_confirmation_scanning_user_waiting_other", p1)
}
/// Other users may not trust it.
internal static var keyVerificationSelfVerifyCurrentSessionAlertMessage: String {
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_message")
}
/// Verify this session
internal static var keyVerificationSelfVerifyCurrentSessionAlertTitle: String {
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_title")
}
/// Verify
internal static var keyVerificationSelfVerifyCurrentSessionAlertValidateAction: String {
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_validate_action")
}
/// Verify this session
internal static var keyVerificationThisSessionTitle: String {
return VectorL10n.tr("Vector", "key_verification_this_session_title")
}
/// Verified
internal static var keyVerificationTileConclusionDoneTitle: String {
return VectorL10n.tr("Vector", "key_verification_tile_conclusion_done_title")
@ -1614,22 +1622,38 @@ internal enum VectorL10n {
internal static var keyVerificationTileRequestStatusWaiting: String {
return VectorL10n.tr("Vector", "key_verification_tile_request_status_waiting")
}
/// Verify user
/// Verify them
internal static var keyVerificationUserTitle: String {
return VectorL10n.tr("Vector", "key_verification_user_title")
}
/// Youve successfully verified this user.
internal static var keyVerificationVerifiedUserDescription1: String {
return VectorL10n.tr("Vector", "key_verification_verified_user_description_1")
/// You can now read secure messages on your new device, and other users will know they can trust it.
internal static var keyVerificationVerifiedNewSessionInformation: String {
return VectorL10n.tr("Vector", "key_verification_verified_new_session_information")
}
/// Messages with this user in this room are end-to-end encrypted and cant be read by third parties.
internal static var keyVerificationVerifiedUserDescription2: String {
return VectorL10n.tr("Vector", "key_verification_verified_user_description_2")
/// New session verified!
internal static var keyVerificationVerifiedNewSessionTitle: String {
return VectorL10n.tr("Vector", "key_verification_verified_new_session_title")
}
/// You can now read secure messages on your other session, and other users will know they can trust it.
internal static var keyVerificationVerifiedOtherSessionInformation: String {
return VectorL10n.tr("Vector", "key_verification_verified_other_session_information")
}
/// You can now read secure messages on this device, and other users will know they can trust it.
internal static var keyVerificationVerifiedThisSessionInformation: String {
return VectorL10n.tr("Vector", "key_verification_verified_this_session_information")
}
/// Messages with this user are end-to-end encrypted and can't be read by third parties.
internal static var keyVerificationVerifiedUserInformation: String {
return VectorL10n.tr("Vector", "key_verification_verified_user_information")
}
/// Can't scan?
internal static var keyVerificationVerifyQrCodeCannotScanAction: String {
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_cannot_scan_action")
}
/// Verify by comparing unique emoji.
internal static var keyVerificationVerifyQrCodeEmojiInformation: String {
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_emoji_information")
}
/// Scan the code to securely verify each other.
internal static var keyVerificationVerifyQrCodeInformation: String {
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_information")
@ -1650,17 +1674,33 @@ internal enum VectorL10n {
internal static var keyVerificationVerifyQrCodeScanOtherCodeSuccessTitle: String {
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_scan_other_code_success_title")
}
/// Verify by emoji
internal static var keyVerificationVerifyQrCodeStartEmojiAction: String {
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_start_emoji_action")
}
/// Verify by scanning
internal static var keyVerificationVerifyQrCodeTitle: String {
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_title")
}
/// Verify this user by confirming the following unique emoji appears on their screen, in the same order.
internal static var keyVerificationVerifyUserTitleEmoji: String {
return VectorL10n.tr("Vector", "key_verification_verify_user_title_emoji")
/// For ultimate security, use another trusted means of communication or do this in person.
internal static var keyVerificationVerifySasAdditionalInformation: String {
return VectorL10n.tr("Vector", "key_verification_verify_sas_additional_information")
}
/// Verify this user by confirming the following numbers appear on their screen, in the same order.
internal static var keyVerificationVerifyUserTitleNumber: String {
return VectorL10n.tr("Vector", "key_verification_verify_user_title_number")
/// They don't match
internal static var keyVerificationVerifySasCancelAction: String {
return VectorL10n.tr("Vector", "key_verification_verify_sas_cancel_action")
}
/// Compare emoji
internal static var keyVerificationVerifySasTitleEmoji: String {
return VectorL10n.tr("Vector", "key_verification_verify_sas_title_emoji")
}
/// Compare numbers
internal static var keyVerificationVerifySasTitleNumber: String {
return VectorL10n.tr("Vector", "key_verification_verify_sas_title_number")
}
/// They match
internal static var keyVerificationVerifySasValidateAction: String {
return VectorL10n.tr("Vector", "key_verification_verify_sas_validate_action")
}
/// %.1fK
internal static func largeBadgeValueKFormat(_ p1: Float) -> String {

View file

@ -32,7 +32,7 @@ final class RiotSettings: NSObject {
static let pinRoomsWithUnreadMessages = "pinRoomsWithUnread"
static let allowStunServerFallback = "allowStunServerFallback"
static let stunServerFallback = "stunServerFallback"
static let enableDMKeyVerification = "enableDMKeyVerification"
static let hideVerifyThisSessionAlert = "hideVerifyThisSessionAlert"
}
static let shared = RiotSettings()
@ -134,4 +134,14 @@ final class RiotSettings: NSObject {
var stunServerFallback: String? {
return UserDefaults.standard.string(forKey: UserDefaultsKeys.stunServerFallback)
}
// MARK: Key verification
var hideVerifyThisSessionAlert: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
}
}
}

View file

@ -27,12 +27,6 @@
@interface AuthenticationViewController () <AuthFallBackViewControllerDelegate, KeyVerificationCoordinatorBridgePresenterDelegate>
{
/**
Store the potential login error received by using a default homeserver different from matrix.org
while we retry a login process against the matrix.org HS.
*/
NSError *loginError;
/**
The default country code used to initialize the mobile phone number input.
*/
@ -43,6 +37,11 @@
*/
id kThemeServiceDidChangeThemeNotificationObserver;
/**
Observe AppDelegateUniversalLinkDidChangeNotification to handle universal link changes.
*/
id universalLinkDidChangeNotificationObserver;
/**
Server discovery.
*/
@ -149,7 +148,12 @@
[self userInterfaceThemeDidChange];
}];
universalLinkDidChangeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:AppDelegateUniversalLinkDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) {
[self updateUniversalLink];
}];
[self userInterfaceThemeDidChange];
[self updateUniversalLink];
}
- (void)userInterfaceThemeDidChange
@ -224,6 +228,20 @@
[self setNeedsStatusBarAppearanceUpdate];
}
- (void)updateUniversalLink
{
UniversalLink *link = [AppDelegate theDelegate].lastHandledUniversalLink;
if (link)
{
NSString *emailAddress = link.queryParams[@"email"];
if (emailAddress && self.authInputsView)
{
AuthInputsView *inputsView = (AuthInputsView *)self.authInputsView;
inputsView.emailTextField.text = emailAddress;
}
}
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return ThemeService.shared.theme.statusBarStyle;
@ -270,6 +288,12 @@
kThemeServiceDidChangeThemeNotificationObserver = nil;
}
if (universalLinkDidChangeNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:universalLinkDidChangeNotificationObserver];
universalLinkDidChangeNotificationObserver = nil;
}
autoDiscovery = nil;
_keyVerificationCoordinatorBridgePresenter = nil;
}
@ -288,16 +312,7 @@
}
super.authType = authType;
// Check a potential stored error.
if (loginError)
{
// Restore the default HS
NSLog(@"[AuthenticationVC] Switch back to default homeserver");
[self setHomeServerTextFieldText:nil];
loginError = nil;
}
if (authType == MXKAuthenticationTypeLogin)
{
[self.submitButton setTitle:NSLocalizedStringFromTable(@"auth_login", @"Vector", nil) forState:UIControlStateNormal];
@ -683,6 +698,7 @@
if ([self.authInputsView isKindOfClass:AuthInputsView.class])
{
authInputsview = (AuthInputsView*)self.authInputsView;
[self updateUniversalLink];
}
// Hide "Forgot password" and "Log in" buttons in case of SSO
@ -845,76 +861,14 @@
- (void)onFailureDuringAuthRequest:(NSError *)error
{
// Homeserver migration: When the default homeserver url is different from matrix.org,
// the login (or forgot pwd) process with an existing matrix.org accounts will then fail.
// Patch: Falling back to matrix.org HS so we don't break everyone's logins
if ([self.homeServerTextField.text isEqualToString:self.defaultHomeServerUrl] && ![self.defaultHomeServerUrl isEqualToString:@"https://matrix.org"] && !self.softLogoutCredentials)
MXError *mxError = [[MXError alloc] initWithNSError:error];
if ([mxError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded])
{
MXError *mxError = [[MXError alloc] initWithNSError:error];
if (self.authType == MXKAuthenticationTypeLogin)
{
if (mxError && [mxError.errcode isEqualToString:kMXErrCodeStringForbidden])
{
// Falling back to matrix.org HS
NSLog(@"[AuthenticationVC] Retry login against matrix.org");
// Store the current error, and change the homeserver url
loginError = error;
[self setHomeServerTextFieldText:@"https://matrix.org"];
// Trigger a new request
[self onButtonPressed:self.submitButton];
return;
}
}
else if (self.authType == MXKAuthenticationTypeForgotPassword)
{
if (mxError && [mxError.errcode isEqualToString:kMXErrCodeStringNotFound])
{
// Sanity check
if ([self.authInputsView isKindOfClass:ForgotPasswordInputsView.class])
{
// Falling back to matrix.org HS
NSLog(@"[AuthenticationVC] Retry forgot password against matrix.org");
// Store the current error, and change the homeserver url
loginError = error;
[self setHomeServerTextFieldText:@"https://matrix.org"];
// Trigger a new request
ForgotPasswordInputsView *authInputsView = (ForgotPasswordInputsView*)self.authInputsView;
[authInputsView.nextStepButton sendActionsForControlEvents:UIControlEventTouchUpInside];
return;
}
}
}
}
// Check whether we were retrying against matrix.org HS
if (loginError)
{
// This is not an existing matrix.org accounts
NSLog(@"[AuthenticationVC] This is not an existing matrix.org accounts");
// Restore the default HS
[self setHomeServerTextFieldText:nil];
// Consider the original login error
[super onFailureDuringAuthRequest:loginError];
loginError = nil;
[self showResourceLimitExceededError:mxError.userInfo];
}
else
{
MXError *mxError = [[MXError alloc] initWithNSError:error];
if ([mxError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded])
{
[self showResourceLimitExceededError:mxError.userInfo];
}
else
{
[super onFailureDuringAuthRequest:error];
}
[super onFailureDuringAuthRequest:error];
}
}

View file

@ -0,0 +1,85 @@
/*
Copyright 2020 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import UIKit
final class RoundedButton: UIButton, Themable {
// MARK: - Constants
private enum Constants {
static let backgroundColorAlpha: CGFloat = 0.2
static let cornerRadius: CGFloat = 6.0
static let fontSize: CGFloat = 17.0
}
// MARK: - Properties
// MARK: Private
private var theme: Theme?
// MARK: Public
var actionStyle: UIAlertAction.Style = .default {
didSet {
self.updateButtonStyle()
}
}
// MARK: - Life cycle
override func awakeFromNib() {
super.awakeFromNib()
self.layer.masksToBounds = true
self.titleLabel?.font = UIFont.systemFont(ofSize: Constants.fontSize)
self.update(theme: ThemeService.shared().theme)
}
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = Constants.cornerRadius
}
// MARK: - Private
private func updateButtonStyle() {
guard let theme = theme else {
return
}
let backgroundColor: UIColor
switch self.actionStyle {
case .default:
backgroundColor = theme.tintColor
default:
backgroundColor = theme.noticeColor
}
self.vc_setBackgroundColor(backgroundColor.withAlphaComponent(Constants.backgroundColorAlpha), for: .normal)
self.setTitleColor(backgroundColor, for: .normal)
}
// MARK: - Themable
func update(theme: Theme) {
self.theme = theme
self.updateButtonStyle()
}
}

View file

@ -91,17 +91,27 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
self.session = session
self.verificationFlow = flow
if case let .incomingRequest(request) = flow {
let verificationKind: KeyVerificationKind
switch flow {
case .incomingRequest(let request):
if request.isFromMyUser {
self.verificationKind = .device
// TODO: Check for .newSession case
verificationKind = .otherSession
} else {
self.verificationKind = .user
verificationKind = .user
}
} else if case .verifyUser = flow {
self.verificationKind = .user
} else {
self.verificationKind = .device
case .verifyUser:
verificationKind = .user
case .completeSecurity:
verificationKind = .thisSession
case .verifyDevice:
verificationKind = .otherSession
case .incomingSASTransaction:
verificationKind = .otherSession
}
self.verificationKind = verificationKind
}
// MARK: - Public methods
@ -172,7 +182,7 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
}
private func createDataLoadingScreenCoordinator(otherUserId: String, otherDeviceId: String) -> KeyVerificationDataLoadingCoordinator {
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, verificationKind: self.verificationKind, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
coordinator.delegate = self
coordinator.start()
@ -180,7 +190,7 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
}
private func createDataLoadingScreenCoordinator(with keyVerificationRequest: MXKeyVerificationRequest) -> KeyVerificationDataLoadingCoordinator {
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, incomingKeyVerificationRequest: keyVerificationRequest)
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, verificationKind: self.verificationKind, incomingKeyVerificationRequest: keyVerificationRequest)
coordinator.delegate = self
coordinator.start()
@ -229,7 +239,7 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
}
private func showVerifyByScanning(keyVerificationRequest: MXKeyVerificationRequest, animated: Bool) {
let coordinator = KeyVerificationVerifyByScanningCoordinator(session: self.session, keyVerificationRequest: keyVerificationRequest)
let coordinator = KeyVerificationVerifyByScanningCoordinator(session: self.session, verificationKind: self.verificationKind, keyVerificationRequest: keyVerificationRequest)
coordinator.delegate = self
coordinator.start()
@ -363,10 +373,6 @@ extension KeyVerificationCoordinator: KeyVerificationVerifyByScanningCoordinator
self.didCancel()
}
func keyVerificationVerifyByScanningCoordinatorCannotScan(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType) {
self.showVerified(animated: true)
}
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, didScanOtherQRCodeData qrCodeData: MXQRCodeData, withTransaction transaction: MXQRCodeTransaction) {
self.showScanConfirmation(for: transaction, codeScanning: .scannedOtherQRCode(qrCodeData), animated: true)
}
@ -394,10 +400,15 @@ extension KeyVerificationCoordinator: KeyVerificationSelfVerifyStartCoordinatorD
// MARK: - KeyVerificationSelfVerifyWaitCoordinatorDelegate
extension KeyVerificationCoordinator: KeyVerificationSelfVerifyWaitCoordinatorDelegate {
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest) {
self.showVerifyByScanning(keyVerificationRequest: keyVerificationRequest, animated: true)
}
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction) {
self.showVerifyBySAS(transaction: incomingSASTransaction, animated: true)
}
func keyVerificationSelfVerifyWaitCoordinatorDidCancel(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType) {
self.didCancel()
}

View file

@ -39,6 +39,10 @@ final class KeyVerificationCoordinatorBridgePresenter: NSObject {
weak var delegate: KeyVerificationCoordinatorBridgePresenterDelegate?
var isPresenting: Bool {
return self.coordinator != nil
}
// MARK: - Setup
init(session: MXSession) {

View file

@ -16,6 +16,26 @@
import Foundation
enum KeyVerificationKind {
case device
case user
case otherSession // An other session
case thisSession // My current session is new
case newSession // My other session is new
case user // Another user
var verificationTitle: String {
let title: String
switch self {
case .otherSession:
title = VectorL10n.keyVerificationOtherSessionTitle
case .thisSession:
title = VectorL10n.keyVerificationThisSessionTitle
case .newSession:
title = VectorL10n.keyVerificationNewSessionTitle
case .user:
title = VectorL10n.keyVerificationUserTitle
}
return title
}
}

View file

@ -37,15 +37,15 @@ final class KeyVerificationDataLoadingCoordinator: KeyVerificationDataLoadingCoo
// MARK: - Setup
init(session: MXSession, otherUserId: String, otherDeviceId: String) {
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
init(session: MXSession, verificationKind: KeyVerificationKind, otherUserId: String, otherDeviceId: String) {
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, verificationKind: verificationKind, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
let keyVerificationDataLoadingViewController = KeyVerificationDataLoadingViewController.instantiate(with: keyVerificationDataLoadingViewModel)
self.keyVerificationDataLoadingViewModel = keyVerificationDataLoadingViewModel
self.keyVerificationDataLoadingViewController = keyVerificationDataLoadingViewController
}
init(session: MXSession, incomingKeyVerificationRequest: MXKeyVerificationRequest) {
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, keyVerificationRequest: incomingKeyVerificationRequest)
init(session: MXSession, verificationKind: KeyVerificationKind, incomingKeyVerificationRequest: MXKeyVerificationRequest) {
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, verificationKind: verificationKind, keyVerificationRequest: incomingKeyVerificationRequest)
let keyVerificationDataLoadingViewController = KeyVerificationDataLoadingViewController.instantiate(with: keyVerificationDataLoadingViewModel)
self.keyVerificationDataLoadingViewModel = keyVerificationDataLoadingViewModel
self.keyVerificationDataLoadingViewController = keyVerificationDataLoadingViewController

View file

@ -47,7 +47,7 @@ final class KeyVerificationDataLoadingViewController: UIViewController {
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.title = self.viewModel.verificationKind.verificationTitle
self.vc_removeBackTitle()
self.setupViews()

View file

@ -31,6 +31,7 @@ final class KeyVerificationDataLoadingViewModel: KeyVerificationDataLoadingViewM
// MARK: Private
private let session: MXSession
private(set) var verificationKind: KeyVerificationKind
private let otherUserId: String?
private let otherDeviceId: String?
private let keyVerificationService = KeyVerificationService()
@ -46,15 +47,17 @@ final class KeyVerificationDataLoadingViewModel: KeyVerificationDataLoadingViewM
// MARK: - Setup
init(session: MXSession, otherUserId: String, otherDeviceId: String) {
init(session: MXSession, verificationKind: KeyVerificationKind, otherUserId: String, otherDeviceId: String) {
self.session = session
self.verificationKind = verificationKind
self.otherUserId = otherUserId
self.otherDeviceId = otherDeviceId
self.keyVerificationRequest = nil
}
init(session: MXSession, keyVerificationRequest: MXKeyVerificationRequest) {
init(session: MXSession, verificationKind: KeyVerificationKind, keyVerificationRequest: MXKeyVerificationRequest) {
self.session = session
self.verificationKind = verificationKind
self.otherUserId = nil
self.otherDeviceId = nil
self.keyVerificationRequest = keyVerificationRequest

View file

@ -35,5 +35,7 @@ protocol KeyVerificationDataLoadingViewModelType {
var viewDelegate: KeyVerificationDataLoadingViewModelViewDelegate? { get set }
var coordinatorDelegate: KeyVerificationDataLoadingViewModelCoordinatorDelegate? { get set }
var verificationKind: KeyVerificationKind { get }
func process(viewAction: KeyVerificationDataLoadingViewAction)
}

View file

@ -61,7 +61,7 @@
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="8Ou-Xh-0rC">
<rect key="frame" x="0.0" y="48" width="374" height="40"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kBt-2D-25V">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kBt-2D-25V" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="182" height="40"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="No">
@ -71,7 +71,7 @@
<action selector="rejectButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="qCV-Oh-YAG"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="03A-fe-h3s">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="03A-fe-h3s" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="192" y="0.0" width="182" height="40"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Yes">

View file

@ -22,11 +22,6 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
// MARK: - Constants
private enum Constants {
static let buttonBackgroundColorAlpha: CGFloat = 0.2
static let buttonCornerRadius: CGFloat = 6.0
}
// MARK: - Properties
// MARK: Outlets
@ -39,8 +34,8 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
@IBOutlet private weak var scannedContentView: UIView!
@IBOutlet private weak var scannedInformationLabel: UILabel!
@IBOutlet private weak var rejectButton: UIButton!
@IBOutlet private weak var confirmButton: UIButton!
@IBOutlet private weak var rejectButton: RoundedButton!
@IBOutlet private weak var confirmButton: RoundedButton!
// MARK: Private
@ -76,15 +71,6 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
self.viewModel.process(viewAction: .loadData)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if self.scannedContentView.isHidden == false {
self.confirmButton.layer.cornerRadius = Constants.buttonCornerRadius
self.rejectButton.layer.cornerRadius = Constants.buttonCornerRadius
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
@ -111,8 +97,8 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
self.titleLabel.textColor = theme.textPrimaryColor
self.waitingLabel.textColor = theme.textSecondaryColor
self.scannedInformationLabel.textColor = theme.textPrimaryColor
self.confirmButton.vc_setBackgroundColor(theme.tintColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
self.rejectButton.vc_setBackgroundColor(theme.noticeColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
self.confirmButton.update(theme: theme)
self.rejectButton.update(theme: theme)
}
private func registerThemeServiceDidChangeThemeNotification() {
@ -130,10 +116,12 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
self.title = VectorL10n.keyVerificationVerifyQrCodeTitle
self.confirmButton.layer.masksToBounds = true
self.rejectButton.layer.masksToBounds = true
self.confirmButton.setTitle(Bundle.mxk_localizedString(forKey: "yes"), for: .normal)
self.rejectButton.setTitle(Bundle.mxk_localizedString(forKey: "no"), for: .normal)
self.rejectButton.actionStyle = .cancel
}
private func render(viewState: KeyVerificationScanConfirmationViewState) {
@ -169,7 +157,7 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
title = VectorL10n.keyVerificationScanConfirmationScanningTitle
switch viewData.verificationKind {
case .device:
case .otherSession, .thisSession, .newSession:
waitingInfo = VectorL10n.keyVerificationScanConfirmationScanningDeviceWaitingOther
case .user:
waitingInfo = VectorL10n.keyVerificationScanConfirmationScanningUserWaitingOther(viewData.otherDisplayName)
@ -178,13 +166,14 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
title = VectorL10n.keyVerificationScanConfirmationScannedTitle
switch viewData.verificationKind {
case .device:
case .otherSession, .thisSession, .newSession:
scannedInfo = VectorL10n.keyVerificationScanConfirmationScannedDeviceInformation
case .user:
scannedInfo = VectorL10n.keyVerificationScanConfirmationScannedUserInformation(viewData.otherDisplayName)
}
}
self.title = viewData.verificationKind.verificationTitle
self.titleLabel.text = title
self.waitingLabel.text = waitingInfo
self.scannedInformationLabel.text = scannedInfo

View file

@ -22,10 +22,10 @@
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="c4q-B8-hPy">
<rect key="frame" x="0.0" y="0.0" width="375" height="432.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="345"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fNE-v3-2lx">
<rect key="frame" x="0.0" y="0.0" width="375" height="432.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="345"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Verified!" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1Nw-CZ-lKr">
<rect key="frame" x="20" y="60" width="335" height="20.5"/>
@ -33,73 +33,49 @@
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="12d-Dc-Rlv">
<rect key="frame" x="20" y="160.5" width="335" height="102"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="You've successfully verified this device." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5dj-7z-eH5">
<rect key="frame" x="0.0" y="0.0" width="335" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Secure messages with this user are end-to-end encrypted and not able to be read by third parties." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="spd-ah-EYp">
<rect key="frame" x="0.0" y="48" width="335" height="54"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="50" translatesAutoresizingMaskIntoConstraints="NO" id="4Ll-vk-JLe">
<rect key="frame" x="0.0" y="362.5" width="375" height="50"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wbk-EX-kTs">
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kgv-EZ-dF9">
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="WcJ-IL-5KV"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
<state key="normal" title="Got it">
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="1" colorSpace="calibratedRGB"/>
</state>
<state key="disabled">
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="0.5" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="validateButtonAction:" destination="dBQ-CG-VDL" eventType="touchUpInside" id="kpR-g5-ogv"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="kgv-EZ-dF9" firstAttribute="top" secondItem="Wbk-EX-kTs" secondAttribute="top" id="1mu-8N-etF"/>
<constraint firstAttribute="bottom" secondItem="kgv-EZ-dF9" secondAttribute="bottom" id="2ce-b1-aV5"/>
<constraint firstAttribute="trailing" secondItem="kgv-EZ-dF9" secondAttribute="trailing" id="OHz-zo-Uvl"/>
<constraint firstAttribute="width" priority="750" constant="500" id="eud-Ba-XSx"/>
<constraint firstItem="kgv-EZ-dF9" firstAttribute="leading" secondItem="Wbk-EX-kTs" secondAttribute="leading" id="gPb-HX-NWn"/>
</constraints>
</view>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="You've successfully verified this device." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Sql-oR-dMk">
<rect key="frame" x="20" y="103" width="335" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="key_verification_success_shield" translatesAutoresizingMaskIntoConstraints="NO" id="ie2-LW-ek2">
<rect key="frame" x="127.5" y="141" width="120" height="120"/>
<constraints>
<constraint firstAttribute="width" secondItem="ie2-LW-ek2" secondAttribute="height" multiplier="1:1" id="Re6-8V-peU"/>
<constraint firstAttribute="width" constant="120" id="qg0-4Z-ffM"/>
</constraints>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4i8-Se-1Ae" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="20" y="281" width="335" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="XNP-zj-OmI"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Got it">
<color key="titleColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="doneButtonAction:" destination="dBQ-CG-VDL" eventType="touchUpInside" id="LL5-rw-xwL"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="12d-Dc-Rlv" firstAttribute="leading" secondItem="1Nw-CZ-lKr" secondAttribute="leading" id="5Kb-MI-4lP"/>
<constraint firstAttribute="width" priority="750" constant="500" id="9am-iX-rzi"/>
<constraint firstAttribute="trailing" secondItem="4Ll-vk-JLe" secondAttribute="trailing" id="CU4-Sr-hLT"/>
<constraint firstItem="12d-Dc-Rlv" firstAttribute="trailing" secondItem="1Nw-CZ-lKr" secondAttribute="trailing" id="Cax-X9-xf8"/>
<constraint firstItem="4Ll-vk-JLe" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" id="FGu-8C-v1U"/>
<constraint firstItem="4Ll-vk-JLe" firstAttribute="top" secondItem="12d-Dc-Rlv" secondAttribute="bottom" constant="100" id="Hue-GK-ORf"/>
<constraint firstItem="ie2-LW-ek2" firstAttribute="centerX" secondItem="fNE-v3-2lx" secondAttribute="centerX" id="BN9-ZW-6DE"/>
<constraint firstAttribute="trailing" secondItem="Sql-oR-dMk" secondAttribute="trailing" constant="20" id="JtB-5o-vhc"/>
<constraint firstAttribute="bottom" secondItem="4i8-Se-1Ae" secondAttribute="bottom" constant="20" id="KB5-ba-4Rb"/>
<constraint firstItem="1Nw-CZ-lKr" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" constant="20" id="LK5-9b-xDf"/>
<constraint firstItem="1Nw-CZ-lKr" firstAttribute="top" secondItem="fNE-v3-2lx" secondAttribute="top" constant="60" id="MUK-4D-vke"/>
<constraint firstAttribute="bottom" secondItem="4Ll-vk-JLe" secondAttribute="bottom" constant="20" id="Vn1-zQ-G8t"/>
<constraint firstItem="4i8-Se-1Ae" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" constant="20" id="WK8-b7-t31"/>
<constraint firstAttribute="trailing" secondItem="1Nw-CZ-lKr" secondAttribute="trailing" constant="20" id="WKJ-Ta-cVg"/>
<constraint firstItem="12d-Dc-Rlv" firstAttribute="centerX" secondItem="fNE-v3-2lx" secondAttribute="centerX" id="ksz-nC-DeX"/>
<constraint firstItem="12d-Dc-Rlv" firstAttribute="top" secondItem="1Nw-CZ-lKr" secondAttribute="bottom" constant="80" id="rhF-BF-2cR"/>
<constraint firstItem="Sql-oR-dMk" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" constant="20" id="kev-re-wea"/>
<constraint firstItem="Sql-oR-dMk" firstAttribute="top" secondItem="1Nw-CZ-lKr" secondAttribute="bottom" constant="22.5" id="kjt-Ha-so6"/>
<constraint firstItem="4i8-Se-1Ae" firstAttribute="top" secondItem="ie2-LW-ek2" secondAttribute="bottom" constant="20" id="miU-BN-TBQ"/>
<constraint firstItem="ie2-LW-ek2" firstAttribute="top" secondItem="Sql-oR-dMk" secondAttribute="bottom" constant="20" id="w1A-1P-Q9Q"/>
<constraint firstAttribute="trailing" secondItem="4i8-Se-1Ae" secondAttribute="trailing" constant="20" id="wEW-BU-RMg"/>
</constraints>
</view>
</subviews>
@ -134,16 +110,17 @@
<viewLayoutGuide key="safeArea" id="6ex-OQ-2sZ"/>
</view>
<connections>
<outlet property="description1Label" destination="5dj-7z-eH5" id="y4w-i9-5hB"/>
<outlet property="description2Label" destination="spd-ah-EYp" id="TXD-8P-gF0"/>
<outlet property="okButton" destination="kgv-EZ-dF9" id="do0-Ot-OKn"/>
<outlet property="okButtonBackgroundView" destination="Wbk-EX-kTs" id="2gv-gg-ROL"/>
<outlet property="doneButton" destination="4i8-Se-1Ae" id="K4a-4m-cU2"/>
<outlet property="informationLabel" destination="Sql-oR-dMk" id="aIw-XY-wP1"/>
<outlet property="titleLabel" destination="1Nw-CZ-lKr" id="zXP-Xt-Zl9"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="bLY-II-iJ3" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1703" y="255"/>
<point key="canvasLocation" x="-1703.2" y="254.12293853073464"/>
</scene>
</scenes>
<resources>
<image name="key_verification_success_shield" width="120" height="120"/>
</resources>
</document>

View file

@ -30,11 +30,8 @@ final class KeyVerificationVerifiedViewController: UIViewController {
// MARK: Outlets
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var description1Label: UILabel!
@IBOutlet private weak var description2Label: UILabel!
@IBOutlet private weak var okButtonBackgroundView: UIView!
@IBOutlet private weak var okButton: UIButton!
@IBOutlet private weak var informationLabel: UILabel!
@IBOutlet private weak var doneButton: RoundedButton!
// MARK: Private
@ -82,30 +79,29 @@ final class KeyVerificationVerifiedViewController: UIViewController {
// MARK: - Private
private func setupViews() {
let title: String
let bodyTitle: String
let descriptionTextPart1: String
let descriptionTextPart2: String
let informationText: String
switch self.verificationKind {
case .device:
title = VectorL10n.deviceVerificationTitle
case .otherSession:
bodyTitle = VectorL10n.deviceVerificationVerifiedTitle
descriptionTextPart1 = VectorL10n.deviceVerificationVerifiedDescription1
descriptionTextPart2 = VectorL10n.deviceVerificationVerifiedDescription2
informationText = VectorL10n.keyVerificationVerifiedOtherSessionInformation
case .newSession:
bodyTitle = VectorL10n.keyVerificationVerifiedNewSessionTitle
informationText = VectorL10n.keyVerificationVerifiedNewSessionInformation
case .thisSession:
bodyTitle = VectorL10n.deviceVerificationVerifiedTitle
informationText = VectorL10n.keyVerificationVerifiedThisSessionInformation
case .user:
title = VectorL10n.keyVerificationUserTitle
bodyTitle = VectorL10n.deviceVerificationVerifiedTitle
descriptionTextPart1 = VectorL10n.keyVerificationVerifiedUserDescription1
descriptionTextPart2 = VectorL10n.keyVerificationVerifiedUserDescription2
informationText = VectorL10n.keyVerificationVerifiedUserInformation
}
self.title = title
self.title = self.verificationKind.verificationTitle
self.titleLabel.text = bodyTitle
self.description1Label.text = descriptionTextPart1
self.description2Label.text = descriptionTextPart2
self.informationLabel.text = informationText
self.okButton.setTitle(VectorL10n.deviceVerificationVerifiedGotItButton, for: .normal)
self.doneButton.setTitle(VectorL10n.deviceVerificationVerifiedGotItButton, for: .normal)
}
private func update(theme: Theme) {
@ -118,11 +114,8 @@ final class KeyVerificationVerifiedViewController: UIViewController {
}
self.titleLabel.textColor = theme.textPrimaryColor
self.description1Label.textColor = theme.textPrimaryColor
self.description2Label.textColor = theme.textPrimaryColor
self.okButtonBackgroundView.backgroundColor = theme.backgroundColor
theme.applyStyle(onButton: self.okButton)
self.informationLabel.textColor = theme.textPrimaryColor
self.doneButton.update(theme: theme)
}
private func registerThemeServiceDidChangeThemeNotification() {
@ -135,7 +128,7 @@ final class KeyVerificationVerifiedViewController: UIViewController {
self.update(theme: ThemeService.shared().theme)
}
@IBAction private func validateButtonAction(_ sender: Any) {
@IBAction private func doneButtonAction(_ sender: Any) {
self.delegate?.keyVerificationVerifiedViewControllerDidTapSetupAction(self)
}
}

View file

@ -22,12 +22,12 @@
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e7g-um-WO4">
<rect key="frame" x="0.0" y="0.0" width="375" height="485"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="502"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="voD-3Q-ryt">
<rect key="frame" x="0.0" y="0.0" width="375" height="485"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="502"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Verify this device by confirming the following emoji appear on the screen of the partner" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="he8-pl-xE9">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Compare emoji" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="he8-pl-xE9">
<rect key="frame" x="20" y="35" width="335" height="61"/>
<constraints>
<constraint firstAttribute="height" constant="61" id="Nam-ca-50k"/>
@ -37,16 +37,13 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For maximum security, we recommend you do this in person or use another trusted means of communication." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bxI-mu-qng">
<rect key="frame" x="20" y="115" width="335" height="80"/>
<constraints>
<constraint firstAttribute="height" constant="80" id="3ag-pn-F2b"/>
</constraints>
<rect key="frame" x="20" y="115" width="335" height="54"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3152 3307 8179" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RD6-ue-X5c">
<rect key="frame" x="37.5" y="290.5" width="300" height="29"/>
<rect key="frame" x="37.5" y="264.5" width="300" height="29"/>
<constraints>
<constraint firstAttribute="width" constant="300" id="6Q5-M2-ifj"/>
</constraints>
@ -54,39 +51,8 @@
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DtR-jx-UKY">
<rect key="frame" x="0.0" y="415" width="375" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DOt-5E-FjF">
<rect key="frame" x="156.5" y="10" width="62" height="30"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" title="Continue">
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="continueButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="uvI-tt-Nfj"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="DOt-5E-FjF" firstAttribute="centerY" secondItem="DtR-jx-UKY" secondAttribute="centerY" id="5eX-a5-zpP"/>
<constraint firstItem="DOt-5E-FjF" firstAttribute="centerX" secondItem="DtR-jx-UKY" secondAttribute="centerX" id="6v9-MN-mk2"/>
<constraint firstAttribute="height" constant="50" id="QNq-au-ZdL"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Waiting for partner to confirm..." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6yX-xD-4X5">
<rect key="frame" x="20" y="242" width="335" height="54"/>
<constraints>
<constraint firstAttribute="width" constant="335" id="9C0-ev-AVw"/>
<constraint firstAttribute="height" constant="54" id="pta-eP-0yH"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="34i-3X-YvQ">
<rect key="frame" x="27.5" y="215" width="320" height="180"/>
<rect key="frame" x="27.5" y="189" width="320" height="180"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="180" id="kpT-ty-CDI"/>
@ -138,25 +104,75 @@
<outlet property="dataSource" destination="V8j-Lb-PgC" id="3m4-oH-KIj"/>
</connections>
</collectionView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="6xJ-uL-C85">
<rect key="frame" x="20" y="389" width="335" height="44"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Zsb-KY-oCN" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="162.5" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="They don't match">
<color key="titleColor" red="1" green="0.29411764709999999" blue="0.33333333329999998" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="cancelButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="1NK-nX-rMW"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FvW-07-g2Q" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="172.5" y="0.0" width="162.5" height="44"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="They match">
<color key="titleColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="validateButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="rFZ-xl-1u8"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="Zsb-KY-oCN" firstAttribute="height" secondItem="6xJ-uL-C85" secondAttribute="height" priority="999" id="Ndm-lB-EyV"/>
<constraint firstItem="FvW-07-g2Q" firstAttribute="height" secondItem="6xJ-uL-C85" secondAttribute="height" priority="999" id="hq6-8l-unN"/>
<constraint firstAttribute="height" priority="750" constant="44" id="lIN-Z9-vVI"/>
</constraints>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Waiting for partner to confirm..." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6yX-xD-4X5">
<rect key="frame" x="20" y="242" width="335" height="54"/>
<constraints>
<constraint firstAttribute="width" constant="335" id="9C0-ev-AVw"/>
<constraint firstAttribute="height" constant="54" id="pta-eP-0yH"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For ultimate security, use another trusted means of communication or do this in person." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gDW-77-nwN">
<rect key="frame" x="20" y="453" width="335" height="29"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="6yX-xD-4X5" firstAttribute="top" secondItem="bxI-mu-qng" secondAttribute="bottom" constant="47" id="6Bh-e4-HVr"/>
<constraint firstAttribute="bottom" secondItem="DtR-jx-UKY" secondAttribute="bottom" constant="20" id="Cnb-UW-hYt"/>
<constraint firstAttribute="trailing" secondItem="DtR-jx-UKY" secondAttribute="trailing" id="K7y-Df-dgz"/>
<constraint firstItem="6xJ-uL-C85" firstAttribute="top" secondItem="34i-3X-YvQ" secondAttribute="bottom" constant="20" id="BaX-9q-msm"/>
<constraint firstAttribute="trailing" secondItem="6xJ-uL-C85" secondAttribute="trailing" constant="20" id="G5w-nx-cbM"/>
<constraint firstAttribute="trailing" secondItem="gDW-77-nwN" secondAttribute="trailing" constant="20" id="Iel-ki-dp5"/>
<constraint firstItem="6xJ-uL-C85" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="MET-AV-3jS"/>
<constraint firstItem="he8-pl-xE9" firstAttribute="leading" secondItem="bxI-mu-qng" secondAttribute="leading" id="Q9n-7p-gHl"/>
<constraint firstItem="he8-pl-xE9" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="QSg-yz-aaB"/>
<constraint firstItem="6yX-xD-4X5" firstAttribute="centerX" secondItem="voD-3Q-ryt" secondAttribute="centerX" id="Rg4-jV-Nht"/>
<constraint firstItem="bxI-mu-qng" firstAttribute="top" secondItem="he8-pl-xE9" secondAttribute="top" constant="80" id="UL4-x0-oFT"/>
<constraint firstItem="gDW-77-nwN" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="YAC-Wy-mPL"/>
<constraint firstItem="he8-pl-xE9" firstAttribute="centerX" secondItem="voD-3Q-ryt" secondAttribute="centerX" id="ZP8-mV-RBh"/>
<constraint firstItem="he8-pl-xE9" firstAttribute="trailing" secondItem="bxI-mu-qng" secondAttribute="trailing" id="Zeg-U8-uis"/>
<constraint firstAttribute="width" priority="750" constant="375" id="glD-Sz-73O"/>
<constraint firstItem="RD6-ue-X5c" firstAttribute="centerY" secondItem="34i-3X-YvQ" secondAttribute="centerY" id="h8F-gc-do4"/>
<constraint firstItem="DtR-jx-UKY" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" id="hK0-aA-d9H"/>
<constraint firstItem="RD6-ue-X5c" firstAttribute="centerX" secondItem="34i-3X-YvQ" secondAttribute="centerX" id="lBM-R8-C6b"/>
<constraint firstItem="DtR-jx-UKY" firstAttribute="top" secondItem="34i-3X-YvQ" secondAttribute="bottom" constant="20" id="liF-Qn-tiw"/>
<constraint firstItem="34i-3X-YvQ" firstAttribute="top" secondItem="bxI-mu-qng" secondAttribute="bottom" constant="20" id="r7A-9g-Mmb"/>
<constraint firstAttribute="bottom" secondItem="gDW-77-nwN" secondAttribute="bottom" constant="20" id="rpv-yg-1jT"/>
<constraint firstItem="he8-pl-xE9" firstAttribute="top" secondItem="voD-3Q-ryt" secondAttribute="top" constant="35" id="s3k-Io-834"/>
<constraint firstItem="gDW-77-nwN" firstAttribute="top" secondItem="6xJ-uL-C85" secondAttribute="bottom" constant="20" id="wL6-tr-pO2"/>
<constraint firstItem="34i-3X-YvQ" firstAttribute="centerX" secondItem="voD-3Q-ryt" secondAttribute="centerX" id="ydb-Fs-K0a"/>
</constraints>
<variation key="default">
@ -179,7 +195,7 @@
<constraints>
<constraint firstAttribute="trailing" secondItem="e7g-um-WO4" secondAttribute="trailing" id="GyG-Fh-PME"/>
<constraint firstItem="e7g-um-WO4" firstAttribute="width" secondItem="9U2-KL-ZVA" secondAttribute="width" id="Ok2-WQ-Zgc"/>
<constraint firstAttribute="bottom" secondItem="e7g-um-WO4" secondAttribute="bottom" constant="70" id="Y46-NP-zAc"/>
<constraint firstAttribute="bottom" secondItem="e7g-um-WO4" secondAttribute="bottom" id="Y46-NP-zAc"/>
<constraint firstItem="e7g-um-WO4" firstAttribute="leading" secondItem="9U2-KL-ZVA" secondAttribute="leading" id="aoV-Yh-AcD"/>
<constraint firstItem="e7g-um-WO4" firstAttribute="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="pFN-bA-SHw"/>
</constraints>
@ -195,13 +211,15 @@
<viewLayoutGuide key="safeArea" id="bFg-jh-JZB"/>
</view>
<connections>
<outlet property="continueButton" destination="DOt-5E-FjF" id="ktw-U4-efQ"/>
<outlet property="continueButtonBackgroundView" destination="DtR-jx-UKY" id="9yG-wP-u8A"/>
<outlet property="additionalInformationLabel" destination="gDW-77-nwN" id="leX-Mb-wlj"/>
<outlet property="buttonsStackView" destination="6xJ-uL-C85" id="vK1-e2-OYg"/>
<outlet property="cancelButton" destination="Zsb-KY-oCN" id="xdE-MX-gp9"/>
<outlet property="decimalLabel" destination="RD6-ue-X5c" id="wlK-nl-CB6"/>
<outlet property="emojisCollectionView" destination="34i-3X-YvQ" id="wDE-oG-peo"/>
<outlet property="informationLabel" destination="bxI-mu-qng" id="pbX-aZ-inC"/>
<outlet property="scrollView" destination="9U2-KL-ZVA" id="ojG-2y-X7b"/>
<outlet property="titleLabel" destination="he8-pl-xE9" id="btA-kv-E2B"/>
<outlet property="validateButton" destination="FvW-07-g2Q" id="cT2-ds-ORQ"/>
<outlet property="waitingPartnerLabel" destination="6yX-xD-4X5" id="fre-bc-Kma"/>
</connections>
</viewController>

View file

@ -33,9 +33,12 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
@IBOutlet private weak var decimalLabel: UILabel!
@IBOutlet private weak var emojisCollectionView: UICollectionView!
@IBOutlet private weak var waitingPartnerLabel: UILabel!
@IBOutlet private weak var continueButtonBackgroundView: UIView!
@IBOutlet private weak var continueButton: UIButton!
@IBOutlet private weak var buttonsStackView: UIStackView!
@IBOutlet private weak var cancelButton: RoundedButton!
@IBOutlet private weak var validateButton: RoundedButton!
@IBOutlet private weak var additionalInformationLabel: UILabel!
// MARK: Private
private var viewModel: KeyVerificationVerifyBySASViewModelType!
@ -99,8 +102,8 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
self.decimalLabel.textColor = theme.textPrimaryColor
self.waitingPartnerLabel.textColor = theme.textPrimaryColor
self.continueButtonBackgroundView.backgroundColor = theme.backgroundColor
theme.applyStyle(onButton: self.continueButton)
self.cancelButton.update(theme: theme)
self.validateButton.update(theme: theme)
emojisCollectionView.reloadData()
}
@ -115,7 +118,7 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
private func setupViews() {
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
self?.cancelButtonAction()
self?.cancelAction()
}
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
@ -131,29 +134,29 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
self.decimalLabel.text = self.viewModel.decimal
}
let title: String
let instructionText: String
let adviceText: String
switch viewModel.verificationKind {
case .device:
title = VectorL10n.deviceVerificationTitle
instructionText = isVerificationByEmoji ? VectorL10n.deviceVerificationVerifyTitleEmoji : VectorL10n.deviceVerificationVerifyTitleNumber
adviceText = VectorL10n.deviceVerificationSecurityAdvice
case .user:
title = VectorL10n.keyVerificationUserTitle
instructionText = isVerificationByEmoji ? VectorL10n.keyVerificationVerifyUserTitleEmoji : VectorL10n.keyVerificationVerifyUserTitleNumber
adviceText = VectorL10n.deviceVerificationSecurityAdvice
if isVerificationByEmoji {
instructionText = VectorL10n.keyVerificationVerifySasTitleEmoji
adviceText = VectorL10n.deviceVerificationSecurityAdviceEmoji
} else {
instructionText = VectorL10n.keyVerificationVerifySasTitleNumber
adviceText = VectorL10n.deviceVerificationSecurityAdviceNumber
}
self.title = title
self.title = self.viewModel.verificationKind.verificationTitle
self.titleLabel.text = instructionText
self.informationLabel.text = adviceText
self.waitingPartnerLabel.text = VectorL10n.deviceVerificationVerifyWaitPartner
self.waitingPartnerLabel.isHidden = true
self.continueButton.setTitle(VectorL10n.continue, for: .normal)
self.cancelButton.setTitle(VectorL10n.keyVerificationVerifySasCancelAction, for: .normal)
self.cancelButton.actionStyle = .cancel
self.validateButton.setTitle(VectorL10n.keyVerificationVerifySasValidateAction, for: .normal)
self.additionalInformationLabel.text = VectorL10n.keyVerificationVerifySasAdditionalInformation
}
private func render(viewState: KeyVerificationVerifyViewState) {
@ -177,8 +180,8 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
private func renderVerified() {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.continueButtonBackgroundView.isHidden = true
self.buttonsStackView.isHidden = true
self.waitingPartnerLabel.isHidden = false
}
@ -210,13 +213,17 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
// MARK: - Actions
@IBAction private func continueButtonAction(_ sender: Any) {
self.viewModel.process(viewAction: .confirm)
}
private func cancelButtonAction() {
private func cancelAction() {
self.viewModel.process(viewAction: .cancel)
}
@IBAction private func cancelButtonAction(_ sender: Any) {
self.cancelAction()
}
@IBAction private func validateButtonAction(_ sender: Any) {
self.viewModel.process(viewAction: .confirm)
}
}

View file

@ -40,11 +40,11 @@ final class KeyVerificationVerifyByScanningCoordinator: KeyVerificationVerifyByS
// MARK: - Setup
init(session: MXSession, keyVerificationRequest: MXKeyVerificationRequest) {
init(session: MXSession, verificationKind: KeyVerificationKind, keyVerificationRequest: MXKeyVerificationRequest) {
self.session = session
self.keyVerificationRequest = keyVerificationRequest
let keyVerificationVerifyByScanningViewModel = KeyVerificationVerifyByScanningViewModel(session: self.session, keyVerificationRequest: keyVerificationRequest)
let keyVerificationVerifyByScanningViewModel = KeyVerificationVerifyByScanningViewModel(session: self.session, verificationKind: verificationKind, keyVerificationRequest: keyVerificationRequest)
let keyVerificationVerifyByScanningViewController = KeyVerificationVerifyByScanningViewController.instantiate(with: keyVerificationVerifyByScanningViewModel)
self.keyVerificationVerifyByScanningViewModel = keyVerificationVerifyByScanningViewModel
self.keyVerificationVerifyByScanningViewController = keyVerificationVerifyByScanningViewController
@ -66,11 +66,7 @@ extension KeyVerificationVerifyByScanningCoordinator: KeyVerificationVerifyBySca
func keyVerificationVerifyByScanningViewModelDidCancel(_ viewModel: KeyVerificationVerifyByScanningViewModelType) {
self.delegate?.keyVerificationVerifyByScanningCoordinatorDidCancel(self)
}
func keyVerificationVerifyByScanningViewModelCannotScan(_ viewModel: KeyVerificationVerifyByScanningViewModelType) {
self.delegate?.keyVerificationVerifyByScanningCoordinatorCannotScan(self)
}
}
func keyVerificationVerifyByScanningViewModel(_ viewModel: KeyVerificationVerifyByScanningViewModelType, didStartSASVerificationWithTransaction transaction: MXSASTransaction) {
self.delegate?.keyVerificationVerifyByScanningCoordinator(self, didCompleteWithSASTransaction: transaction)

View file

@ -19,8 +19,7 @@
import Foundation
protocol KeyVerificationVerifyByScanningCoordinatorDelegate: class {
func keyVerificationVerifyByScanningCoordinatorDidCancel(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType)
func keyVerificationVerifyByScanningCoordinatorCannotScan(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType)
func keyVerificationVerifyByScanningCoordinatorDidCancel(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType)
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, didScanOtherQRCodeData qrCodeData: MXQRCodeData, withTransaction transaction: MXQRCodeTransaction)
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, qrCodeDidScannedByOtherWithTransaction transaction: MXQRCodeTransaction)
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, didCompleteWithSASTransaction transaction: MXSASTransaction)

View file

@ -180,8 +180,16 @@ final class KeyVerificationVerifyByScanningViewController: UIViewController {
hideQRCodeImage = true
}
self.title = viewData.verificationKind.verificationTitle
self.titleLabel.text = viewData.verificationKind.verificationTitle
self.qrCodeContainerView.isHidden = hideQRCodeImage
self.scanButtonContainerView.isHidden = !viewData.showScanAction
if viewData.qrCodeData == nil && viewData.showScanAction == false {
// Update the copy if QR code scanning is not possible at all
self.informationLabel.text = VectorL10n.keyVerificationVerifyQrCodeEmojiInformation
self.cannotScanButton.setTitle(VectorL10n.keyVerificationVerifyQrCodeStartEmojiAction, for: .normal)
}
}
private func render(error: Error) {

View file

@ -29,6 +29,7 @@ final class KeyVerificationVerifyByScanningViewModel: KeyVerificationVerifyBySca
// MARK: Private
private let session: MXSession
private let verificationKind: KeyVerificationKind
private let keyVerificationRequest: MXKeyVerificationRequest
private let qrCodeDataCoder: MXQRCodeDataCoder
private let keyVerificationManager: MXKeyVerificationManager
@ -43,8 +44,9 @@ final class KeyVerificationVerifyByScanningViewModel: KeyVerificationVerifyBySca
// MARK: - Setup
init(session: MXSession, keyVerificationRequest: MXKeyVerificationRequest) {
init(session: MXSession, verificationKind: KeyVerificationKind, keyVerificationRequest: MXKeyVerificationRequest) {
self.session = session
self.verificationKind = verificationKind
self.keyVerificationManager = self.session.crypto.keyVerificationManager
self.keyVerificationRequest = keyVerificationRequest
self.qrCodeDataCoder = MXQRCodeDataCoder()
@ -94,7 +96,8 @@ final class KeyVerificationVerifyByScanningViewModel: KeyVerificationVerifyBySca
canShowScanAction = false
}
let viewData = KeyVerificationVerifyByScanningViewData(qrCodeData: qrCodePlayloadData,
let viewData = KeyVerificationVerifyByScanningViewData(verificationKind: self.verificationKind,
qrCodeData: qrCodePlayloadData,
showScanAction: canShowScanAction)
self.update(viewState: .loaded(viewData: viewData))

View file

@ -19,6 +19,7 @@
import Foundation
struct KeyVerificationVerifyByScanningViewData {
let verificationKind: KeyVerificationKind
let qrCodeData: Data?
let showScanAction: Bool
}

View file

@ -63,7 +63,7 @@ final class DeviceVerificationIncomingViewController: UIViewController {
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.title = VectorL10n.keyVerificationOtherSessionTitle
self.vc_removeBackTitle()
self.setupViews()

View file

@ -50,7 +50,7 @@
<action selector="startVerificationButtonAction:" destination="KS5-Uc-kth" eventType="touchUpInside" id="XRr-SM-v5B"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="To be secure, do this in person or use another way to communicate." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9u5-8O-e7v">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="To be secure, do this in person or use another way to communicate." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9u5-8O-e7v">
<rect key="frame" x="20" y="130" width="335" height="29"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/>

View file

@ -60,7 +60,7 @@ final class KeyVerificationSelfVerifyStartViewController: UIViewController {
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.title = VectorL10n.keyVerificationNewSessionTitle
self.setupViews()
self.activityPresenter = ActivityIndicatorPresenter()

View file

@ -60,10 +60,15 @@ final class KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyW
// MARK: - KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate
extension KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate {
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest) {
self.delegate?.keyVerificationSelfVerifyWaitCoordinator(self, didAcceptKeyVerificationRequest: keyVerificationRequest)
}
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction) {
self.delegate?.keyVerificationSelfVerifyWaitCoordinator(self, didAcceptIncomingSASTransaction: incomingSASTransaction)
}
func keyVerificationSelfVerifyWaitViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType) {
self.delegate?.keyVerificationSelfVerifyWaitCoordinatorDidCancel(self)
}

View file

@ -20,6 +20,7 @@ import Foundation
protocol KeyVerificationSelfVerifyWaitCoordinatorDelegate: class {
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest)
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction)
func keyVerificationSelfVerifyWaitCoordinatorDidCancel(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType)
}

View file

@ -134,6 +134,10 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
self.renderLoading()
case .loaded(let isNewSignIn):
self.renderLoaded(isNewSignIn: isNewSignIn)
case .cancelled(let reason):
self.renderCancelled(reason: reason)
case .cancelledByMe(let reason):
self.renderCancelledByMe(reason: reason)
case .error(let error):
self.render(error: error)
}
@ -150,6 +154,26 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
self.cancelBarButtonItem?.title = isNewSignIn ? VectorL10n.skip : VectorL10n.cancel
}
private func renderCancelled(reason: MXTransactionCancelCode) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelled, animated: true) {
self.viewModel.process(viewAction: .cancel)
}
}
private func renderCancelledByMe(reason: MXTransactionCancelCode) {
if reason.value != MXTransactionCancelCode.user().value {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelledByMe(reason.humanReadable), animated: true) {
self.viewModel.process(viewAction: .cancel)
}
} else {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
}
}
private func render(error: Error) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)

View file

@ -46,6 +46,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
}
deinit {
self.unregisterKeyVerificationManagerNewRequestNotification()
}
// MARK: - Public
@ -64,6 +65,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
private func loadData() {
self.registerKeyVerificationManagerNewRequestNotification(for: self.verificationManager)
self.update(viewState: .loaded(self.isNewSignIn))
self.registerTransactionDidStateChangeNotification()
}
private func cancel() {
@ -87,6 +89,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
return
}
self.unregisterKeyVerificationManagerNewRequestNotification()
self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, didAcceptKeyVerificationRequest: keyVerificationRequest)
}, failure: { [weak self] (error) in
@ -101,9 +104,11 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
private func registerKeyVerificationManagerNewRequestNotification(for verificationManager: MXKeyVerificationManager) {
NotificationCenter.default.addObserver(self, selector: #selector(keyVerificationManagerNewRequestNotification(notification:)), name: .MXKeyVerificationManagerNewRequest, object: verificationManager)
AppDelegate.the()?.handleSelfVerificationRequest = false
}
private func unregisterKeyVerificationManagerNewRequestNotification() {
AppDelegate.the()?.handleSelfVerificationRequest = true
NotificationCenter.default.removeObserver(self, name: .MXKeyVerificationManagerNewRequest, object: nil)
}
@ -119,6 +124,51 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
return
}
self.unregisterTransactionDidStateChangeNotification()
self.acceptKeyVerificationRequest(keyVerificationRequest)
}
// MARK: MXKeyVerificationTransactionDidChange
private func registerTransactionDidStateChangeNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(transactionDidStateChange(notification:)), name: .MXKeyVerificationTransactionDidChange, object: nil)
}
private func unregisterTransactionDidStateChangeNotification() {
NotificationCenter.default.removeObserver(self, name: .MXKeyVerificationTransactionDidChange, object: nil)
}
@objc private func transactionDidStateChange(notification: Notification) {
guard let sasTransaction = notification.object as? MXIncomingSASTransaction,
sasTransaction.otherUserId == self.session.myUserId else {
return
}
self.sasTransactionDidStateChange(sasTransaction)
}
private func sasTransactionDidStateChange(_ transaction: MXIncomingSASTransaction) {
switch transaction.state {
case MXSASTransactionStateIncomingShowAccept:
// Stop listening for incoming request
self.unregisterKeyVerificationManagerNewRequestNotification()
transaction.accept()
case MXSASTransactionStateShowSAS:
self.unregisterTransactionDidStateChangeNotification()
self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, didAcceptIncomingSASTransaction: transaction)
case MXSASTransactionStateCancelled:
guard let reason = transaction.reasonCancelCode else {
return
}
self.unregisterTransactionDidStateChangeNotification()
self.update(viewState: .cancelled(reason))
case MXSASTransactionStateCancelledByMe:
guard let reason = transaction.reasonCancelCode else {
return
}
self.unregisterTransactionDidStateChangeNotification()
self.update(viewState: .cancelledByMe(reason))
default:
break
}
}
}

View file

@ -24,6 +24,7 @@ protocol KeyVerificationSelfVerifyWaitViewModelViewDelegate: class {
protocol KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate: class {
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest)
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction)
func keyVerificationSelfVerifyWaitViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType)
}

View file

@ -22,5 +22,7 @@ import Foundation
enum KeyVerificationSelfVerifyWaitViewState {
case loading
case loaded(_ isNewSignIn: Bool)
case cancelled(MXTransactionCancelCode)
case cancelledByMe(MXTransactionCancelCode)
case error(Error)
}

View file

@ -59,7 +59,7 @@ final class DeviceVerificationStartViewController: UIViewController {
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.title = VectorL10n.keyVerificationOtherSessionTitle
self.vc_removeBackTitle()
self.setupViews()
@ -116,7 +116,7 @@ final class DeviceVerificationStartViewController: UIViewController {
self.scrollView.keyboardDismissMode = .interactive
self.titleLabel.text = VectorL10n.deviceVerificationStartTitle
self.informationLabel.text = VectorL10n.deviceVerificationSecurityAdvice
self.informationLabel.text = VectorL10n.deviceVerificationSecurityAdviceNumber
self.waitingPartnerLabel.text = VectorL10n.deviceVerificationStartWaitPartner
self.useLegacyVerificationLabel.text = VectorL10n.deviceVerificationStartUseLegacy

View file

@ -23,8 +23,6 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
private enum Constants {
static let cornerRadius: CGFloat = 8.0
static let buttonBackgroundColorAlpha: CGFloat = 0.2
static let buttonCornerRadius: CGFloat = 6.0
}
// MARK: - Properties
@ -39,8 +37,8 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
@IBOutlet private weak var requestStatusLabel: UILabel!
@IBOutlet private weak var buttonsContainerView: UIView!
@IBOutlet private weak var acceptButton: UIButton!
@IBOutlet private weak var declineButton: UIButton!
@IBOutlet private weak var acceptButton: RoundedButton!
@IBOutlet private weak var declineButton: RoundedButton!
// MARK: Public
@ -110,20 +108,16 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
super.awakeFromNib()
self.layer.masksToBounds = true
self.acceptButton.layer.masksToBounds = true
self.acceptButton.titleLabel?.adjustsFontSizeToFitWidth = true
self.acceptButton.titleLabel?.minimumScaleFactor = 0.5
self.acceptButton.titleLabel?.baselineAdjustment = .alignCenters
self.acceptButton.setTitle(VectorL10n.keyVerificationTileRequestIncomingApprovalAccept, for: .normal)
self.declineButton.layer.masksToBounds = true
self.declineButton.titleLabel?.adjustsFontSizeToFitWidth = true
self.declineButton.titleLabel?.minimumScaleFactor = 0.5
self.declineButton.titleLabel?.baselineAdjustment = .alignCenters
self.declineButton.actionStyle = .cancel
self.declineButton.setTitle(VectorL10n.keyVerificationTileRequestIncomingApprovalDecline, for: .normal)
}
@ -131,11 +125,6 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
super.layoutSubviews()
self.layer.cornerRadius = Constants.cornerRadius
if self.isButtonsHidden == false {
self.acceptButton.layer.cornerRadius = Constants.buttonCornerRadius
self.declineButton.layer.cornerRadius = Constants.buttonCornerRadius
}
}
// MARK: - Public
@ -145,8 +134,8 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
self.titleLabel.textColor = theme.textPrimaryColor
self.otherUserInformationLabel.textColor = theme.textSecondaryColor
self.acceptButton.vc_setBackgroundColor(theme.tintColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
self.declineButton.vc_setBackgroundColor(theme.noticeColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
self.acceptButton.update(theme: theme)
self.declineButton.update(theme: theme)
}
func updateSenderInfo(with userId: String, userDisplayName: String?) {

View file

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -46,7 +50,7 @@
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="WxG-vh-Bn0">
<rect key="frame" x="71" y="0.0" width="151" height="40"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="atD-LF-sGH">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="atD-LF-sGH" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="72" height="40"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Decline">
@ -56,7 +60,7 @@
<action selector="declineButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="dS6-Xr-6jZ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="irs-8W-qcs">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="irs-8W-qcs" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="82" y="0.0" width="69" height="40"/>
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
<state key="normal" title="Accept">

View file

@ -675,7 +675,14 @@ UIDocumentInteractionControllerDelegate>
{
if (!self.mainSession.crypto.crossSigning.canCrossSign)
{
return [UIImage imageNamed:@"encryption_normal"];
if ([deviceId isEqualToString:self.mainSession.myDeviceId])
{
return [UIImage imageNamed:@"encryption_warning"];
}
else
{
return [UIImage imageNamed:@"encryption_normal"];
}
}
UIImage* shieldImageForDevice = [UIImage imageNamed:@"encryption_warning"];

View file

@ -66,6 +66,8 @@
@property(nonatomic,getter=isHidden) BOOL hidden;
@property(nonatomic) BOOL verifyCurrentSessionAlertHasBeenDisplayed;
@end
@implementation MasterTabBarController
@ -206,6 +208,8 @@
[childViewControllers removeAllObjects];
}
[self presentVerifyCurrentSessionAlertIfNeeded];
}
if (unifiedSearchViewController)
@ -215,6 +219,55 @@
}
}
- (void)presentVerifyCurrentSessionAlertIfNeeded
{
if (RiotSettings.shared.hideVerifyThisSessionAlert || self.verifyCurrentSessionAlertHasBeenDisplayed)
{
return;
}
MXSession *mainSession = self.mxSessions.firstObject;
if (self.viewLoaded
&& mainSession.state >= MXSessionStateStoreDataReady
&& mainSession.crypto.crossSigning
&& mainSession.crypto.crossSigning.state == MXCrossSigningStateCrossSigningExists)
{
self.verifyCurrentSessionAlertHasBeenDisplayed = YES;
[self presentVerifyCurrentSessionAlertWithSession:mainSession];
}
}
- (void)presentVerifyCurrentSessionAlertWithSession:(MXSession*)session
{
[currentAlert dismissViewControllerAnimated:NO completion:nil];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_title", @"Vector", nil)
message:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_message", @"Vector", nil)
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_validate_action", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[[AppDelegate theDelegate] presentCompleteSecurityForSession:session];
}]];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"later", @"Vector", nil)
style:UIAlertActionStyleCancel
handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"do_not_ask_again", @"Vector", nil)
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action) {
RiotSettings.shared.hideVerifyThisSessionAlert = YES;
}]];
[self presentViewController:alert animated:YES completion:nil];
currentAlert = alert;
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
@ -339,6 +392,9 @@
// Prepare data sources and return
[self initializeDataSources];
// Add matrix sessions observer on first added session
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMatrixSessionStateDidChange:) name:kMXSessionStateDidChangeNotification object:nil];
return;
}
else
@ -387,6 +443,8 @@
- (void)onMatrixSessionStateDidChange:(NSNotification *)notif
{
[self refreshTabBarBadges];
[self presentVerifyCurrentSessionAlertIfNeeded];
}
- (void)showAuthenticationScreen

View file

@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.11.1</string>
<string>0.11.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.11.1</string>
<string>0.11.2</string>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>ITSEncryptionExportComplianceCode</key>

View file

@ -0,0 +1,35 @@
/*
Copyright 2020 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface UniversalLink : NSObject
@property (nonatomic, copy, readonly) NSURL *url;
@property (nonatomic, copy, readonly) NSArray<NSString*> *pathParams;
@property (nonatomic, copy, readonly) NSDictionary<NSString*, NSString*> *queryParams;
- (id)initWithUrl:(NSURL *)url
pathParams:(NSArray<NSString*> *)pathParams
queryParams:(NSDictionary<NSString*, NSString*> *)queryParams;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,60 @@
/*
Copyright 2020 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "UniversalLink.h"
@implementation UniversalLink
- (id)initWithUrl:(NSURL *)url pathParams:(NSArray<NSString *> *)pathParams queryParams:(NSDictionary<NSString *,NSString *> *)queryParams
{
self = [super init];
if (self)
{
_url = url;
_pathParams = pathParams;
_queryParams = queryParams;
}
return self;
}
- (BOOL)isEqual:(id)other
{
if (other == self)
return YES;
if (![other isKindOfClass:UniversalLink.class])
return NO;
UniversalLink *otherLink = (UniversalLink *)other;
return [_url isEqual:otherLink.url]
&& [_pathParams isEqualToArray:otherLink.pathParams]
&& [_queryParams isEqualToDictionary:otherLink.queryParams];
}
- (NSUInteger)hash
{
NSUInteger prime = 31;
NSUInteger result = 1;
result = prime * result + [_url hash];
result = prime * result + [_pathParams hash];
result = prime * result + [_queryParams hash];
return result;
}
@end

View file

@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>0.11.1</string>
<string>0.11.2</string>
<key>CFBundleVersion</key>
<string>0.11.1</string>
<string>0.11.2</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>

View file

@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>0.11.1</string>
<string>0.11.2</string>
<key>CFBundleVersion</key>
<string>0.11.1</string>
<string>0.11.2</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>