Skip to content

Commit

Permalink
Merge pull request #222 from Hirobreak/2fa
Browse files Browse the repository at this point in the history
Two-factor Auth
  • Loading branch information
danieltigse authored Oct 19, 2018
2 parents 84e0027 + cfe66fc commit e58ecaf
Show file tree
Hide file tree
Showing 34 changed files with 320 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<EnvironmentVariable
key = "forceProduction"
value = "true"
isEnabled = "NO">
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class CreateCustomJSONFileAsyncTask {
handleRow($0.toDictionary(emailId: emailId))
}



DispatchQueue.main.async {
completion(nil, self.fileURL)
}
Expand Down
33 changes: 23 additions & 10 deletions iOS-Email-Client/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,9 @@
<constraint firstAttribute="width" constant="43" id="kPw-4a-gTD"/>
</constraints>
<color key="onTintColor" red="0.0" green="0.56862745098039214" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="onSwitchToggle:" destination="ZzE-Yh-VbX" eventType="valueChanged" id="Ebg-dL-bAK"/>
</connections>
</switch>
</subviews>
<constraints>
Expand All @@ -1397,6 +1400,7 @@
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="availableSwitch" destination="kgW-OS-3hM" id="oVz-ch-0Ua"/>
<outlet property="optionLabel" destination="5wZ-K9-zuW" id="niO-4k-IcX"/>
</connections>
</tableViewCell>
Expand Down Expand Up @@ -1558,7 +1562,7 @@
</connections>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NsV-eR-Br8">
<rect key="frame" x="243" y="288.5" width="105" height="38"/>
<rect key="frame" x="243" y="323.5" width="105" height="38"/>
<color key="backgroundColor" red="0.0" green="0.56862745098039214" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="38" id="698-sM-68Z"/>
Expand All @@ -1578,13 +1582,20 @@
</connections>
</button>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="i2e-ku-M8K">
<rect key="frame" x="285.5" y="297.5" width="20" height="20"/>
<rect key="frame" x="285.5" y="332.5" width="20" height="20"/>
</activityIndicatorView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Note: Changing your recovery email will turn off Two-Factor Authentication" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lM2-53-pVD">
<rect key="frame" x="27" y="276.5" width="321" height="38.5"/>
<fontDescription key="fontDescription" name="NunitoSans-Regular" family="Nunito Sans" pointSize="14"/>
<color key="textColor" red="0.44705882349999998" green="0.44705882349999998" blue="0.44705882349999998" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Upi-pd-9ph" firstAttribute="centerY" secondItem="S9Q-rO-GEN" secondAttribute="centerY" id="08s-mZ-uvB"/>
<constraint firstItem="W6o-Yn-D7Z" firstAttribute="centerX" secondItem="n3y-BG-AGw" secondAttribute="centerX" id="89z-bC-lqJ"/>
<constraint firstItem="lM2-53-pVD" firstAttribute="top" secondItem="nCs-ch-41A" secondAttribute="bottom" constant="18" id="AVH-O1-6N5"/>
<constraint firstItem="i2e-ku-M8K" firstAttribute="centerX" secondItem="NsV-eR-Br8" secondAttribute="centerX" id="C2f-ZQ-KiA"/>
<constraint firstItem="nCs-ch-41A" firstAttribute="trailing" secondItem="Zcd-QO-oCP" secondAttribute="trailing" id="Dob-nd-Ubf"/>
<constraint firstItem="nCs-ch-41A" firstAttribute="top" secondItem="Zcd-QO-oCP" secondAttribute="bottom" constant="15" id="E0I-5T-wke"/>
Expand All @@ -1598,11 +1609,13 @@
<constraint firstItem="n3y-BG-AGw" firstAttribute="top" secondItem="iNz-jU-IJX" secondAttribute="bottom" constant="15" id="UxJ-HK-xQo"/>
<constraint firstItem="Upi-pd-9ph" firstAttribute="leading" secondItem="iNz-jU-IJX" secondAttribute="trailing" id="W9j-nV-IB8"/>
<constraint firstItem="i2e-ku-M8K" firstAttribute="centerY" secondItem="NsV-eR-Br8" secondAttribute="centerY" id="h8k-fa-dyW"/>
<constraint firstItem="lM2-53-pVD" firstAttribute="trailing" secondItem="Upi-pd-9ph" secondAttribute="trailing" id="hVx-Vm-ajx"/>
<constraint firstItem="Zcd-QO-oCP" firstAttribute="trailing" secondItem="Upi-pd-9ph" secondAttribute="trailing" id="lXp-jg-rre"/>
<constraint firstItem="Upi-pd-9ph" firstAttribute="trailing" secondItem="S9Q-rO-GEN" secondAttribute="trailing" id="nca-MU-PVK"/>
<constraint firstItem="NsV-eR-Br8" firstAttribute="top" secondItem="nCs-ch-41A" secondAttribute="bottom" constant="30" id="ny8-6L-Lpd"/>
<constraint firstItem="NsV-eR-Br8" firstAttribute="top" secondItem="nCs-ch-41A" secondAttribute="bottom" constant="65" id="ny8-6L-Lpd"/>
<constraint firstItem="NsV-eR-Br8" firstAttribute="trailing" secondItem="Zcd-QO-oCP" secondAttribute="trailing" id="p5n-hV-tK1"/>
<constraint firstItem="W6o-Yn-D7Z" firstAttribute="centerY" secondItem="n3y-BG-AGw" secondAttribute="centerY" id="shV-9R-cgP"/>
<constraint firstItem="lM2-53-pVD" firstAttribute="leading" secondItem="Zcd-QO-oCP" secondAttribute="leading" id="t0P-WV-xcF"/>
<constraint firstItem="S9Q-rO-GEN" firstAttribute="leading" secondItem="Bc4-Fn-Mhk" secondAttribute="leading" constant="27" id="y1s-o5-hla"/>
<constraint firstItem="iNz-jU-IJX" firstAttribute="leading" secondItem="S9Q-rO-GEN" secondAttribute="leading" id="yd9-F4-Bbo"/>
</constraints>
Expand Down Expand Up @@ -1878,26 +1891,26 @@
</userDefinedRuntimeAttributes>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Current Device" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="owA-aL-tUp">
<rect key="frame" x="252" y="23" width="100" height="20"/>
<rect key="frame" x="257" y="23" width="95" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="7aT-Fc-td6"/>
<constraint firstAttribute="width" constant="95" id="7aT-Fc-td6"/>
<constraint firstAttribute="height" constant="20" id="cfn-aM-jge"/>
</constraints>
<fontDescription key="fontDescription" name="NunitoSans-Regular" family="Nunito Sans" pointSize="14"/>
<color key="textColor" red="0.37254901960784315" green="0.72549019607843135" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="amW-Di-fUH">
<rect key="frame" x="61" y="13" width="186" height="40"/>
<rect key="frame" x="61" y="13" width="196" height="40"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Samsung Galaxy S8" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="K3s-zY-auf">
<rect key="frame" x="0.0" y="0.0" width="186" height="22"/>
<rect key="frame" x="0.0" y="0.0" width="196" height="22"/>
<fontDescription key="fontDescription" name="NunitoSans-Regular" family="Nunito Sans" pointSize="16"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Guayaquil - 12 hours ago" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0bv-pm-gsw">
<rect key="frame" x="0.0" y="22" width="186" height="18"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Guayaquil - 12 hours ago" textAlignment="natural" lineBreakMode="characterWrap" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0bv-pm-gsw">
<rect key="frame" x="0.0" y="22" width="196" height="18"/>
<fontDescription key="fontDescription" name="NunitoSans-Regular" family="Nunito Sans" pointSize="13"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
Expand All @@ -1917,7 +1930,7 @@
</button>
</subviews>
<constraints>
<constraint firstItem="owA-aL-tUp" firstAttribute="leading" secondItem="amW-Di-fUH" secondAttribute="trailing" constant="5" id="8hW-Je-NRb"/>
<constraint firstItem="owA-aL-tUp" firstAttribute="leading" secondItem="amW-Di-fUH" secondAttribute="trailing" id="8hW-Je-NRb"/>
<constraint firstItem="amW-Di-fUH" firstAttribute="centerY" secondItem="9C0-OI-bsM" secondAttribute="centerY" id="F5c-bO-nVr"/>
<constraint firstItem="AGu-bu-kQR" firstAttribute="trailing" secondItem="owA-aL-tUp" secondAttribute="trailing" id="Lza-yA-9XS"/>
<constraint firstItem="AGu-bu-kQR" firstAttribute="centerY" secondItem="owA-aL-tUp" secondAttribute="centerY" id="UZu-zA-hrs"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ class ConnectUploadViewController: UIViewController{
self.presentProcessInterrupted()
return
}
CriptextFileManager.deleteFile(url: myUrl)
CriptextFileManager.deleteFile(path: compressedPath)
self.databasePath = outputPath
self.state = .waiting
self.handleState()
Expand Down Expand Up @@ -143,6 +145,7 @@ class ConnectUploadViewController: UIViewController{
self.presentProcessInterrupted()
return
}
CriptextFileManager.deleteFile(path: path)
self.state = .sendData
self.handleState()
}
Expand Down
18 changes: 8 additions & 10 deletions iOS-Email-Client/Controllers/CustomTabsController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class CustomTabsController: TabsController {
}

