Merge pull request #5293 from vector-im/langleyd/5292_refresh_tokens

App: Refresh Tokens Implementation
This commit is contained in:
David Langley
2022-01-31 08:59:19 +00:00
committed by GitHub
23 changed files with 511 additions and 272 deletions

View File

@@ -351,6 +351,9 @@ final class BuildSettings: NSObject {
static let authScreenShowCustomServerOptions = true
static let authScreenShowSocialLoginSection = true
// MARK: - Authentication Options
static let authEnableRefreshTokens = false
// MARK: - Unified Search
static let unifiedSearchScreenShowPublicDirectory = true

View File

@@ -76,6 +76,8 @@ class CommonConfiguration: NSObject, Configurable {
sdkOptions.enableKeyBackupWhenStartingMXCrypto = false
sdkOptions.clientPermalinkBaseUrl = BuildSettings.clientPermalinkBaseUrl
sdkOptions.authEnableRefreshTokens = BuildSettings.authEnableRefreshTokens
// Configure key provider delegate
MXKeyProvider.sharedInstance().delegate = EncryptionKeyManager.shared
}

View File

@@ -150,4 +150,4 @@ post_install do |installer|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end
end

View File

@@ -155,7 +155,7 @@ class UserSessionsService: NSObject {
let isSessionStateValid: Bool
switch mxSession.state {
case .closed, .unknownToken:
case .closed:
isSessionStateValid = false
default:
isSessionStateValid = true

View File

@@ -96,7 +96,7 @@ import AnalyticsEvents
// Catch and log crashes
MXLogger.logCrashes(true)
MXLogger.setBuildVersion(AppDelegate.theDelegate().build)
MXLogger.setBuildVersion(AppInfo.current.buildInfo.readableBuildVersion)
}
/// Use the analytics settings from the supplied session to configure analytics.
@@ -213,6 +213,18 @@ extension Analytics {
}
}
/// Track when a user becomes unauthenticated without pressing the `sign out` button.
/// - Parameters:
/// - softLogout: Wether it was a soft/hard logout that was triggered.
/// - refreshTokenAuth: Wether it was either an access-token-based or refresh-token-based auth mechanism enabled.
/// - errorCode: The error code as returned by the homeserver that triggered the logout.
/// - errorReason: The reason for the error as returned by the homeserver that triggered the logout.
func trackAuthUnauthenticatedError(softLogout: Bool, refreshTokenAuth: Bool, errorCode: String, errorReason: String) {
let errorCode = AnalyticsEvent.UnauthenticatedError.ErrorCode(rawValue: errorCode) ?? .M_UNKNOWN
let event = AnalyticsEvent.UnauthenticatedError(errorCode: errorCode, errorReason: errorReason, refreshTokenAuth: refreshTokenAuth, softLogout: softLogout)
client.capture(event)
}
/// Track whether the user accepted or declined the terms to an identity server.
/// **Note** This method isn't currently implemented.
/// - Parameter accepted: Whether the terms were accepted.

View File

@@ -333,7 +333,7 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
didCheckFalseAuthScreenDisplay = YES;
MXLogDebug(@"[AuthenticationVC] viewDidAppear: Checking false logout");
[[MXKAccountManager sharedManager] forceReloadAccounts];
[MXKAccountManager sharedManagerWithReload: YES];
if ([MXKAccountManager sharedManager].activeAccounts.count)
{
// For now, we do not have better solution than forcing the user to restart the app

View File

@@ -1482,7 +1482,9 @@
MXRestClient *mxRestClient = [[MXRestClient alloc] initWithCredentials:credentials andOnUnrecognizedCertificateBlock:^BOOL(NSData *certificate) {
return NO;
}];
} andPersistentTokenDataHandler:^(void (^handler)(NSArray<MXCredentials *> *credentials, void (^completion)(BOOL didUpdateCredentials))) {
[[MXKAccountManager sharedManager] readAndWriteCredentials:handler];
} andUnauthenticatedHandler: nil];
MXWeakify(self);
[[MXKAccountManager sharedManager].dehydrationService rehydrateDeviceWithMatrixRestClient:mxRestClient dehydrationKey:keyData success:^(NSString * deviceId) {

View File

@@ -17,6 +17,7 @@
*/
#import <MatrixSDK/MatrixSDK.h>
#import "MXKAccountData.h"
@class MXKAccount;
@@ -56,29 +57,7 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
`MXKAccount` object contains the credentials of a logged matrix user. It is used to handle matrix
session and presence for this user.
*/
@interface MXKAccount : NSObject <NSCoding>
/**
The account's credentials: homeserver, access token, user id.
*/
@property (nonatomic, readonly) MXCredentials *mxCredentials;
/**
The identity server URL.
*/
@property (nonatomic) NSString *identityServerURL;
/**
The antivirus server URL, if any (nil by default).
Set a non-null url to configure the antivirus scanner use.
*/
@property (nonatomic) NSString *antivirusServerURL;
/**
The Push Gateway URL used to send event notifications to (nil by default).
This URL should be over HTTPS and never over HTTP.
*/
@property (nonatomic) NSString *pushGatewayURL;
@interface MXKAccount : MXKAccountData
/**
The matrix REST client used to make matrix API requests.
@@ -107,12 +86,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
*/
@property (nonatomic, readonly) NSString *fullDisplayName;
/**
The 3PIDs linked to this account.
[self load3PIDs] must be called to update the property.
*/
@property (nonatomic, readonly) NSArray<MXThirdPartyIdentifier *> *threePIDs;
/**
The email addresses linked to this account.
This is a subset of self.threePIDs.
@@ -125,12 +98,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
*/
@property (nonatomic, readonly) NSArray<NSString *> *linkedPhoneNumbers;
/**
The account user's device.
[self loadDeviceInformation] must be called to update the property.
*/
@property (nonatomic, readonly) MXDevice *device;
/**
The account user's presence (`MXPresenceUnknown` by default, available if matrix session `mxSession` is opened).
The notification `kMXKAccountUserInfoDidChangeNotification` is posted in case of change of this property.
@@ -148,11 +115,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
*/
@property (nonatomic, readonly) BOOL pushNotificationServiceIsActive;
/**
Transient information storage.
*/
@property (nonatomic, strong, readonly) NSMutableDictionary<NSString *, id<NSCoding>> *others;
/**
Enable Push notification based on Apple Push Notification Service (APNS).
@@ -166,11 +128,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
success:(void (^)(void))success
failure:(void (^)(NSError *))failure;
/**
Flag to indicate that an APNS pusher has been set on the homeserver for this device.
*/
@property (nonatomic, readonly) BOOL hasPusherForPushNotifications;
/**
The Push notification activity (based on PushKit) for this account.
YES when Push is turned on (locally available and enabled homeserver side).
@@ -190,26 +147,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
success:(void (^)(void))success
failure:(void (^)(NSError *))failure;
/**
Flag to indicate that a PushKit pusher has been set on the homeserver for this device.
*/
@property (nonatomic, readonly) BOOL hasPusherForPushKitNotifications;
/**
Enable In-App notifications based on Remote notifications rules.
NO by default.
*/
@property (nonatomic) BOOL enableInAppNotifications;
/**
Disable the account without logging out (NO by default).
A matrix session is automatically opened for the account when this property is toggled from YES to NO.
The session is closed when this property is set to YES.
*/
@property (nonatomic,getter=isDisabled) BOOL disabled;
/**
Manage the online presence event.
@@ -217,11 +154,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
*/
@property (nonatomic) BOOL hideUserPresence;
/**
Flag indicating if the end user has been warned about encryption and its limitations.
*/
@property (nonatomic,getter=isWarnedAboutEncryption) BOOL warnedAboutEncryption;
/**
Register the MXKAccountOnCertificateChange block that will be used to handle certificate change during account use.
This block is nil by default, any new certificate is ignored/untrusted (this will abort the connection to the server).
@@ -284,11 +216,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
#pragma mark - Soft logout
/**
Flag to indicate if the account has been logged out by the homeserver admin.
*/
@property (nonatomic, readonly) BOOL isSoftLogout;
/**
Soft logout the account.
@@ -432,4 +359,8 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
success:(void (^)(void))success
failure:(void (^)(NSError *error))failure;
/**
Handle unauthenticated errors from the server triggering hard/soft logouts as appropriate.
*/
- (void)handleUnauthenticatedWithError:(MXError *)error isSoftLogout:(BOOL)isSoftLogout isRefreshTokenAuth:(BOOL)isRefreshTokenAuth andCompletion:(void (^)(void))completion;
@end

View File

@@ -36,6 +36,8 @@
#import "MXKSwiftHeader.h"
#import "GeneratedInterface-Swift.h"
NSString *const kMXKAccountUserInfoDidChangeNotification = @"kMXKAccountUserInfoDidChangeNotification";
NSString *const kMXKAccountAPNSActivityDidChangeNotification = @"kMXKAccountAPNSActivityDidChangeNotification";
NSString *const kMXKAccountPushKitActivityDidChangeNotification = @"kMXKAccountPushKitActivityDidChangeNotification";
@@ -92,13 +94,10 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
@property (nonatomic, strong) id<MXBackgroundTask> backgroundTask;
@property (nonatomic, strong) id<MXBackgroundTask> backgroundSyncBgTask;
@property (nonatomic, strong) NSMutableDictionary<NSString *, id<NSCoding>> *others;
@end
@implementation MXKAccount
@synthesize mxCredentials, mxSession, mxRestClient;
@synthesize threePIDs;
@synthesize mxSession, mxRestClient;
@synthesize userPresence;
@synthesize userTintColor;
@synthesize hideUserPresence;
@@ -144,7 +143,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
notifyOpenSessionFailure = YES;
// Report credentials and alloc REST client.
mxCredentials = credentials;
_mxCredentials = credentials;
[self prepareRESTClient];
userPresence = MXPresenceUnknown;
@@ -171,65 +170,19 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (id)initWithCoder:(NSCoder *)coder
{
self = [super init];
self = [super initWithCoder:coder];
if (self)
{
notifyOpenSessionFailure = YES;
NSString *homeServerURL = [coder decodeObjectForKey:@"homeserverurl"];
NSString *userId = [coder decodeObjectForKey:@"userid"];
NSString *accessToken = [coder decodeObjectForKey:@"accesstoken"];
_identityServerURL = [coder decodeObjectForKey:@"identityserverurl"];
NSString *identityServerAccessToken = [coder decodeObjectForKey:@"identityserveraccesstoken"];
mxCredentials = [[MXCredentials alloc] initWithHomeServer:homeServerURL
userId:userId
accessToken:accessToken];
mxCredentials.identityServer = _identityServerURL;
mxCredentials.identityServerAccessToken = identityServerAccessToken;
mxCredentials.deviceId = [coder decodeObjectForKey:@"deviceId"];
mxCredentials.allowedCertificate = [coder decodeObjectForKey:@"allowedCertificate"];
[self prepareRESTClient];
[self registerAccountDataDidChangeIdentityServerNotification];
[self registerIdentityServiceDidChangeAccessTokenNotification];
if ([coder decodeObjectForKey:@"threePIDs"])
{
threePIDs = [coder decodeObjectForKey:@"threePIDs"];
}
if ([coder decodeObjectForKey:@"device"])
{
_device = [coder decodeObjectForKey:@"device"];
}
userPresence = MXPresenceUnknown;
if ([coder decodeObjectForKey:@"antivirusserverurl"])
{
_antivirusServerURL = [coder decodeObjectForKey:@"antivirusserverurl"];
}
if ([coder decodeObjectForKey:@"pushgatewayurl"])
{
_pushGatewayURL = [coder decodeObjectForKey:@"pushgatewayurl"];
}
_hasPusherForPushNotifications = [coder decodeBoolForKey:@"_enablePushNotifications"];
_hasPusherForPushKitNotifications = [coder decodeBoolForKey:@"enablePushKitNotifications"];
_enableInAppNotifications = [coder decodeBoolForKey:@"enableInAppNotifications"];
_disabled = [coder decodeBoolForKey:@"disabled"];
_isSoftLogout = [coder decodeBoolForKey:@"isSoftLogout"];
_warnedAboutEncryption = [coder decodeBoolForKey:@"warnedAboutEncryption"];
_others = [coder decodeObjectForKey:@"others"];
// Refresh device information
[self loadDeviceInformation:nil failure:nil];
}
@@ -237,60 +190,6 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:mxCredentials.homeServer forKey:@"homeserverurl"];
[coder encodeObject:mxCredentials.userId forKey:@"userid"];
[coder encodeObject:mxCredentials.accessToken forKey:@"accesstoken"];
[coder encodeObject:mxCredentials.identityServerAccessToken forKey:@"identityserveraccesstoken"];
if (mxCredentials.deviceId)
{
[coder encodeObject:mxCredentials.deviceId forKey:@"deviceId"];
}
if (mxCredentials.allowedCertificate)
{
[coder encodeObject:mxCredentials.allowedCertificate forKey:@"allowedCertificate"];
}
if (self.threePIDs)
{
[coder encodeObject:threePIDs forKey:@"threePIDs"];
}
if (self.device)
{
[coder encodeObject:_device forKey:@"device"];
}
if (self.identityServerURL)
{
[coder encodeObject:_identityServerURL forKey:@"identityserverurl"];
}
if (self.antivirusServerURL)
{
[coder encodeObject:_antivirusServerURL forKey:@"antivirusserverurl"];
}
if (self.pushGatewayURL)
{
[coder encodeObject:_pushGatewayURL forKey:@"pushgatewayurl"];
}
[coder encodeBool:_hasPusherForPushNotifications forKey:@"_enablePushNotifications"];
[coder encodeBool:_hasPusherForPushKitNotifications forKey:@"enablePushKitNotifications"];
[coder encodeBool:_enableInAppNotifications forKey:@"enableInAppNotifications"];
[coder encodeBool:_disabled forKey:@"disabled"];
[coder encodeBool:_isSoftLogout forKey:@"isSoftLogout"];
[coder encodeBool:_warnedAboutEncryption forKey:@"warnedAboutEncryption"];
[coder encodeObject:_others forKey:@"others"];
}
#pragma mark - Properties
- (void)setIdentityServerURL:(NSString *)identityServerURL
@@ -298,10 +197,10 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
if (identityServerURL.length)
{
_identityServerURL = identityServerURL;
mxCredentials.identityServer = identityServerURL;
self.mxCredentials.identityServer = identityServerURL;
// Update services used in MXSession
[mxSession setIdentityServer:mxCredentials.identityServer andAccessToken:mxCredentials.identityServerAccessToken];
[mxSession setIdentityServer:self.mxCredentials.identityServer andAccessToken:self.mxCredentials.identityServerAccessToken];
}
else
{
@@ -355,24 +254,19 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
{
if (self.userDisplayName.length)
{
return [NSString stringWithFormat:@"%@ (%@)", self.userDisplayName, mxCredentials.userId];
return [NSString stringWithFormat:@"%@ (%@)", self.userDisplayName, self.mxCredentials.userId];
}
else
{
return mxCredentials.userId;
return self.mxCredentials.userId;
}
}
- (NSArray<MXThirdPartyIdentifier *> *)threePIDs
{
return threePIDs;
}
- (NSArray<NSString *> *)linkedEmails
{
NSMutableArray<NSString *> *linkedEmails = [NSMutableArray array];
for (MXThirdPartyIdentifier *threePID in threePIDs)
for (MXThirdPartyIdentifier *threePID in self.threePIDs)
{
if ([threePID.medium isEqualToString:kMX3PIDMediumEmail])
{
@@ -387,7 +281,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
{
NSMutableArray<NSString *> *linkedPhoneNumbers = [NSMutableArray array];
for (MXThirdPartyIdentifier *threePID in threePIDs)
for (MXThirdPartyIdentifier *threePID in self.threePIDs)
{
if ([threePID.medium isEqualToString:kMX3PIDMediumMSISDN])
{
@@ -402,7 +296,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
{
if (!userTintColor)
{
userTintColor = [MXKTools colorWithRGBValue:[mxCredentials.userId hash]];
userTintColor = [MXKTools colorWithRGBValue:[self.mxCredentials.userId hash]];
}
return userTintColor;
@@ -410,7 +304,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (BOOL)pushNotificationServiceIsActive
{
BOOL pushNotificationServiceIsActive = ([[MXKAccountManager sharedManager] isAPNSAvailable] && _hasPusherForPushNotifications && mxSession);
BOOL pushNotificationServiceIsActive = ([[MXKAccountManager sharedManager] isAPNSAvailable] && self.hasPusherForPushNotifications && mxSession);
MXLogDebug(@"[MXKAccount][Push] pushNotificationServiceIsActive: %@", @(pushNotificationServiceIsActive));
return pushNotificationServiceIsActive;
@@ -461,7 +355,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
}
}
}
else if (_hasPusherForPushNotifications)
else if (self.hasPusherForPushNotifications)
{
MXLogDebug(@"[MXKAccount][Push] enablePushNotifications: Disable APNS for %@ account", self.mxCredentials.userId);
@@ -487,7 +381,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (BOOL)isPushKitNotificationActive
{
BOOL isPushKitNotificationActive = ([[MXKAccountManager sharedManager] isPushAvailable] && _hasPusherForPushKitNotifications && mxSession);
BOOL isPushKitNotificationActive = ([[MXKAccountManager sharedManager] isPushAvailable] && self.hasPusherForPushKitNotifications && mxSession);
MXLogDebug(@"[MXKAccount][Push] isPushKitNotificationActive: %@", @(isPushKitNotificationActive));
return isPushKitNotificationActive;
@@ -535,7 +429,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
failure (error);
}
}
else if (_hasPusherForPushKitNotifications)
else if (self.hasPusherForPushKitNotifications)
{
MXLogDebug(@"[MXKAccount][Push] enablePushKitNotifications: Disable Push for %@ account", self.mxCredentials.userId);
@@ -633,7 +527,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
success();
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
}
failure:failure];
}
@@ -653,7 +547,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
success();
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
}
failure:failure];
}
@@ -686,9 +580,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (void)load3PIDs:(void (^)(void))success failure:(void (^)(NSError *))failure
{
[mxRestClient threePIDs:^(NSArray<MXThirdPartyIdentifier *> *threePIDs2) {
self->threePIDs = threePIDs2;
self->_threePIDs = threePIDs2;
// Archive updated field
[[MXKAccountManager sharedManager] saveAccounts];
@@ -708,9 +602,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (void)loadDeviceInformation:(void (^)(void))success failure:(void (^)(NSError *error))failure
{
if (mxCredentials.deviceId)
if (self.mxCredentials.deviceId)
{
[mxRestClient deviceByDeviceId:mxCredentials.deviceId success:^(MXDevice *device) {
[mxRestClient deviceByDeviceId:self.mxCredentials.deviceId success:^(MXDevice *device) {
self->_device = device;
@@ -751,21 +645,21 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
[mxSession.myUser setPresence:userPresence
andStatusMessage:statusMessage
success:^{
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) succeeded", self->mxCredentials.userId, (unsigned long)self->userPresence);
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) succeeded", self.mxCredentials.userId, (unsigned long)self->userPresence);
if (completion)
{
completion();
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
}
failure:^(NSError *error) {
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) failed", self->mxCredentials.userId, (unsigned long)self->userPresence);
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) failed", self.mxCredentials.userId, (unsigned long)self->userPresence);
}];
}
else if (hideUserPresence)
{
MXLogDebug(@"[MXKAccount] %@: set user presence is disabled.", mxCredentials.userId);
MXLogDebug(@"[MXKAccount] %@: set user presence is disabled.", self.mxCredentials.userId);
}
}
@@ -783,7 +677,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
-(void)openSessionWithStore:(id<MXStore>)store
{
// Sanity check
if (!mxCredentials || !mxRestClient)
if (!self.mxCredentials || !mxRestClient)
{
MXLogDebug(@"[MXKAccount] Matrix session cannot be created without credentials");
return;
@@ -1048,9 +942,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (void)hydrateWithCredentials:(MXCredentials*)credentials
{
// Sanity check
if ([mxCredentials.userId isEqualToString:credentials.userId])
if ([self.mxCredentials.userId isEqualToString:credentials.userId])
{
mxCredentials = credentials;
_mxCredentials = credentials;
_isSoftLogout = NO;
[[MXKAccountManager sharedManager] saveAccounts];
@@ -1058,11 +952,10 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
}
else
{
MXLogDebug(@"[MXKAccount] hydrateWithCredentials: Error: users ids mismatch: %@ vs %@", credentials.userId, mxCredentials.userId);
MXLogDebug(@"[MXKAccount] hydrateWithCredentials: Error: users ids mismatch: %@ vs %@", credentials.userId, self.mxCredentials.userId);
}
}
- (void)deletePusher
{
if (self.pushNotificationServiceIsActive)
@@ -1259,7 +1152,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
success();
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId];
} failure:^(NSError *error) {
@@ -1278,7 +1171,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
success();
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId];
return;
}
@@ -1295,7 +1188,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
failure(error);
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId];
}];
}
@@ -1322,7 +1215,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
MXLogDebug(@"[MXKAccount][Push] refreshPushKitPusher: Error: %@", error);
}];
}
else if (_hasPusherForPushKitNotifications)
else if (self.hasPusherForPushKitNotifications)
{
if ([MXKAccountManager sharedManager].pushDeviceToken)
{
@@ -1336,7 +1229,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
else
{
MXLogDebug(@"[MXKAccount][Push] refreshPushKitPusher: PushKit pusher for %@ account is already disabled. Reset _hasPusherForPushKitNotifications", self.mxCredentials.userId);
_hasPusherForPushKitNotifications = NO;
self->_hasPusherForPushKitNotifications = NO;
[[MXKAccountManager sharedManager] saveAccounts];
}
}
@@ -1398,7 +1291,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
success();
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self.mxCredentials.userId];
} failure:^(NSError *error) {
@@ -1417,7 +1310,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
success();
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self.mxCredentials.userId];
return;
}
@@ -1434,7 +1327,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
failure(error);
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self.mxCredentials.userId];
}];
}
@@ -1443,7 +1336,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
MXLogDebug(@"[MXKAccount][Push] enablePusher: %@", @(enabled));
// Refuse to try & turn push on if we're not logged in, it's nonsensical.
if (!mxCredentials)
if (!self.mxCredentials)
{
MXLogDebug(@"[MXKAccount][Push] enablePusher: Not setting push token because we're not logged in");
return;
@@ -1610,7 +1503,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
[self.mxSession startWithSyncFilter:syncFilter onServerSyncDone:^{
MXStrongifyAndReturnIfNil(self);
MXLogDebug(@"[MXKAccount] %@: The session is ready. Matrix SDK session has been started in %0.fms.", self->mxCredentials.userId, [[NSDate date] timeIntervalSinceDate:self->openSessionStartDate] * 1000);
MXLogDebug(@"[MXKAccount] %@: The session is ready. Matrix SDK session has been started in %0.fms.", self.mxCredentials.userId, [[NSDate date] timeIntervalSinceDate:self->openSessionStartDate] * 1000);
[self setUserPresence:MXPresenceOnline andStatusMessage:nil completion:nil];
@@ -1745,11 +1638,11 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
}
// Here displayname or other information have been updated, post update notification.
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
}];
// User information are just up-to-date (`mxSession` is running), post update notification.
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
}
}
else if (mxSession.state == MXSessionStateStoreDataReady || mxSession.state == MXSessionStateSyncInProgress)
@@ -1764,40 +1657,30 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
{
// Here the initial server sync is in progress. The session is not running yet, but some user's information are available (from local storage).
// We post update notification to let observer take into account this user's information even if they may not be up-to-date.
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:mxCredentials.userId];
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
}
}
else if (mxSession.state == MXSessionStatePaused)
{
isPauseRequested = NO;
}
else if (mxSession.state == MXSessionStateUnknownToken)
{
// Logout this account
[[MXKAccountManager sharedManager] removeAccount:self completion:nil];
}
else if (mxSession.state == MXSessionStateSoftLogout)
{
// Soft logout this account
[[MXKAccountManager sharedManager] softLogout:self];
}
}
- (void)prepareRESTClient
{
if (!mxCredentials)
if (!self.mxCredentials)
{
return;
}
mxRestClient = [[MXRestClient alloc] initWithCredentials:mxCredentials andOnUnrecognizedCertificateBlock:^BOOL(NSData *certificate) {
MXWeakify(self);
mxRestClient = [[MXRestClient alloc] initWithCredentials:self.mxCredentials andOnUnrecognizedCertificateBlock:^BOOL(NSData *certificate) {
MXStrongifyAndReturnValueIfNil(self, NO);
if (_onCertificateChangeBlock)
{
if (_onCertificateChangeBlock (self, certificate))
{
// Update the certificate in credentials
self->mxCredentials.allowedCertificate = certificate;
self.mxCredentials.allowedCertificate = certificate;
// Archive updated field
[[MXKAccountManager sharedManager] saveAccounts];
@@ -1805,16 +1688,39 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
return YES;
}
self->mxCredentials.ignoredCertificate = certificate;
self.mxCredentials.ignoredCertificate = certificate;
// Archive updated field
[[MXKAccountManager sharedManager] saveAccounts];
}
return NO;
} andPersistentTokenDataHandler:^(void (^handler)(NSArray<MXCredentials *> *credentials, void (^completion)(BOOL didUpdateCredentials))) {
[MXKAccountManager.sharedManager readAndWriteCredentials:handler];
} andUnauthenticatedHandler:^(MXError *error, BOOL isSoftLogout, BOOL isRefreshTokenAuth, void (^completion)(void)) {
MXStrongifyAndReturnIfNil(self);
[self handleUnauthenticatedWithError:error isSoftLogout:isSoftLogout isRefreshTokenAuth:isRefreshTokenAuth andCompletion:completion];
}];
}
- (void)handleUnauthenticatedWithError:(MXError *)error isSoftLogout:(BOOL)isSoftLogout isRefreshTokenAuth:(BOOL)isRefreshTokenAuth andCompletion:(void (^)(void))completion
{
[Analytics.shared trackAuthUnauthenticatedErrorWithSoftLogout:isSoftLogout refreshTokenAuth:isRefreshTokenAuth errorCode:error.errcode errorReason:error.error];
MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: trackAuthUnauthenticatedErrorWithSoftLogout sent");
if (isSoftLogout)
{
MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: soft logout.");
[[MXKAccountManager sharedManager] softLogout:self];
completion();
}
else
{
MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: hard logout.");
[[MXKAccountManager sharedManager] removeAccount:self sendLogoutRequest:NO completion:completion];
}
}
- (void)onDateTimeFormatUpdate
{
if ([mxSession.roomSummaryUpdateDelegate isKindOfClass:MXKEventFormatter.class])
@@ -1871,7 +1777,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
#pragma mark - Crypto
- (void)resetDeviceId
{
mxCredentials.deviceId = nil;
self.mxCredentials.deviceId = nil;
// Archive updated field
[[MXKAccountManager sharedManager] saveAccounts];
@@ -2187,11 +2093,11 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
MXSession *mxSession = notification.object;
if (mxSession == self.mxSession)
{
if (![mxCredentials.identityServer isEqualToString:self.mxSession.accountDataIdentityServer])
if (![self.mxCredentials.identityServer isEqualToString:self.mxSession.accountDataIdentityServer])
{
_identityServerURL = self.mxSession.accountDataIdentityServer;
mxCredentials.identityServer = _identityServerURL;
mxCredentials.identityServerAccessToken = nil;
self.mxCredentials.identityServer = _identityServerURL;
self.mxCredentials.identityServerAccessToken = nil;
// Archive updated field
[[MXKAccountManager sharedManager] saveAccounts];
@@ -2204,7 +2110,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
- (void)identityService:(MXIdentityService *)identityService didUpdateAccessToken:(NSString *)accessToken
{
mxCredentials.identityServerAccessToken = accessToken;
self.mxCredentials.identityServerAccessToken = accessToken;
}
- (void)registerIdentityServiceDidChangeAccessTokenNotification
@@ -2220,9 +2126,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
NSString *identityServer = userInfo[MXIdentityServiceNotificationIdentityServerKey];
NSString *accessToken = userInfo[MXIdentityServiceNotificationAccessTokenKey];
if (userId && identityServer && accessToken && [mxCredentials.identityServer isEqualToString:identityServer])
if (userId && identityServer && accessToken && [self.mxCredentials.identityServer isEqualToString:identityServer])
{
mxCredentials.identityServerAccessToken = accessToken;
self.mxCredentials.identityServerAccessToken = accessToken;
// Archive updated field
[[MXKAccountManager sharedManager] saveAccounts];

View File

@@ -0,0 +1,118 @@
//
// Copyright 2021 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 <MatrixSDK/MatrixSDK.h>
@class MXKAccountData;
@interface MXKAccountData : NSObject <NSCoding> {
@protected MXCredentials *_mxCredentials;
@protected NSString *_identityServerURL;
@protected NSString *_antivirusServerURL;
@protected NSString *_pushGatewayURL;
@protected MXDevice *_device;
@protected BOOL _disabled;
@protected BOOL _enableInAppNotifications;
@protected BOOL _warnedAboutEncryption;
@protected NSMutableDictionary<NSString *, id<NSCoding>> *_others;
@protected NSArray<MXThirdPartyIdentifier *> *_threePIDs;
@protected BOOL _isSoftLogout;
@protected BOOL _hasPusherForPushNotifications;
@protected BOOL _hasPusherForPushKitNotifications;
}
/**
The account's credentials: homeserver, access token, user id.
*/
@property (nonatomic, readonly, nonnull) MXCredentials *mxCredentials;
/**
The identity server URL.
*/
@property (nonatomic, nonnull) NSString *identityServerURL;
/**
The antivirus server URL, if any (nil by default).
Set a non-null url to configure the antivirus scanner use.
*/
@property (nonatomic, nullable) NSString *antivirusServerURL;
/**
The Push Gateway URL used to send event notifications to (nil by default).
This URL should be over HTTPS and never over HTTP.
*/
@property (nonatomic, nullable) NSString *pushGatewayURL;
/**
The 3PIDs linked to this account.
[self load3PIDs] must be called to update the property.
*/
@property (nonatomic, readonly, nullable) NSArray<MXThirdPartyIdentifier *> *threePIDs;
/**
The account user's device.
[self loadDeviceInformation] must be called to update the property.
*/
@property (nonatomic, readonly, nullable) MXDevice *device;
/**
Transient information storage.
*/
@property (nonatomic, strong, readonly, nonnull) NSMutableDictionary<NSString *, id<NSCoding>> *others;
/**
Flag to indicate that an APNS pusher has been set on the homeserver for this device.
*/
@property (nonatomic, readonly) BOOL hasPusherForPushNotifications;
/**
The Push notification activity (based on PushKit) for this account.
YES when Push is turned on (locally available and enabled homeserver side).
*/
@property (nonatomic, readonly) BOOL isPushKitNotificationActive;
/**
Flag to indicate that a PushKit pusher has been set on the homeserver for this device.
*/
@property (nonatomic, readonly) BOOL hasPusherForPushKitNotifications;
/**
Enable In-App notifications based on Remote notifications rules.
NO by default.
*/
@property (nonatomic) BOOL enableInAppNotifications;
/**
Disable the account without logging out (NO by default).
A matrix session is automatically opened for the account when this property is toggled from YES to NO.
The session is closed when this property is set to YES.
*/
@property (nonatomic,getter=isDisabled) BOOL disabled;
/**
Flag indicating if the end user has been warned about encryption and its limitations.
*/
@property (nonatomic,getter=isWarnedAboutEncryption) BOOL warnedAboutEncryption;
#pragma mark - Soft logout
/**
Flag to indicate if the account has been logged out by the homeserver admin.
*/
@property (nonatomic, readonly) BOOL isSoftLogout;
@end

View File

@@ -0,0 +1,150 @@
//
// Copyright 2021 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 <Foundation/Foundation.h>
#import "MXKAccountData.h"
@interface MXKAccountData ()
@end
@implementation MXKAccountData
@synthesize mxCredentials = _mxCredentials;
#pragma mark - NSCoding
- (id)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (self)
{
NSString *homeServerURL = [coder decodeObjectForKey:@"homeserverurl"];
NSString *userId = [coder decodeObjectForKey:@"userid"];
NSString *accessToken = [coder decodeObjectForKey:@"accesstoken"];
_identityServerURL = [coder decodeObjectForKey:@"identityserverurl"];
NSString *identityServerAccessToken = [coder decodeObjectForKey:@"identityserveraccesstoken"];
_mxCredentials = [[MXCredentials alloc] initWithHomeServer:homeServerURL
userId:userId
accessToken:accessToken];
_mxCredentials.accessTokenExpiresAt = [coder decodeInt64ForKey:@"accessTokenExpiresAt"];
_mxCredentials.refreshToken = [coder decodeObjectForKey:@"refreshToken"];
_mxCredentials.identityServer = _identityServerURL;
_mxCredentials.identityServerAccessToken = identityServerAccessToken;
_mxCredentials.deviceId = [coder decodeObjectForKey:@"deviceId"];
_mxCredentials.allowedCertificate = [coder decodeObjectForKey:@"allowedCertificate"];
if ([coder decodeObjectForKey:@"threePIDs"])
{
_threePIDs = [coder decodeObjectForKey:@"threePIDs"];
}
if ([coder decodeObjectForKey:@"device"])
{
_device = [coder decodeObjectForKey:@"device"];
}
if ([coder decodeObjectForKey:@"antivirusserverurl"])
{
_antivirusServerURL = [coder decodeObjectForKey:@"antivirusserverurl"];
}
if ([coder decodeObjectForKey:@"pushgatewayurl"])
{
_pushGatewayURL = [coder decodeObjectForKey:@"pushgatewayurl"];
}
_hasPusherForPushNotifications = [coder decodeBoolForKey:@"_enablePushNotifications"];
_hasPusherForPushKitNotifications = [coder decodeBoolForKey:@"enablePushKitNotifications"];
_enableInAppNotifications = [coder decodeBoolForKey:@"enableInAppNotifications"];
_disabled = [coder decodeBoolForKey:@"disabled"];
_isSoftLogout = [coder decodeBoolForKey:@"isSoftLogout"];
_warnedAboutEncryption = [coder decodeBoolForKey:@"warnedAboutEncryption"];
_others = [coder decodeObjectForKey:@"others"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:_mxCredentials.homeServer forKey:@"homeserverurl"];
[coder encodeObject:_mxCredentials.userId forKey:@"userid"];
[coder encodeObject:_mxCredentials.accessToken forKey:@"accesstoken"];
if (self.mxCredentials.accessTokenExpiresAt) {
[coder encodeInt64:_mxCredentials.accessTokenExpiresAt forKey:@"accessTokenExpiresAt"];
}
if (self.mxCredentials.refreshToken) {
[coder encodeObject:_mxCredentials.refreshToken forKey:@"refreshToken"];
}
[coder encodeObject:_mxCredentials.identityServerAccessToken forKey:@"identityserveraccesstoken"];
if (self.mxCredentials.deviceId)
{
[coder encodeObject:_mxCredentials.deviceId forKey:@"deviceId"];
}
if (self.mxCredentials.allowedCertificate)
{
[coder encodeObject:_mxCredentials.allowedCertificate forKey:@"allowedCertificate"];
}
if (self.threePIDs)
{
[coder encodeObject:_threePIDs forKey:@"threePIDs"];
}
if (self.device)
{
[coder encodeObject:_device forKey:@"device"];
}
if (self.identityServerURL)
{
[coder encodeObject:_identityServerURL forKey:@"identityserverurl"];
}
if (self.antivirusServerURL)
{
[coder encodeObject:_antivirusServerURL forKey:@"antivirusserverurl"];
}
if (self.pushGatewayURL)
{
[coder encodeObject:_pushGatewayURL forKey:@"pushgatewayurl"];
}
[coder encodeBool:_hasPusherForPushNotifications forKey:@"_enablePushNotifications"];
[coder encodeBool:_hasPusherForPushKitNotifications forKey:@"enablePushKitNotifications"];
[coder encodeBool:_enableInAppNotifications forKey:@"enableInAppNotifications"];
[coder encodeBool:_disabled forKey:@"disabled"];
[coder encodeBool:_isSoftLogout forKey:@"isSoftLogout"];
[coder encodeBool:_warnedAboutEncryption forKey:@"warnedAboutEncryption"];
[coder encodeObject:_others forKey:@"others"];
}
@end

View File

@@ -110,6 +110,8 @@ extern NSString *const MXKAccountManagerDataType;
*/
+ (MXKAccountManager *)sharedManager;
+ (MXKAccountManager *)sharedManagerWithReload:(BOOL)reload;
/**
Check for each enabled account if a matrix session is already opened.
Open a matrix session for each enabled account which doesn't have a session.
@@ -208,11 +210,6 @@ extern NSString *const MXKAccountManagerDataType;
*/
- (MXKAccount *)accountKnowingUserWithUserId:(NSString *)userId;
/**
Force the account manager to reload existing accounts from the local storage.
The account manager is supposed to handle itself the list of the accounts.
Call this method only when an account has been changed from an other application from the same group.
*/
- (void)forceReloadAccounts;
- (void)readAndWriteCredentials:(void (^)(NSArray<MXCredentials*> * _Nullable readData, void (^completion)(BOOL didUpdateCredentials)))readAnWriteHandler;
@end

View File

@@ -21,6 +21,8 @@
#import "MXKAppSettings.h"
#import "MXKTools.h"
#import "MXKAccountData.h"
#import "MXRefreshTokenData.h"
static NSString *const kMXKAccountsKeyOld = @"accounts";
static NSString *const kMXKAccountsKey = @"accountsV2";
@@ -43,13 +45,23 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
@implementation MXKAccountManager
+ (MXKAccountManager *)sharedManager
{
return [MXKAccountManager sharedManagerWithReload:NO];
}
+ (MXKAccountManager *)sharedManagerWithReload:(BOOL)reload
{
static MXKAccountManager *sharedAccountManager = nil;
static dispatch_once_t onceToken;
__block BOOL didLoad = false;
dispatch_once(&onceToken, ^{
didLoad = true;
sharedAccountManager = [[super allocWithZone:NULL] init];
});
if (reload && !didLoad) {
[sharedAccountManager loadAccounts];
}
return sharedAccountManager;
}
@@ -599,7 +611,6 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
- (void)loadAccounts
{
MXLogDebug(@"[MXKAccountManager] loadAccounts");
NSString *accountFile = [self accountFile];
if ([[NSFileManager defaultManager] fileExistsAtPath:accountFile])
{
@@ -665,12 +676,6 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
}
}
- (void)forceReloadAccounts
{
MXLogDebug(@"[MXKAccountManager] Force reload existing accounts from local storage");
[self loadAccounts];
}
- (NSData*)encryptData:(NSData*)data
{
// Exceptions are not caught as the key is always needed if the KeyProviderDelegate
@@ -723,4 +728,69 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
}
}
- (void)readAndWriteCredentials:(void (^)(NSArray<MXCredentials*> * _Nullable readData, void (^completion)(BOOL didUpdateCredentials)))readAnWriteHandler
{
NSError *error;
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
__block BOOL coordinatorSuccess = NO;
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: purposeIdentifier = %@", fileCoordinator.purposeIdentifier);
NSDate *coordinateStartTime = [NSDate date];
[fileCoordinator coordinateReadingItemAtURL:[self accountFileUrl]
options:0
writingItemAtURL:[self accountFileUrl]
options:NSFileCoordinatorWritingForMerging
error:&error
byAccessor:^(NSURL * _Nonnull newReadingURL, NSURL * _Nonnull newWritingURL) {
NSDate *accessorStartTime = [NSDate date];
NSTimeInterval acquireInterval = [accessorStartTime timeIntervalSinceDate:coordinateStartTime];
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: acquireInterval = %f", acquireInterval);
NSError *error = nil;
NSData* data = [NSData dataWithContentsOfURL:newReadingURL options:(NSDataReadingMappedAlways | NSDataReadingUncached) error:&error];
// Decrypt data if encryption method is provided
NSData *unciphered = [self decryptData:data];
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingFromData:unciphered error:&error];
decoder.requiresSecureCoding = false;
[decoder setClass:[MXKAccountData class] forClassName:@"MXKAccount"];
NSMutableArray<MXKAccountData*>* mxAccountsData = [decoder decodeObjectForKey:@"mxAccounts"];
NSMutableArray<MXCredentials*>* mxAccountCredentials = [NSMutableArray arrayWithCapacity:mxAccounts.count];
for(MXKAccountData *account in mxAccountsData){
[mxAccountCredentials addObject:account.mxCredentials];
}
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_enter(dispatchGroup);
__block BOOL didUpdate = NO;
readAnWriteHandler(mxAccountCredentials, ^(BOOL didUpdateCredentials) {
didUpdate = didUpdateCredentials;
dispatch_group_leave(dispatchGroup);
});
dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER);
if (didUpdate) {
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: did update saving credential data");
NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initRequiringSecureCoding: NO];
[encoder setClassName:@"MXKAccount" forClass:[MXKAccountData class]];
[encoder encodeObject:mxAccountsData forKey:@"mxAccounts"];
NSData *writeData = [self encryptData:[encoder encodedData]];
coordinatorSuccess = [writeData writeToURL:newWritingURL atomically:YES];
} else {
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: did not update not saving credential data");
coordinatorSuccess = YES;
}
NSDate *accessorEndTime = [NSDate date];
NSTimeInterval lockedTime = [accessorEndTime timeIntervalSinceDate:accessorStartTime];
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: lockedTime = %f", lockedTime);
}];
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials:exit %d", coordinatorSuccess);
}
- (NSURL *)accountFileUrl
{
return [NSURL fileURLWithPath: [self accountFile]];
}
@end

View File

@@ -56,8 +56,14 @@ class NotificationService: UNNotificationServiceExtension {
guard let userAccount = userAccount else {
return nil
}
return MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil)
let restClient = MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil, persistentTokenDataHandler: { persistTokenDataHandler in
MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler)
}, unauthenticatedHandler: { error, softLogout, refreshTokenAuth, completion in
userAccount.handleUnauthenticatedWithError(error, isSoftLogout: softLogout, isRefreshTokenAuth: refreshTokenAuth, andCompletion: completion)
})
return restClient
}()
private static var isLoggerInitialized: Bool = false
private lazy var pushGatewayRestClient: MXPushGatewayRestClient = {
let url = URL(string: BuildSettings.serverConfigSygnalAPIUrlString)!
@@ -91,6 +97,8 @@ class NotificationService: UNNotificationServiceExtension {
// log memory at the beginning of the process
logMemory()
setupAnalytics()
UNUserNotificationCenter.current().removeUnwantedNotifications()
// check if this is a Matrix notification
@@ -164,15 +172,26 @@ class NotificationService: UNNotificationServiceExtension {
}
}
private func setupAnalytics(){
// Configure our analytics. It will start if the option is enabled
let analytics = Analytics.shared
MXSDKOptions.sharedInstance().analyticsDelegate = analytics
analytics.startIfEnabled()
}
private func setup(withRoomId roomId: String, eventId: String, completion: @escaping () -> Void) {
MXKAccountManager.shared()?.forceReloadAccounts()
MXKAccountManager.sharedManager(withReload: true)
self.userAccount = MXKAccountManager.shared()?.activeAccounts.first
if let userAccount = userAccount {
Self.backgroundServiceInitQueue.sync {
if NotificationService.backgroundSyncService?.credentials != userAccount.mxCredentials {
MXLog.debug("[NotificationService] setup: MXBackgroundSyncService init: BEFORE")
self.logMemory()
NotificationService.backgroundSyncService = MXBackgroundSyncService(withCredentials: userAccount.mxCredentials)
NotificationService.backgroundSyncService = MXBackgroundSyncService(withCredentials: userAccount.mxCredentials, persistTokenDataHandler: { persistTokenDataHandler in
MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler)
}, unauthenticatedHandler: { error, softLogout, refreshTokenAuth, completion in
userAccount.handleUnauthenticatedWithError(error, isSoftLogout: softLogout, isRefreshTokenAuth: refreshTokenAuth, andCompletion: completion)
})
MXLog.debug("[NotificationService] setup: MXBackgroundSyncService init: AFTER")
self.logMemory()
}

View File

@@ -21,4 +21,6 @@
#import "MatrixKit-Bridging-Header.h"
#import "BuildInfo.h"
#endif /* RiotNSE_Bridging_Header_h */

View File

@@ -62,6 +62,8 @@ targets:
- path: ../Riot/Managers/Widgets/WidgetConstants.m
- path: ../Riot/PropertyWrappers/UserDefaultsBackedPropertyWrapper.swift
- path: ../Riot/Modules/MatrixKit
- path: ../Riot/Modules/Analytics
- path: ../Riot/Managers/AppInfo/
excludes:
- "**/*.md" # excludes all files with the .md extension
- path: ../Riot/Generated/MatrixKitStrings.swift

View File

@@ -81,8 +81,11 @@
NSMutableArray *cellData = [NSMutableArray array];
MXRestClient *mxRestClient = [[MXRestClient alloc] initWithCredentials:self.credentials andOnUnrecognizedCertificateBlock:nil andPersistentTokenDataHandler:^(void (^handler)(NSArray<MXCredentials *> *credentials, void (^completion)(BOOL didUpdateCredentials))) {
[[MXKAccountManager sharedManager] readAndWriteCredentials:handler];
} andUnauthenticatedHandler:nil];
// Add a fake matrix session to each room summary to provide it a REST client (used to handle correctly the room avatar).
MXSession *session = [[MXSession alloc] initWithMatrixRestClient:[[MXRestClient alloc] initWithCredentials:self.credentials andOnUnrecognizedCertificateBlock:nil]];
MXSession *session = [[MXSession alloc] initWithMatrixRestClient:mxRestClient];
for (id<MXRoomSummaryProtocol> summary in summaries)
{

View File

@@ -78,7 +78,14 @@
- (void)shareViewController:(ShareViewController *)shareViewController didRequestShareForRoomIdentifiers:(NSSet<NSString *> *)roomIdentifiers
{
MXSession *session = [[MXSession alloc] initWithMatrixRestClient:[[MXRestClient alloc] initWithCredentials:self.userAccount.mxCredentials andOnUnrecognizedCertificateBlock:nil]];
MXWeakify(self);
MXRestClient *restClient = [[MXRestClient alloc] initWithCredentials:self.userAccount.mxCredentials andOnUnrecognizedCertificateBlock:nil andPersistentTokenDataHandler:^(void (^handler)(NSArray<MXCredentials *> *credentials, void (^completion)(BOOL didUpdateCredentials))) {
[[MXKAccountManager sharedManager] readAndWriteCredentials:handler];
} andUnauthenticatedHandler:^(MXError *error, BOOL isSoftLogout, BOOL isRefreshTokenAuth, void (^completion)(void)) {
MXStrongifyAndReturnIfNil(self);
[self.userAccount handleUnauthenticatedWithError:error isSoftLogout:isSoftLogout isRefreshTokenAuth:isRefreshTokenAuth andCompletion:completion];
}];
MXSession *session = [[MXSession alloc] initWithMatrixRestClient:restClient];
[MXFileStore setPreloadOptions:0];
MXWeakify(session);
@@ -147,7 +154,7 @@
- (void)checkUserAccount
{
// Force account manager to reload account from the local storage.
[[MXKAccountManager sharedManager] forceReloadAccounts];
[MXKAccountManager sharedManagerWithReload:YES];
if (self.userAccount)
{

View File

@@ -52,6 +52,10 @@
[MXLog configure:configuration];
// Configure our analytics. It will start if the option is enabled
Analytics *analytics = Analytics.shared;
[MXSDKOptions sharedInstance].analyticsDelegate = analytics;
[analytics startIfEnabled];
[ThemeService.shared setThemeId:RiotSettings.shared.userInterfaceTheme];

View File

@@ -69,6 +69,7 @@ targets:
- path: ../Riot/Assets/SharedImages.xcassets
buildPhase: resources
- path: ../Riot/Modules/MatrixKit
- path: ../Riot/Modules/Analytics
excludes:
- "**/*.md" # excludes all files with the .md extension
- path: ../Riot/Generated/MatrixKitStrings.swift

View File

@@ -53,6 +53,11 @@
}
[MXLog configure:configuration];
// Configure our analytics. It will start if the option is enabled
Analytics *analytics = Analytics.shared;
[MXSDKOptions sharedInstance].analyticsDelegate = analytics;
[analytics startIfEnabled];
}
return self;
}

View File

@@ -15,3 +15,4 @@
//
#import "MatrixKit-Bridging-Header.h"
#import "BuildInfo.h"

View File

@@ -51,6 +51,10 @@ targets:
- path: ../Riot/Managers/Locale/LocaleProviderType.swift
- path: ../Riot/Managers/Locale/LocaleProvider.swift
- path: ../Riot/Modules/MatrixKit
- path: ../Riot/Modules/Analytics
- path: ../Riot/Managers/AppInfo/
- path: ../Riot/Managers/Locale/LocaleProviderType.swift
- path: ../Riot/Generated/Strings.swift
excludes:
- "**/*.md" # excludes all files with the .md extension
- path: ../Riot/Generated/MatrixKitStrings.swift