mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-02 06:06:57 +02:00
Merge pull request #1012 from vector-im/keys_export
E2E keys export: Add an "Export keys" button to the settings
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
|
||||
#import "MediaPickerViewController.h"
|
||||
|
||||
@interface SettingsViewController : MXKViewController<UITextFieldDelegate, MediaPickerViewControllerDelegate, UITableViewDelegate, UITableViewDataSource, MXKDeviceViewDelegate>
|
||||
@interface SettingsViewController : MXKViewController<UITextFieldDelegate, MediaPickerViewControllerDelegate, UITableViewDelegate, UITableViewDataSource, MXKDeviceViewDelegate, UIDocumentInteractionControllerDelegate>
|
||||
|
||||
@property (nonatomic) IBOutlet UITableView *tableView;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2017 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.
|
||||
@@ -27,6 +28,8 @@
|
||||
#import <Photos/Photos.h>
|
||||
#import <MediaPlayer/MediaPlayer.h>
|
||||
|
||||
#import "MXKEncryptionKeysExportView.h"
|
||||
|
||||
#import "OLMKit/OLMKit.h"
|
||||
|
||||
enum {
|
||||
@@ -70,6 +73,10 @@ enum {
|
||||
#define LABS_CRYPTO_INDEX 0
|
||||
#define LABS_COUNT 1
|
||||
|
||||
#define CRYPTOGRAPHY_INFO_INDEX 0
|
||||
#define CRYPTOGRAPHY_EXPORT_INDEX 1
|
||||
#define CRYPTOGRAPHY_COUNT 2
|
||||
|
||||
#define SECTION_TITLE_PADDING_WHEN_HIDDEN 0.01f
|
||||
|
||||
typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
@@ -137,6 +144,11 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
|
||||
//
|
||||
UIAlertController *resetPwdAlertController;
|
||||
|
||||
// The document interaction Controller used to export e2e keys
|
||||
UIDocumentInteractionController *documentInteractionController;
|
||||
NSURL *keyExportsFile;
|
||||
NSTimer *keyExportsFileDeletionTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,6 +232,13 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
if (documentInteractionController)
|
||||
{
|
||||
[documentInteractionController dismissPreviewAnimated:NO];
|
||||
[documentInteractionController dismissMenuAnimated:NO];
|
||||
documentInteractionController = nil;
|
||||
}
|
||||
|
||||
if (isSavingInProgress || isResetPwdInProgress || isEmailBindingInProgress)
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
@@ -798,7 +817,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
// Check whether this section is visible.
|
||||
if (self.mainSession.crypto)
|
||||
{
|
||||
count = 1;
|
||||
count = CRYPTOGRAPHY_COUNT;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
@@ -1323,16 +1342,39 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CRYPTOGRAPHY_INDEX)
|
||||
{
|
||||
MXKTableViewCell *cryptoCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier]];
|
||||
if (!cryptoCell)
|
||||
if (row == CRYPTOGRAPHY_INFO_INDEX)
|
||||
{
|
||||
cryptoCell = [[MXKTableViewCell alloc] init];
|
||||
MXKTableViewCell *cryptoCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCell defaultReuseIdentifier]];
|
||||
if (!cryptoCell)
|
||||
{
|
||||
cryptoCell = [[MXKTableViewCell alloc] init];
|
||||
}
|
||||
|
||||
cryptoCell.textLabel.attributedText = [self cryptographyInformation];
|
||||
cryptoCell.textLabel.numberOfLines = 0;
|
||||
|
||||
cell = cryptoCell;
|
||||
}
|
||||
else if (row == CRYPTOGRAPHY_EXPORT_INDEX)
|
||||
{
|
||||
MXKTableViewCellWithButton *exportKeysBtnCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]];
|
||||
if (!exportKeysBtnCell)
|
||||
{
|
||||
exportKeysBtnCell = [[MXKTableViewCellWithButton alloc] init];
|
||||
}
|
||||
|
||||
NSString *btnTitle = NSLocalizedStringFromTable(@"settings_crypto_export", @"Vector", nil);
|
||||
[exportKeysBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
|
||||
[exportKeysBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateHighlighted];
|
||||
[exportKeysBtnCell.mxkButton setTintColor:kVectorColorGreen];
|
||||
exportKeysBtnCell.mxkButton.titleLabel.font = [UIFont systemFontOfSize:17];
|
||||
|
||||
[exportKeysBtnCell.mxkButton removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
[exportKeysBtnCell.mxkButton addTarget:self action:@selector(exportEncryptionKeys:) forControlEvents:UIControlEventTouchUpInside];
|
||||
exportKeysBtnCell.mxkButton.accessibilityIdentifier = nil;
|
||||
|
||||
cell = exportKeysBtnCell;
|
||||
}
|
||||
|
||||
cryptoCell.textLabel.attributedText = [self cryptographyInformation];
|
||||
cryptoCell.textLabel.numberOfLines = 0;
|
||||
|
||||
cell = cryptoCell;
|
||||
}
|
||||
|
||||
return cell;
|
||||
@@ -1427,7 +1469,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
[label sizeToFit];
|
||||
return label.frame.size.height + 16;
|
||||
}
|
||||
else if (indexPath.section == SETTINGS_SECTION_CRYPTOGRAPHY_INDEX)
|
||||
else if (indexPath.section == SETTINGS_SECTION_CRYPTOGRAPHY_INDEX && indexPath.row == CRYPTOGRAPHY_INFO_INDEX)
|
||||
{
|
||||
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 50)];
|
||||
label.numberOfLines = 0;
|
||||
@@ -2180,6 +2222,65 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
[self presentViewController:navigationController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)exportEncryptionKeys:(UITapGestureRecognizer *)recognizer
|
||||
{
|
||||
[currentAlert dismiss:NO];
|
||||
|
||||
MXKEncryptionKeysExportView *exportView = [[MXKEncryptionKeysExportView alloc] initWithMatrixSession:self.mainSession];
|
||||
currentAlert = exportView;
|
||||
|
||||
// Use a temporary file for the export
|
||||
keyExportsFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"riot-keys.txt"]];
|
||||
|
||||
// Make sure the file is empty
|
||||
[self deleteKeyExportFile];
|
||||
|
||||
// Show the export dialog
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[exportView showInViewController:self toExportKeysToFile:keyExportsFile onComplete:^(BOOL success) {
|
||||
|
||||
if (weakSelf && success)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->currentAlert = nil;
|
||||
|
||||
// Let another app handling this file
|
||||
self->documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:keyExportsFile];
|
||||
[self->documentInteractionController setDelegate:self];
|
||||
|
||||
if ([self->documentInteractionController presentOptionsMenuFromRect:self.view.frame inView:self.view animated:YES])
|
||||
{
|
||||
// We want to delete the temp keys file after it has been processed by the other app.
|
||||
// We use [UIDocumentInteractionControllerDelegate didEndSendingToApplication] for that
|
||||
// but it is not reliable for all cases (see http://stackoverflow.com/a/21867096).
|
||||
// So, arm a timer to auto delete the file after 10mins.
|
||||
keyExportsFileDeletionTimer = [NSTimer scheduledTimerWithTimeInterval:600 target:self selector:@selector(deleteKeyExportFile) userInfo:self repeats:NO];
|
||||
}
|
||||
else
|
||||
{
|
||||
self->documentInteractionController = nil;
|
||||
[self deleteKeyExportFile];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)deleteKeyExportFile
|
||||
{
|
||||
// Cancel the deletion timer if it is still here
|
||||
if (keyExportsFileDeletionTimer)
|
||||
{
|
||||
[keyExportsFileDeletionTimer invalidate];
|
||||
keyExportsFileDeletionTimer = nil;
|
||||
}
|
||||
|
||||
// And delete the file
|
||||
if (keyExportsFile && [[NSFileManager defaultManager] fileExistsAtPath:keyExportsFile.path])
|
||||
{
|
||||
[[NSFileManager defaultManager] removeItemAtPath:keyExportsFile.path error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - MediaPickerViewController Delegate
|
||||
|
||||
- (void)dismissMediaPicker
|
||||
@@ -2449,4 +2550,17 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
||||
[self presentViewController:resetPwdAlertController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - UIDocumentInteractionControllerDelegate
|
||||
|
||||
- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application
|
||||
{
|
||||
// If iOS wants to call this method, this is the right time to remove the file
|
||||
[self deleteKeyExportFile];
|
||||
}
|
||||
|
||||
- (void)documentInteractionControllerDidDismissOptionsMenu:(UIDocumentInteractionController *)controller
|
||||
{
|
||||
documentInteractionController = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user