func loadData(){
let myDevice = Device.createActiveDevice(deviceId: myAccount.deviceId)
APIManager.getSettings(token: myAccount.jwt) { (responseData) in
if case .Unauthorized = responseData {
self.logout()
Expand All @@ -39,20 +40,17 @@ class CustomTabsController: TabsController {
}
guard case let .SuccessDictionary(settings) = responseData,
let devices = settings["devices"] as? [[String: Any]],
let recoveryData = settings["recoveryEmail"] as? [String: Any] else {
let general = settings["general"] as? [String: Any] else {
return
}
for device in devices {
let newDevice = Device.fromDictionary(data: device)
guard !self.devicesData.devices.contains(where: {$0.id == newDevice.id && $0.active}) else {
continue
}
self.devicesData.devices.append(newDevice)
}
let email = recoveryData["address"] as! String
let status = recoveryData["status"] as! Int
let myDevices = devices.map({Device.fromDictionary(data: $0)}).filter({$0.id != myDevice.id}).sorted(by: {$0.safeDate > $1.safeDate})
self.devicesData.devices.append(contentsOf: myDevices)
let email = general["recoveryEmail"] as! String
let status = general["recoveryEmailConfirmed"] as! Int
let isTwoFactor = general["twoFactorAuth"] as! Int
self.generalData.recoveryEmail = email
self.generalData.recoveryEmailStatus = email.isEmpty ? .none : status == self.STATUS_NOT_CONFIRMED ? .pending : .verified
self.generalData.isTwoFactor = isTwoFactor == 1 ? true : false
self.reloadChildViews()
}
}
Expand Down
13 changes: 6 additions & 7 deletions iOS-Email-Client/Controllers/EmailDetailViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,6 @@ class EmailDetailViewController: UIViewController {
self.coachMarksController.overlay.allowTap = true
self.coachMarksController.overlay.color = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.85)
self.coachMarksController.dataSource = self

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
guard let lastIndex = self.emailData.emails.index(where: {$0.isExpanded}) else {
return
}
self.emailsTableView.scrollToRow(at: IndexPath(row: lastIndex, section: 0), at: .bottom, animated: false)
}
}

