Skip to content

Commit

Permalink
Show server version info in server details
Browse files Browse the repository at this point in the history
  • Loading branch information
tmolitor-stud-tu committed Jan 4, 2024
1 parent 3c130b3 commit 26f4fd5
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Monal/Classes/ContactResources.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct ContactResources: View {
if softwareInfo.fromJid == contact.obj.contactJid && xmppAccount.accountNo == contact.obj.accountId {
DispatchQueue.main.async {
DDLogVerbose("Successfully matched software version info update to current contact: \(contact.obj)")
self.contactVersionInfos[softwareInfo.resource] = ObservableKVOWrapper<MLContactSoftwareVersionInfo>(softwareInfo)
self.contactVersionInfos[softwareInfo.resource ?? ""] = ObservableKVOWrapper<MLContactSoftwareVersionInfo>(softwareInfo)
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions Monal/Classes/DataLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ -(void) setResourceOnline:(XMPPPresence*) presenceObj forAccount:(NSNumber*) acc
}];
}

-(MLContactSoftwareVersionInfo* _Nullable) getSoftwareVersionInfoForContact:(NSString*)contact resource:(NSString*)resource andAccount:(NSNumber*)accountNo
-(MLContactSoftwareVersionInfo* _Nullable) getSoftwareVersionInfoForContact:(NSString*) contact resource:(NSString*) resource andAccount:(NSNumber*) accountNo
{
if(accountNo == nil)
return nil;
Expand All @@ -668,14 +668,14 @@ -(MLContactSoftwareVersionInfo* _Nullable) getSoftwareVersionInfoForContact:(NSS
}
}

-(void) setSoftwareVersionInfoForContact:(NSString*)contact
resource:(NSString*)resource
andAccount:(NSNumber*)account
-(void) setSoftwareVersionInfoForContact:(NSString*) contact
resource:(NSString*) resource
andAccount:(NSNumber*) account
withSoftwareInfo:(MLContactSoftwareVersionInfo*) newSoftwareInfo
{
[self.db voidWriteTransaction:^{
NSString* query = @"update buddy_resources set platform_App_Name=?, platform_App_Version=?, platform_OS=? where buddy_id in (select buddy_id from buddylist where account_id=? and buddy_name=?) and resource=?";
NSArray* params = @[newSoftwareInfo.appName, newSoftwareInfo.appVersion, newSoftwareInfo.platformOs, account, contact, resource];
NSArray* params = @[nilWrapper(newSoftwareInfo.appName), nilWrapper(newSoftwareInfo.appVersion), nilWrapper(newSoftwareInfo.platformOs), account, contact, resource];
[self.db executeNonQuery:query andArguments:params];
}];
}
Expand Down
2 changes: 2 additions & 0 deletions Monal/Classes/HelperTools.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#import "MLUDPLogger.h"
#import "MLStreamRedirect.h"
#import "commithash.h"
#import "MLContactSoftwareVersionInfo.h"

@import UserNotifications;
@import CoreImage;
Expand Down Expand Up @@ -643,6 +644,7 @@ +(id) unserializeData:(NSData*) data
[MLMessage class],
[NSURL class],
[OmemoState class],
[MLContactSoftwareVersionInfo class],
]] fromData:data error:&error];
if(error)
@throw [NSException exceptionWithName:@"NSError" reason:[NSString stringWithFormat:@"%@", error] userInfo:@{@"error": error}];
Expand Down
7 changes: 4 additions & 3 deletions Monal/Classes/MLContactSoftwareVersionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@

NS_ASSUME_NONNULL_BEGIN

@interface MLContactSoftwareVersionInfo : NSObject
@interface MLContactSoftwareVersionInfo : NSObject <NSSecureCoding>

@property (nonatomic, copy) NSString* fromJid;
@property (nonatomic, copy) NSString* resource;
@property (nonatomic, copy) NSString* _Nullable resource;
@property (nonatomic, copy) NSString* _Nullable appName;
@property (nonatomic, copy) NSString* _Nullable appVersion;
@property (nonatomic, copy) NSString* _Nullable platformOs;
@property (nonatomic, copy) NSDate* _Nullable lastInteraction;

