mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-21 17:12:45 +02:00
Complete security: Add recover secrets action.
This commit is contained in:
+4
@@ -72,4 +72,8 @@ extension KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyWai
|
||||
func keyVerificationSelfVerifyWaitViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType) {
|
||||
self.delegate?.keyVerificationSelfVerifyWaitCoordinatorDidCancel(self)
|
||||
}
|
||||
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ coordinator: KeyVerificationSelfVerifyWaitViewModelType, wantsToRecoverSecretsWith secretsRecoveryMode: SecretsRecoveryMode) {
|
||||
self.delegate?.keyVerificationSelfVerifyWaitCoordinator(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -22,6 +22,7 @@ protocol KeyVerificationSelfVerifyWaitCoordinatorDelegate: class {
|
||||
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest)
|
||||
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction)
|
||||
func keyVerificationSelfVerifyWaitCoordinatorDidCancel(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType)
|
||||
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, wantsToRecoverSecretsWith secretsRecoveryMode: SecretsRecoveryMode)
|
||||
}
|
||||
|
||||
/// `KeyVerificationSelfVerifyWaitCoordinatorType` is a protocol describing a Coordinator that handle key backup setup passphrase navigation flow.
|
||||
|
||||
+1
@@ -22,4 +22,5 @@ import Foundation
|
||||
enum KeyVerificationSelfVerifyWaitViewAction {
|
||||
case loadData
|
||||
case cancel
|
||||
case recoverSecrets
|
||||
}
|
||||
|
||||
+148
-74
@@ -18,95 +18,166 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IlB-Ch-LEo">
|
||||
<rect key="frame" x="0.0" y="201.5" width="375" height="284"/>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="asO-rj-82y">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d5Y-pj-XsI">
|
||||
<rect key="frame" x="20" y="10" width="335" height="84"/>
|
||||
<string key="text">Verify this session from one of your others sessions, granting it access to encrypted messages.
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tIM-sl-gwE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="412.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IlB-Ch-LEo">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="412.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d5Y-pj-XsI">
|
||||
<rect key="frame" x="20" y="20" width="335" height="84"/>
|
||||
<string key="text">Verify this session from one of your others sessions, granting it access to encrypted messages.
|
||||
|
||||
Use the latest Riot on your other devices:</string>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="ANK-XS-dY7">
|
||||
<rect key="frame" x="27.5" y="134" width="320" height="95.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="3at-ql-vhb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="160" height="95.5"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="monitor" translatesAutoresizingMaskIntoConstraints="NO" id="nrB-Kj-4zE">
|
||||
<rect key="frame" x="56" y="0.0" width="48" height="48"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="48" id="F2W-zC-UJo"/>
|
||||
<constraint firstAttribute="width" secondItem="nrB-Kj-4zE" secondAttribute="height" multiplier="1:1" id="TOT-bj-1W4"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iBP-FF-AYM">
|
||||
<rect key="frame" x="38.5" y="62" width="83" height="33.5"/>
|
||||
<string key="text">Riot Web
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="ANK-XS-dY7">
|
||||
<rect key="frame" x="27.5" y="144" width="320" height="95.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="3at-ql-vhb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="160" height="95.5"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="monitor" translatesAutoresizingMaskIntoConstraints="NO" id="nrB-Kj-4zE">
|
||||
<rect key="frame" x="56" y="0.0" width="48" height="48"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="48" id="F2W-zC-UJo"/>
|
||||
<constraint firstAttribute="width" secondItem="nrB-Kj-4zE" secondAttribute="height" multiplier="1:1" id="TOT-bj-1W4"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iBP-FF-AYM">
|
||||
<rect key="frame" x="38.5" y="62" width="83" height="33.5"/>
|
||||
<string key="text">Riot Web
|
||||
Riot Desktop</string>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="coY-7W-lY7">
|
||||
<rect key="frame" x="160" y="0.0" width="160" height="95.5"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="smartphone" translatesAutoresizingMaskIntoConstraints="NO" id="P0P-X4-uSQ">
|
||||
<rect key="frame" x="56" y="0.0" width="48" height="48"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="48" id="4NO-k7-6iK"/>
|
||||
<constraint firstAttribute="width" secondItem="P0P-X4-uSQ" secondAttribute="height" multiplier="1:1" id="AZP-GN-y8E"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gLH-sE-KCq">
|
||||
<rect key="frame" x="22.5" y="62" width="115" height="33.5"/>
|
||||
<string key="text">Riot iOS
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="coY-7W-lY7">
|
||||
<rect key="frame" x="160" y="0.0" width="160" height="95.5"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="smartphone" translatesAutoresizingMaskIntoConstraints="NO" id="P0P-X4-uSQ">
|
||||
<rect key="frame" x="56" y="0.0" width="48" height="48"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="48" id="4NO-k7-6iK"/>
|
||||
<constraint firstAttribute="width" secondItem="P0P-X4-uSQ" secondAttribute="height" multiplier="1:1" id="AZP-GN-y8E"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gLH-sE-KCq">
|
||||
<rect key="frame" x="22.5" y="62" width="115" height="33.5"/>
|
||||
<string key="text">Riot iOS
|
||||
Riot X for Android</string>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="320" id="TyM-5Y-YSw"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="or another cross-signing capable Matrix client" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rFM-AQ-wAB">
|
||||
<rect key="frame" x="20" y="259.5" width="335" height="14.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="8oJ-o6-DLK">
|
||||
<rect key="frame" x="20" y="294" width="335" height="118.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nf8-Ye-b9r">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="118.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OEt-k0-vgM" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="10" width="335" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="7ws-Nc-I7y"/>
|
||||
</constraints>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="Use a recovery passphrase or key">
|
||||
<color key="titleColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="recoverSecretsButtonAction:" destination="79A-qb-tmk" eventType="touchUpInside" id="FY5-tR-dyT"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="If you can't accessing an existing session" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Ou-cM-K9C">
|
||||
<rect key="frame" x="20" y="64" width="295" height="24.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
|
||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="4Ou-cM-K9C" secondAttribute="trailing" constant="20" id="6a1-gA-Cev"/>
|
||||
<constraint firstAttribute="bottom" secondItem="4Ou-cM-K9C" secondAttribute="bottom" constant="30" id="X1c-Yc-qLh"/>
|
||||
<constraint firstItem="4Ou-cM-K9C" firstAttribute="top" secondItem="OEt-k0-vgM" secondAttribute="bottom" constant="10" id="Y5b-Bf-IYu"/>
|
||||
<constraint firstItem="OEt-k0-vgM" firstAttribute="top" secondItem="nf8-Ye-b9r" secondAttribute="top" constant="10" id="fvJ-vZ-MMa"/>
|
||||
<constraint firstItem="OEt-k0-vgM" firstAttribute="leading" secondItem="nf8-Ye-b9r" secondAttribute="leading" id="loc-cf-E6p"/>
|
||||
<constraint firstItem="4Ou-cM-K9C" firstAttribute="leading" secondItem="nf8-Ye-b9r" secondAttribute="leading" constant="20" id="o3E-Q9-7h1"/>
|
||||
<constraint firstAttribute="trailing" secondItem="OEt-k0-vgM" secondAttribute="trailing" id="yQK-YS-7Yr"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="nf8-Ye-b9r" firstAttribute="width" secondItem="8oJ-o6-DLK" secondAttribute="width" id="ZNi-0G-uDR"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="d5Y-pj-XsI" secondAttribute="trailing" constant="20" id="3Mi-wg-su3"/>
|
||||
<constraint firstAttribute="height" priority="250" id="72E-My-WHK"/>
|
||||
<constraint firstItem="ANK-XS-dY7" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="IlB-Ch-LEo" secondAttribute="leading" id="9BR-a1-3By"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8oJ-o6-DLK" secondAttribute="bottom" id="CB2-Nd-n2g"/>
|
||||
<constraint firstItem="rFM-AQ-wAB" firstAttribute="top" secondItem="ANK-XS-dY7" secondAttribute="bottom" constant="20" id="Goe-Tt-Jbm"/>
|
||||
<constraint firstItem="d5Y-pj-XsI" firstAttribute="leading" secondItem="IlB-Ch-LEo" secondAttribute="leading" constant="20" id="Okc-DX-xdE"/>
|
||||
<constraint firstItem="d5Y-pj-XsI" firstAttribute="top" secondItem="IlB-Ch-LEo" secondAttribute="top" constant="20" id="Pkt-ox-zZs"/>
|
||||
<constraint firstItem="rFM-AQ-wAB" firstAttribute="leading" secondItem="IlB-Ch-LEo" secondAttribute="leading" constant="20" id="PtP-G3-lC6"/>
|
||||
<constraint firstAttribute="trailing" secondItem="rFM-AQ-wAB" secondAttribute="trailing" constant="20" id="Q78-Oe-Lh2"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ANK-XS-dY7" secondAttribute="trailing" id="RQI-kF-Z1h"/>
|
||||
<constraint firstItem="8oJ-o6-DLK" firstAttribute="leading" secondItem="IlB-Ch-LEo" secondAttribute="leading" constant="20" id="RtP-rm-bjH"/>
|
||||
<constraint firstItem="8oJ-o6-DLK" firstAttribute="top" secondItem="rFM-AQ-wAB" secondAttribute="bottom" constant="20" id="dvv-3U-uH4"/>
|
||||
<constraint firstItem="ANK-XS-dY7" firstAttribute="top" secondItem="d5Y-pj-XsI" secondAttribute="bottom" constant="40" id="gnp-AK-DYa"/>
|
||||
<constraint firstItem="ANK-XS-dY7" firstAttribute="centerX" secondItem="IlB-Ch-LEo" secondAttribute="centerX" id="nEo-IT-GtP"/>
|
||||
<constraint firstAttribute="trailing" secondItem="8oJ-o6-DLK" secondAttribute="trailing" constant="20" id="vev-7p-7ua"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="320" id="TyM-5Y-YSw"/>
|
||||
<constraint firstItem="IlB-Ch-LEo" firstAttribute="centerX" secondItem="tIM-sl-gwE" secondAttribute="centerX" id="428-8q-pvc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="IlB-Ch-LEo" secondAttribute="bottom" id="8t4-aW-4OV"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="IlB-Ch-LEo" secondAttribute="trailing" id="EBp-6W-LtY"/>
|
||||
<constraint firstItem="IlB-Ch-LEo" firstAttribute="top" secondItem="tIM-sl-gwE" secondAttribute="top" id="HqF-24-jLe"/>
|
||||
<constraint firstItem="IlB-Ch-LEo" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="tIM-sl-gwE" secondAttribute="leading" id="d4W-6f-aGG"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="or another cross-signing capable Matrix client" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rFM-AQ-wAB">
|
||||
<rect key="frame" x="20" y="249.5" width="335" height="14.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="d5Y-pj-XsI" secondAttribute="trailing" constant="20" id="3Mi-wg-su3"/>
|
||||
<constraint firstAttribute="bottom" secondItem="rFM-AQ-wAB" secondAttribute="bottom" constant="20" id="4Gy-0v-H5m"/>
|
||||
<constraint firstAttribute="height" priority="250" id="72E-My-WHK"/>
|
||||
<constraint firstItem="ANK-XS-dY7" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="IlB-Ch-LEo" secondAttribute="leading" id="9BR-a1-3By"/>
|
||||
<constraint firstItem="rFM-AQ-wAB" firstAttribute="top" secondItem="ANK-XS-dY7" secondAttribute="bottom" constant="20" id="Goe-Tt-Jbm"/>
|
||||
<constraint firstItem="d5Y-pj-XsI" firstAttribute="leading" secondItem="IlB-Ch-LEo" secondAttribute="leading" constant="20" id="Okc-DX-xdE"/>
|
||||
<constraint firstItem="d5Y-pj-XsI" firstAttribute="top" secondItem="IlB-Ch-LEo" secondAttribute="top" constant="10" id="Pkt-ox-zZs"/>
|
||||
<constraint firstItem="rFM-AQ-wAB" firstAttribute="leading" secondItem="IlB-Ch-LEo" secondAttribute="leading" constant="20" id="PtP-G3-lC6"/>
|
||||
<constraint firstAttribute="trailing" secondItem="rFM-AQ-wAB" secondAttribute="trailing" constant="20" id="Q78-Oe-Lh2"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ANK-XS-dY7" secondAttribute="trailing" id="RQI-kF-Z1h"/>
|
||||
<constraint firstItem="ANK-XS-dY7" firstAttribute="top" secondItem="d5Y-pj-XsI" secondAttribute="bottom" constant="40" id="gnp-AK-DYa"/>
|
||||
<constraint firstItem="ANK-XS-dY7" firstAttribute="centerX" secondItem="IlB-Ch-LEo" secondAttribute="centerX" id="nEo-IT-GtP"/>
|
||||
<constraint firstAttribute="bottom" secondItem="tIM-sl-gwE" secondAttribute="bottom" id="I5t-jH-6vU"/>
|
||||
<constraint firstItem="tIM-sl-gwE" firstAttribute="width" secondItem="asO-rj-82y" secondAttribute="width" id="Ngd-NZ-QSP"/>
|
||||
<constraint firstItem="tIM-sl-gwE" firstAttribute="leading" secondItem="asO-rj-82y" secondAttribute="leading" id="clc-OI-kPa"/>
|
||||
<constraint firstItem="tIM-sl-gwE" firstAttribute="top" secondItem="asO-rj-82y" secondAttribute="top" id="hZy-Kz-O3K"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tIM-sl-gwE" secondAttribute="trailing" id="k4M-hm-HD7"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.94509803920000002" green="0.96078431369999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="IlB-Ch-LEo" firstAttribute="centerY" secondItem="GnW-bb-rsL" secondAttribute="centerY" id="Hh1-tV-pXA"/>
|
||||
<constraint firstItem="IlB-Ch-LEo" firstAttribute="trailing" secondItem="GnW-bb-rsL" secondAttribute="trailing" id="Kbx-ln-UzT"/>
|
||||
<constraint firstItem="IlB-Ch-LEo" firstAttribute="leading" secondItem="GnW-bb-rsL" secondAttribute="leading" id="f6d-Hi-qnR"/>
|
||||
<constraint firstItem="asO-rj-82y" firstAttribute="trailing" secondItem="GnW-bb-rsL" secondAttribute="trailing" id="Isw-tg-7go"/>
|
||||
<constraint firstItem="GnW-bb-rsL" firstAttribute="leading" secondItem="asO-rj-82y" secondAttribute="leading" id="YWL-Xu-ApZ"/>
|
||||
<constraint firstItem="GnW-bb-rsL" firstAttribute="top" secondItem="asO-rj-82y" secondAttribute="top" id="b3e-2d-oiV"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="asO-rj-82y" secondAttribute="bottom" id="wMk-Oq-DwP"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="GnW-bb-rsL"/>
|
||||
</view>
|
||||
@@ -117,6 +188,9 @@ Riot X for Android</string>
|
||||
<outlet property="informationLabel" destination="d5Y-pj-XsI" id="TMb-bc-58a"/>
|
||||
<outlet property="mobileClientImageView" destination="P0P-X4-uSQ" id="WtT-ix-yq8"/>
|
||||
<outlet property="mobileClientLabel" destination="gLH-sE-KCq" id="jQ0-7U-mr8"/>
|
||||
<outlet property="recoverSecretsAdditionalInformationLabel" destination="4Ou-cM-K9C" id="80N-lF-x2L"/>
|
||||
<outlet property="recoverSecretsButton" destination="OEt-k0-vgM" id="RHU-ps-4m7"/>
|
||||
<outlet property="recoverSecretsContainerView" destination="nf8-Ye-b9r" id="4az-pe-0Uc"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="OMs-Ee-CjK" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
@@ -125,7 +199,7 @@ Riot X for Android</string>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="monitor" width="24" height="24"/>
|
||||
<image name="smartphone" width="24" height="24"/>
|
||||
<image name="monitor" width="48" height="48"/>
|
||||
<image name="smartphone" width="48" height="48"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
+39
-5
@@ -40,6 +40,11 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
||||
|
||||
@IBOutlet private weak var additionalInformationLabel: UILabel!
|
||||
|
||||
|
||||
@IBOutlet private weak var recoverSecretsContainerView: UIView!
|
||||
@IBOutlet private weak var recoverSecretsButton: RoundedButton!
|
||||
@IBOutlet private weak var recoverSecretsAdditionalInformationLabel: UILabel!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var viewModel: KeyVerificationSelfVerifyWaitViewModelType!
|
||||
@@ -112,6 +117,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
||||
self?.cancelButtonAction()
|
||||
}
|
||||
|
||||
self.vc_removeBackTitle()
|
||||
|
||||
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
||||
self.cancelBarButtonItem = cancelBarButtonItem
|
||||
|
||||
@@ -126,14 +133,16 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
||||
self.mobileClientImageView.image = Asset.Images.smartphone.image.withRenderingMode(.alwaysTemplate)
|
||||
|
||||
self.additionalInformationLabel.text = VectorL10n.deviceVerificationSelfVerifyWaitAdditionalInformation
|
||||
|
||||
self.recoverSecretsAdditionalInformationLabel.text = VectorL10n.deviceVerificationSelfVerifyWaitRecoverSecretsAdditionalInformation
|
||||
}
|
||||
|
||||
private func render(viewState: KeyVerificationSelfVerifyWaitViewState) {
|
||||
switch viewState {
|
||||
case .loading:
|
||||
self.renderLoading()
|
||||
case .loaded(let isNewSignIn):
|
||||
self.renderLoaded(isNewSignIn: isNewSignIn)
|
||||
case .loaded(let viewData):
|
||||
self.renderLoaded(viewData: viewData)
|
||||
case .cancelled(let reason):
|
||||
self.renderCancelled(reason: reason)
|
||||
case .cancelledByMe(let reason):
|
||||
@@ -147,11 +156,32 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
||||
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
|
||||
}
|
||||
|
||||
private func renderLoaded(isNewSignIn: Bool) {
|
||||
private func renderLoaded(viewData: KeyVerificationSelfVerifyWaitViewData) {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
|
||||
self.title = isNewSignIn ? VectorL10n.deviceVerificationSelfVerifyWaitNewSignInTitle : VectorL10n.deviceVerificationSelfVerifyWaitTitle
|
||||
self.cancelBarButtonItem?.title = isNewSignIn ? VectorL10n.skip : VectorL10n.cancel
|
||||
self.title = viewData.isNewSignIn ? VectorL10n.deviceVerificationSelfVerifyWaitNewSignInTitle : VectorL10n.deviceVerificationSelfVerifyWaitTitle
|
||||
self.cancelBarButtonItem?.title = viewData.isNewSignIn ? VectorL10n.skip : VectorL10n.cancel
|
||||
|
||||
let hideRecoverSecrets: Bool
|
||||
let recoverSecretsButtonTitle: String?
|
||||
|
||||
switch viewData.secretsRecoveryAvailability {
|
||||
case .notAvailable:
|
||||
hideRecoverSecrets = true
|
||||
recoverSecretsButtonTitle = nil
|
||||
case .available(let secretsRecoveryMode):
|
||||
hideRecoverSecrets = false
|
||||
|
||||
switch secretsRecoveryMode {
|
||||
case .passphraseOrKey:
|
||||
recoverSecretsButtonTitle = VectorL10n.deviceVerificationSelfVerifyWaitRecoverSecretsWithPassphrase
|
||||
case .onlyKey:
|
||||
recoverSecretsButtonTitle = VectorL10n.deviceVerificationSelfVerifyWaitRecoverSecretsWithoutPassphrase
|
||||
}
|
||||
}
|
||||
|
||||
self.recoverSecretsContainerView.isHidden = hideRecoverSecrets
|
||||
self.recoverSecretsButton.setTitle(recoverSecretsButtonTitle, for: .normal)
|
||||
}
|
||||
|
||||
private func renderCancelled(reason: MXTransactionCancelCode) {
|
||||
@@ -184,6 +214,10 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
||||
private func cancelButtonAction() {
|
||||
self.viewModel.process(viewAction: .cancel)
|
||||
}
|
||||
|
||||
@IBAction private func recoverSecretsButtonAction(_ sender: Any) {
|
||||
self.viewModel.process(viewAction: .recoverSecrets)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+21
-1
@@ -28,6 +28,9 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
||||
private let keyVerificationService: KeyVerificationService
|
||||
private let verificationManager: MXKeyVerificationManager
|
||||
private let isNewSignIn: Bool
|
||||
private lazy var secretsRecoveryAvailability: SecretsRecoveryAvailability = {
|
||||
return self.secretsRecoveryAvailability(from: self.session.crypto.recoveryService)
|
||||
}()
|
||||
|
||||
private var keyVerificationRequest: MXKeyVerificationRequest?
|
||||
|
||||
@@ -57,6 +60,12 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
||||
self.loadData()
|
||||
case .cancel:
|
||||
self.cancel()
|
||||
case .recoverSecrets:
|
||||
switch self.secretsRecoveryAvailability {
|
||||
case .notAvailable:
|
||||
fatalError("Should not happen: When recovery is not available button is hidden")
|
||||
case .available(let secretsRecoveryMode): self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,11 +89,22 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
||||
})
|
||||
}
|
||||
|
||||
// let recoverySecretsStatus = self.recoveryStatus(from: self.session.crypto.recoveryService)
|
||||
let viewData = KeyVerificationSelfVerifyWaitViewData(isNewSignIn: self.isNewSignIn, secretsRecoveryAvailability: self.secretsRecoveryAvailability)
|
||||
|
||||
self.registerKeyVerificationManagerNewRequestNotification(for: self.verificationManager)
|
||||
self.update(viewState: .loaded(self.isNewSignIn))
|
||||
self.update(viewState: .loaded(viewData))
|
||||
self.registerTransactionDidStateChangeNotification()
|
||||
}
|
||||
|
||||
private func secretsRecoveryAvailability(from recoveryService: MXRecoveryService) -> SecretsRecoveryAvailability {
|
||||
guard recoveryService.hasRecovery() else {
|
||||
return .notAvailable
|
||||
}
|
||||
let secretsRecoveryMode: SecretsRecoveryMode = recoveryService.usePassphrase() ? .passphraseOrKey : .onlyKey
|
||||
return .available(secretsRecoveryMode)
|
||||
}
|
||||
|
||||
private func cancel() {
|
||||
self.unregisterKeyVerificationManagerNewRequestNotification()
|
||||
self.cancelKeyVerificationRequest()
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ protocol KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate: class {
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest)
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction)
|
||||
func keyVerificationSelfVerifyWaitViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType)
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, wantsToRecoverSecretsWith secretsRecoveryMode: SecretsRecoveryMode)
|
||||
}
|
||||
|
||||
/// Protocol describing the view model used by `KeyVerificationSelfVerifyWaitViewController`
|
||||
|
||||
+11
-1
@@ -18,10 +18,20 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SecretsRecoveryAvailability {
|
||||
case notAvailable
|
||||
case available(_ mode: SecretsRecoveryMode)
|
||||
}
|
||||
|
||||
struct KeyVerificationSelfVerifyWaitViewData {
|
||||
let isNewSignIn: Bool
|
||||
let secretsRecoveryAvailability: SecretsRecoveryAvailability
|
||||
}
|
||||
|
||||
/// KeyVerificationSelfVerifyWaitViewController view state
|
||||
enum KeyVerificationSelfVerifyWaitViewState {
|
||||
case loading
|
||||
case loaded(_ isNewSignIn: Bool)
|
||||
case loaded(_ viewData: KeyVerificationSelfVerifyWaitViewData)
|
||||
case cancelled(MXTransactionCancelCode)
|
||||
case cancelledByMe(MXTransactionCancelCode)
|
||||
case error(Error)
|
||||
|
||||
Reference in New Issue
Block a user