override func viewWillDisappear(_ animated: Bool) {
Expand Down Expand Up @@ -645,13 +638,19 @@ extension EmailDetailViewController: DetailMoreOptionsViewDelegate {
self.presentPasswordPopover(myAccount: self.myAccount)
return
}
if case .Conflicts = responseData {
self.showAlert("Unsend Failed", message: "Failed to unsend the email. Time (1h) for unsending has already expired.", style: .alert)
self.emailsTableView.reloadData()
return
}
guard case .Success = responseData else {
self.showAlert("Unsend Failed", message: "Unable to unsend email. Please try again later", style: .alert)
self.emailsTableView.reloadData()
return
}
DBManager.unsendEmail(email)
email.isLoaded = false
cell.isLoaded = false
cell.setContent(email, myEmail: self.emailData.accountEmail)
self.emailsTableView.reloadData()
}
Expand Down
10 changes: 9 additions & 1 deletion iOS-Email-Client/Controllers/GenericAlertUIPopover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ class GenericAlertUIPopover: BaseUIPopover {

var myTitle: String?
var myMessage: String?
var myAttributedMessage: NSAttributedString?
var myButton: String = "Ok"
var onOkPress: (() -> (Void))?
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var messageLabel: UILabel!
@IBOutlet weak var okButton: UIButton!


init(){
Expand All @@ -28,7 +31,12 @@ class GenericAlertUIPopover: BaseUIPopover {
override func viewDidLoad() {
super.viewDidLoad()
titleLabel.text = myTitle
messageLabel.text = myMessage
okButton.setTitle(myButton, for: .normal)
if let attributedMessage = myAttributedMessage {
messageLabel.attributedText = attributedMessage
} else {
messageLabel.text = myMessage
}
}

@IBAction func okPress(_ sender: Any) {
Expand Down
3 changes: 2 additions & 1 deletion iOS-Email-Client/Controllers/InboxViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ extension InboxViewController: WebSocketManagerDelegate {
}
settings.generalData.recoveryEmail = address
settings.generalData.recoveryEmailStatus = .pending
settings.generalData.isTwoFactor = false
settings.reloadChildViews()
case .RecoveryVerified:
guard let nav = self.presentedViewController as? UINavigationController,
Expand Down Expand Up @@ -368,7 +369,7 @@ extension InboxViewController {
menuViewController.reloadView()
}

if result.emails.contains(where: {!$0.isInvalidated && $0.status != .unsent}) {
if result.emails.contains(where: {!$0.isInvalidated && $0.status != .unsent && !$0.isSent}) {
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class ConnectDeviceViewController: UIViewController{
self.presentProcessInterrupted()
return
}
CriptextFileManager.deleteFile(path: path)
CriptextFileManager.deleteFile(path: decryptedPath)
state = .processDB(myAccount, decompressedPath, data)
self.handleState()
}
Expand Down Expand Up @@ -161,6 +163,7 @@ class ConnectDeviceViewController: UIViewController{
}
}
DBManager.insertBatchRows(rows: dbRows, maps: &maps)
CriptextFileManager.deleteFile(path: path)
DispatchQueue.main.async {
self.connectUIView.progressChange(value: self.PROGRESS_COMPLETE, message: "Decrypting Mailbox") {
self.connectUIView.messageLabel.text = "Mailbox restored successfully!"
Expand Down
Loading

0 comments on commit e58ecaf

Please sign in to comment.