-(instancetype) initWithJid:(NSString*) jid andRessource:(NSString*) resource andAppName:(NSString* _Nullable) appName andAppVersion:(NSString* _Nullable) appVersion andPlatformOS:(NSString* _Nullable) platformOs andLastInteraction:(NSDate* _Nullable) lastInteraction;
+(BOOL) supportsSecureCoding;
-(instancetype) initWithJid:(NSString*) jid andRessource:(NSString* _Nullable) resource andAppName:(NSString* _Nullable) appName andAppVersion:(NSString* _Nullable) appVersion andPlatformOS:(NSString* _Nullable) platformOs andLastInteraction:(NSDate* _Nullable) lastInteraction;
-(BOOL) isEqual:(id _Nullable) object;
-(NSUInteger) hash;

Expand Down
31 changes: 30 additions & 1 deletion Monal/Classes/MLContactSoftwareVersionInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ @interface MLContactSoftwareVersionInfo ()

@implementation MLContactSoftwareVersionInfo

-(instancetype) initWithJid:(NSString*) jid andRessource:(NSString*) resource andAppName:(NSString* _Nullable) appName andAppVersion:(NSString* _Nullable) appVersion andPlatformOS:(NSString* _Nullable) platformOs andLastInteraction:(NSDate* _Nullable) lastInteraction
+(BOOL) supportsSecureCoding
{
return YES;
}

-(instancetype) initWithJid:(NSString*) jid andRessource:(NSString* _Nullable) resource andAppName:(NSString* _Nullable) appName andAppVersion:(NSString* _Nullable) appVersion andPlatformOS:(NSString* _Nullable) platformOs andLastInteraction:(NSDate* _Nullable) lastInteraction
{
self = [super init];
self.fromJid = jid;
Expand All @@ -26,6 +31,28 @@ -(instancetype) initWithJid:(NSString*) jid andRessource:(NSString*) resource an
return self;
}

-(void) encodeWithCoder:(NSCoder*) coder
{
[coder encodeObject:self.fromJid forKey:@"fromJid"];
[coder encodeObject:self.resource forKey:@"resource"];
[coder encodeObject:self.appName forKey:@"appName"];
[coder encodeObject:self.appVersion forKey:@"appVersion"];
[coder encodeObject:self.platformOs forKey:@"platformOs"];
[coder encodeObject:self.lastInteraction forKey:@"lastInteraction"];
}

-(instancetype) initWithCoder:(NSCoder*) coder
{
self = [self init];
self.fromJid = [coder decodeObjectForKey:@"fromJid"];
self.resource = [coder decodeObjectForKey:@"resource"];
self.appName = [coder decodeObjectForKey:@"appName"];
self.appVersion = [coder decodeObjectForKey:@"appVersion"];
self.platformOs = [coder decodeObjectForKey:@"platformOs"];
self.lastInteraction = [coder decodeObjectForKey:@"lastInteraction"];
return self;
}

