blob: 852b11ca216cd698246c89a684a2b1e7373d2295 [file] [log] [blame]
Alexandre Lision624b1a82016-09-11 19:29:01 -04001/*
Sébastien Blin029ffa82019-01-02 17:43:48 -05002 * Copyright (C) 2016-2019 Savoir-faire Linux Inc.
Alexandre Lision624b1a82016-09-11 19:29:01 -04003 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#import "MigrateRingAccountsWC.h"
21
22//LRC
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040023#import <api/newaccountmodel.h>
Alexandre Lision624b1a82016-09-11 19:29:01 -040024
25//RING
26#import "views/ITProgressIndicator.h"
27
28@interface MigrateRingAccountsWC() <NSTextFieldDelegate>{
29 __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
30 __unsafe_unretained IBOutlet NSSecureTextField* passwordConfirmField;
31 __unsafe_unretained IBOutlet NSTextField* infoField;
32 __unsafe_unretained IBOutlet NSTextField* errorField;
33 __unsafe_unretained IBOutlet ITProgressIndicator* progressIndicator;
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040034 __unsafe_unretained IBOutlet NSImageView* profileImage;
35 __unsafe_unretained IBOutlet NSTextField* alias;
Alexandre Lision624b1a82016-09-11 19:29:01 -040036}
37
38- (IBAction)onClickComplete:(id)sender;
39@end
40
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040041@implementation MigrateRingAccountsWC {
Alexandre Lision624b1a82016-09-11 19:29:01 -040042 struct {
43 unsigned int didComplete:1;
44 unsigned int didCompleteWithError:1;
45 } delegateRespondsTo;
46}
47
48NSTimer* errorTimer;
49QMetaObject::Connection stateChanged;
50
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040051@synthesize accountModel, accountToMigrate;
52
Alexandre Lision624b1a82016-09-11 19:29:01 -040053#pragma mark - Initialise / Setters
54- (id)initWithDelegate:(id <MigrateRingAccountsDelegate>) del actionCode:(NSInteger) code
55{
56 return [super initWithWindowNibName:@"MigrateRingAccountsWindow" delegate:del actionCode:code];
57}
58
59- (void) awakeFromNib{
60 [self setInfoMessageForAccount];
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040061 [profileImage setWantsLayer: YES];
62 profileImage.layer.cornerRadius = 40;
63 profileImage.layer.masksToBounds = YES;
Alexandre Lision624b1a82016-09-11 19:29:01 -040064}
65
66- (void)setDelegate:(id <MigrateRingAccountsDelegate>)aDelegate
67{
68 if (super.delegate != aDelegate) {
69 [super setDelegate: aDelegate];
70 delegateRespondsTo.didCompleteWithError = [self.delegate respondsToSelector:@selector(migrationDidCompleteWithError)];
71 delegateRespondsTo.didComplete = [self.delegate respondsToSelector:@selector(migrationDidComplete)];
72 }
73}
74
Alexandre Lision624b1a82016-09-11 19:29:01 -040075- (void) setInfoMessageForAccount
76{
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040077 const lrc::api::account::Info& accountInfo = self.accountModel->getAccountInfo(accountToMigrate);
78 NSData *imageData = [[NSData alloc]
79 initWithBase64EncodedString: @(accountInfo.profileInfo.avatar.c_str())
80 options:NSDataBase64DecodingIgnoreUnknownCharacters];
81 NSImage *image = [[NSImage alloc] initWithData:imageData];
82 if (image) {
83 profileImage.image = image;
84 } else {
85 profileImage.image = [NSImage imageNamed:@"default_avatar_overlay.png"];
86 profileImage.layer.backgroundColor = [[NSColor grayColor] CGColor];
87 }
88 alias.stringValue = @(accountInfo.profileInfo.alias.c_str());
89
90 NSMutableAttributedString* infoMessage = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"This account needs to be migrated",@"Text shown to the user")];
Alexandre Lision624b1a82016-09-11 19:29:01 -040091 [infoMessage appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
Alexandre Lision624b1a82016-09-11 19:29:01 -040092 const CGFloat fontSize = 13;
93 NSDictionary *attrs = @{
94 NSFontAttributeName:[NSFont boldSystemFontOfSize:fontSize]
95 };
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040096 auto registredName = accountInfo.registeredName;
97 if(!registredName.empty()) {
98 [infoMessage appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedString(@"Registered name: ",@"Text shown to the user")
99 attributes:attrs]];
100 [infoMessage appendAttributedString:[[NSAttributedString alloc] initWithString:@(registredName.c_str()) attributes:attrs]];
101 } else {
102 [infoMessage appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedString(@"ID: ",@"Text shown to the user")
103 attributes:attrs]];
104 [infoMessage appendAttributedString:[[NSAttributedString alloc] initWithString:@(accountInfo.profileInfo.uri.c_str()) attributes:attrs]];
105
106 }
Alexandre Lision624b1a82016-09-11 19:29:01 -0400107 [infoMessage appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
108 [infoMessage appendAttributedString:[[NSAttributedString alloc] initWithString:NSLocalizedString(@"To proceed with the migration, you must choose a password for your account. This password will be used to encrypt your master key. It will be required for adding new devices to your Ring account. If you are not ready to choose a password, you may close Ring and resume the migration later.",@"Text shown to the user")]];
109 [infoField setAttributedStringValue:infoMessage];
110}
111
Alexandre Lision624b1a82016-09-11 19:29:01 -0400112- (void) showError:(NSString*) errorMessage
113{
114 [errorField setStringValue:errorMessage];
115 [super showError];
116}
117
118- (void)showLoading
119{
120 [progressIndicator setNumberOfLines:30];
121 [progressIndicator setWidthOfLine:2];
122 [progressIndicator setLengthOfLine:5];
123 [progressIndicator setInnerMargin:20];
124 [super showLoading];
125}
126
127#pragma mark - Events Handlers
128- (IBAction)removeAccount:(id)sender
129{
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400130 self.accountModel->removeAccount(accountToMigrate);
Alexandre Lision624b1a82016-09-11 19:29:01 -0400131 [self cancelPressed:sender];
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400132 if (delegateRespondsTo.didComplete)
133 [((id<MigrateRingAccountsDelegate>)self.delegate) migrationDidComplete];
Alexandre Lision624b1a82016-09-11 19:29:01 -0400134}
135
136- (IBAction)startMigration:(NSButton *)sender
137{
138 if (![self validatePasswords]) {
139 [self showError:NSLocalizedString(@"Password and confirmation mismatch.",@"Text show to the user when password didn't match")];
140 } else {
141 [self showLoading];
142 errorTimer = [NSTimer scheduledTimerWithTimeInterval:30
143 target:self
144 selector:@selector(didCompleteWithError) userInfo:nil
145 repeats:NO];
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400146 stateChanged = QObject::connect(self.accountModel,
147 &lrc::api::NewAccountModel::migrationEnded,
148 [self](const std::string& accountId, bool ok) {
149 if (accountToMigrate != accountId) {
150 return;
151 }
152 if (ok) {
153 [self didComplete];
154 } else {
155 [self didCompleteWithError];
Alexandre Lision624b1a82016-09-11 19:29:01 -0400156 }
157 });
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400158 lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(accountToMigrate);
159 accountProperties.archivePassword = [self.password UTF8String];
160 self.accountModel->setAccountConfig(accountToMigrate, accountProperties);
Alexandre Lision624b1a82016-09-11 19:29:01 -0400161 }
162}
163
164- (BOOL)validatePasswords
165{
166 BOOL result = (self.password.length != 0 && [self.password isEqualToString:self.passwordConfirmation]);
167 NSLog(@"ValidatesPasswords : %s", result ? "true" : "false");
168 return result;
169}
170
171+ (NSSet *)keyPathsForValuesAffectingValidatePasswords
172{
173 return [NSSet setWithObjects:@"password", @"passwordConfirmation", nil];
174}
175
Alexandre Lision624b1a82016-09-11 19:29:01 -0400176#pragma mark - Delegates
177- (void)didComplete
178{
179 [errorTimer invalidate];
180 errorTimer = nil;
181 [self showFinal];
182}
183
184- (void)onClickComplete:(id)sender
185{
186 [self cancelPressed:sender];
187 if (delegateRespondsTo.didComplete)
188 [((id<MigrateRingAccountsDelegate>)self.delegate) migrationDidComplete];
189}
190
Alexandre Lision624b1a82016-09-11 19:29:01 -0400191- (void)didCompleteWithError
192{
193 [self showError:NSLocalizedString(@"Failed to migrate your account. You can retry by pressing Ok or delete your account.",@"Error message shown to user when it is impossible to migrate account")];
194}
195
Alexandre Lision624b1a82016-09-11 19:29:01 -0400196@end