-(BOOL) isEqual:(id _Nullable) object
{
if(object == nil || self == object)
Expand All @@ -43,6 +70,8 @@ -(NSUInteger) hash

-(NSString*) id
{
if(self.resource == nil)
return [NSString stringWithFormat:@"%@", self.fromJid];
return [NSString stringWithFormat:@"%@/%@", self.fromJid, self.resource];
}

Expand Down
42 changes: 17 additions & 25 deletions Monal/Classes/MLIQProcessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -708,35 +708,27 @@ +(BOOL) processRosterWithAccount:(xmpp*) account andIqNode:(XMPPIQ*) iqNode
+(void) iqVersionResult:(XMPPIQ*) iqNode forAccount:(xmpp*) account
{
NSString* iqAppName = [iqNode findFirst:@"{jabber:iq:version}query/name#"];
if(!iqAppName)
iqAppName = @"";
NSString* iqAppVersion = [iqNode findFirst:@"{jabber:iq:version}query/version#"];
if(!iqAppVersion)
iqAppVersion = @"";
NSString* iqPlatformOS = [iqNode findFirst:@"{jabber:iq:version}query/os#"];
if(!iqPlatformOS)
iqPlatformOS = @"";

MLContactSoftwareVersionInfo* versionDBInfo = [[DataLayer sharedInstance] getSoftwareVersionInfoForContact:iqNode.fromUser resource:iqNode.fromResource andAccount:account.accountNo];

if(versionDBInfo == nil || !(
[versionDBInfo.appName isEqualToString:iqAppName] &&
[versionDBInfo.appVersion isEqualToString:iqAppVersion] &&
[versionDBInfo.platformOs isEqualToString:iqPlatformOS]
)) {
DDLogVerbose(@"Updating software version info for %@", iqNode.from);
NSDate* lastInteraction = [[DataLayer sharedInstance] lastInteractionOfJid:iqNode.fromUser andResource:iqNode.fromResource forAccountNo:account.accountNo];
MLContactSoftwareVersionInfo* newSoftwareVersionInfo = [[MLContactSoftwareVersionInfo alloc] initWithJid:iqNode.fromUser andRessource:iqNode.fromResource andAppName:iqAppName andAppVersion:iqAppVersion andPlatformOS:iqPlatformOS andLastInteraction:lastInteraction];

[[DataLayer sharedInstance] setSoftwareVersionInfoForContact:iqNode.fromUser
resource:iqNode.fromResource
andAccount:account.accountNo
withSoftwareInfo:newSoftwareVersionInfo];

[[MLNotificationQueue currentQueue] postNotificationName:kMonalXmppUserSoftWareVersionRefresh
object:account
userInfo:@{@"versionInfo": newSoftwareVersionInfo}];
if([iqNode.fromUser isEqualToString:account.connectionProperties.identity.domain])
{
account.connectionProperties.serverVersion = [[MLContactSoftwareVersionInfo alloc] initWithJid:iqNode.fromUser andRessource:iqNode.fromResource andAppName:iqAppName andAppVersion:iqAppVersion andPlatformOS:iqPlatformOS andLastInteraction:[NSDate date]];
return;
}

DDLogVerbose(@"Updating software version info for %@", iqNode.from);
NSDate* lastInteraction = [[DataLayer sharedInstance] lastInteractionOfJid:iqNode.fromUser andResource:iqNode.fromResource forAccountNo:account.accountNo];
MLContactSoftwareVersionInfo* newSoftwareVersionInfo = [[MLContactSoftwareVersionInfo alloc] initWithJid:iqNode.fromUser andRessource:iqNode.fromResource andAppName:iqAppName andAppVersion:iqAppVersion andPlatformOS:iqPlatformOS andLastInteraction:lastInteraction];

[[DataLayer sharedInstance] setSoftwareVersionInfoForContact:iqNode.fromUser
resource:iqNode.fromResource
andAccount:account.accountNo
withSoftwareInfo:newSoftwareVersionInfo];

[[MLNotificationQueue currentQueue] postNotificationName:kMonalXmppUserSoftWareVersionRefresh
object:account
userInfo:@{@"versionInfo": newSoftwareVersionInfo}];
}

+(void) respondWithErrorTo:(XMPPIQ*) iqNode onAccount:(xmpp*) account
Expand Down
37 changes: 31 additions & 6 deletions Monal/Classes/MLServerDetails.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
#import "MLServerDetails.h"
#import "UIColor+Theme.h"
#import "SCRAM.h"
#import "MLContactSoftwareVersionInfo.h"
#import "DataLayer.h"

@interface MLServerDetails ()

@property (nonatomic, strong) MLContactSoftwareVersionInfo* serverVersion;
@property (nonatomic, strong) NSMutableArray* serverCaps;
@property (nonatomic, strong) NSMutableArray* stunTurnServers;
@property (nonatomic, strong) NSMutableArray* srvRecords;
Expand All @@ -23,7 +26,9 @@ @interface MLServerDetails ()

@implementation MLServerDetails

//TODO: make all of these shareable as one long text (or json)
enum MLServerDetailsSections {
SERVER_VERSION_SECTION,
SUPPORTED_SERVER_XEPS_SECTION,
VOIP_SECTION,
SRV_RECORS_SECTION,
Expand All @@ -36,6 +41,7 @@ @implementation MLServerDetails
#define SERVER_DETAILS_COLOR_OK @"Blue"
#define SERVER_DETAILS_COLOR_NON_IDEAL @"Orange"
#define SERVER_DETAILS_COLOR_ERROR @"Red"
#define SERVER_DETAILS_COLOR_NONE @""

- (void) viewDidLoad
{
Expand All @@ -55,6 +61,7 @@ -(void) viewWillAppear:(BOOL) animated
self.navigationItem.title = self.xmppAccount.connectionProperties.identity.domain;
self.tableView.allowsSelection = NO;

self.serverVersion = self.xmppAccount.connectionProperties.serverVersion;
[self checkServerCaps:self.xmppAccount.connectionProperties];
[self convertSRVRecordsToReadable];
[self checkTLSVersions:self.xmppAccount.connectionProperties];
Expand Down Expand Up @@ -290,7 +297,9 @@ -(NSInteger) numberOfSectionsInTableView:(UITableView*) tableView

-(NSInteger) tableView:(UITableView*) tableView numberOfRowsInSection:(NSInteger) section
{
if(section == SUPPORTED_SERVER_XEPS_SECTION)
if(section == SERVER_VERSION_SECTION)
return 1;
else if(section == SUPPORTED_SERVER_XEPS_SECTION)
return (NSInteger)self.serverCaps.count;
else if(section == VOIP_SECTION)
return (NSInteger)self.stunTurnServers.count;
Expand All @@ -310,7 +319,21 @@ -(UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NS
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"serverCell" forIndexPath:indexPath];

NSDictionary* dic;
if(indexPath.section == SUPPORTED_SERVER_XEPS_SECTION)
if(indexPath.section == SERVER_VERSION_SECTION)
{
if(indexPath.row == 0)
{
NSString* serverName = nilDefault(self.serverVersion.appName, NSLocalizedString(@"<unknown server>", @"server details"));
NSString* serverVersion = nilDefault(self.serverVersion.appVersion, NSLocalizedString(@"<unknown version>", @"server details"));
NSString* serverPlatform = self.serverVersion.platformOs != nil ? [NSString stringWithFormat:NSLocalizedString(@" running on %@", @"server details"), self.serverVersion.platformOs] : @"";
dic = @{
@"Color": SERVER_DETAILS_COLOR_NONE,
@"Title": serverName,
@"Description": [NSString stringWithFormat:NSLocalizedString(@"version %@%@", @"server details"), serverVersion, serverPlatform],
};
}
}
else if(indexPath.section == SUPPORTED_SERVER_XEPS_SECTION)
dic = [self.serverCaps objectAtIndex:(NSUInteger)indexPath.row];
if(indexPath.section == VOIP_SECTION)
dic = [self.stunTurnServers objectAtIndex:(NSUInteger)indexPath.row];
Expand All @@ -323,8 +346,8 @@ -(UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NS
else if(indexPath.section == CB_SECTION)
dic = [self.channelBindingTypes objectAtIndex:(NSUInteger)indexPath.row];

cell.textLabel.text = [dic objectForKey:@"Title"];
cell.detailTextLabel.text = [dic objectForKey:@"Description"];
cell.textLabel.text = nilExtractor([dic objectForKey:@"Title"]);
cell.detailTextLabel.text = nilExtractor([dic objectForKey:@"Description"]);

// Add background color to selected cells
if([dic objectForKey:@"Color"])
Expand Down Expand Up @@ -363,9 +386,11 @@ -(UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NS

-(NSString*) tableView:(UITableView*) tableView titleForHeaderInSection:(NSInteger) section
{
if(section == SUPPORTED_SERVER_XEPS_SECTION)
if(section == SERVER_VERSION_SECTION)
return NSLocalizedString(@"This is the software running on your server.", @"");
else if(section == SUPPORTED_SERVER_XEPS_SECTION)
return NSLocalizedString(@"These are the modern XMPP capabilities Monal detected on your server after you have logged in.", @"");
if(section == VOIP_SECTION)
else if(section == VOIP_SECTION)
return NSLocalizedString(@"These are STUN and TURN services announced by your server. (blue entries are used by monal)", @"");
else if(section == SRV_RECORS_SECTION)
return NSLocalizedString(@"These are SRV resource records found for your domain.", @"");
Expand Down
3 changes: 3 additions & 0 deletions Monal/Classes/MLXMPPConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

NS_ASSUME_NONNULL_BEGIN

@class MLContactSoftwareVersionInfo;

/**
A class to hold the the identity, host, state and discovered properties of an xmpp connection
*/
Expand All @@ -32,6 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) NSMutableArray* discoveredServices;
@property (nonatomic, strong) NSMutableArray* discoveredStunTurnServers;
@property (nonatomic, strong) NSMutableDictionary* discoveredAdhocCommands;
@property (nonatomic, strong) MLContactSoftwareVersionInfo* _Nullable serverVersion;

@property (nonatomic, strong) NSString* _Nullable conferenceServer;

Expand Down
1 change: 1 addition & 0 deletions Monal/Classes/MLXMPPConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ -(id) initWithServer:(MLXMPPServer*) server andIdentity:(MLXMPPIdentity*) identi
self.discoveredServices = [NSMutableArray new];
self.discoveredStunTurnServers = [NSMutableArray new];
self.discoveredAdhocCommands = [NSMutableDictionary new];
self.serverVersion = nil;
return self;
}

Expand Down
14 changes: 13 additions & 1 deletion Monal/Classes/xmpp.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
@import AVFoundation;
@import WebRTC;

#define STATE_VERSION 9
#define STATE_VERSION 10
#define CONNECT_TIMEOUT 7.0
#define IQ_TIMEOUT 60.0
NSString* const kQueueID = @"queueID";
Expand Down Expand Up @@ -3431,6 +3431,9 @@ -(void) realPersistState

if(self.connectionProperties.discoveredAdhocCommands)
[values setObject:[self.connectionProperties.discoveredAdhocCommands copy] forKey:@"discoveredAdhocCommands"];

if(self.connectionProperties.serverVersion)
[values setObject:self.connectionProperties.serverVersion forKey:@"serverVersion"];

[values setObject:self->_lastInteractionDate forKey:@"lastInteractionDate"];
[values setValue:[NSDate date] forKey:@"stateSavedAt"];
Expand Down Expand Up @@ -3542,6 +3545,7 @@ -(void) realReadState
self.connectionProperties.discoveredServices = [[dic objectForKey:@"discoveredServices"] mutableCopy];
self.connectionProperties.discoveredStunTurnServers = [[dic objectForKey:@"discoveredStunTurnServers"] mutableCopy];
self.connectionProperties.discoveredAdhocCommands = [[dic objectForKey:@"discoveredAdhocCommands"] mutableCopy];
self.connectionProperties.serverVersion = [dic objectForKey:@"serverVersion"];

self.connectionProperties.uploadServer = [dic objectForKey:@"uploadServer"];
self.connectionProperties.conferenceServer = [dic objectForKey:@"conferenceServer"];
Expand Down Expand Up @@ -3800,6 +3804,13 @@ -(void) queryDisco
[self sendIq:adhocCommands withHandler:$newHandler(MLIQProcessor, handleAdhocDisco)];
}

-(void) queryServerVersion
{
XMPPIQ* serverVersion = [[XMPPIQ alloc] initWithType:kiqGetType];
[serverVersion getEntitySoftWareVersionTo:self.connectionProperties.identity.domain];
[self send:serverVersion];
}

-(void) queryExternalServicesOn:(NSString*) jid
{
XMPPIQ* externalDisco = [[XMPPIQ alloc] initWithType:kiqGetType];
Expand Down Expand Up @@ -3951,6 +3962,7 @@ -(void) initSession
//if and what pubsub/pep features the server supports, before handling that
//we can pipeline the disco requests and outgoing presence broadcast, though
[self queryDisco];
[self queryServerVersion];
[self purgeOfflineStorage];
[self sendPresence]; //this will trigger a replay of offline stanzas on prosody (no XEP-0013 support anymore 😡)
//the offline messages will come in *after* we initialized the mam query, because the disco result comes in first
Expand Down

0 comments on commit 26f4fd5

Please sign in to comment.