Registration support.

Support the 2 following flows: m.login.email.identity and m.login.recaptcha.
This commit is contained in:
giomfo 2016-04-01 16:31:13 +02:00
parent 236d202142
commit 87811e8350
7 changed files with 628 additions and 179 deletions

View file

@ -16,12 +16,14 @@
// Titles
"title_recents" = "Messages";
"warning" = "Warning";
// Actions
"view" = "View";
"mark_all_as_read_prompt" = "Mark all as read?";
"next" = "Next";
"back" = "Back";
"continue" = "Continue";
"create" = "Create";
"leave" = "Leave";
"remove" = "Remove";
@ -40,10 +42,21 @@
"auth_user_id_placeholder" = "Email or user name";
"auth_password_placeholder" = "Password";
"auth_user_name_placeholder" = "Your name";
"auth_optional_email_placeholder" = "Email address (optional)";
"auth_email_placeholder" = "Email address";
"auth_repeat_password_placeholder" = "Repeat password";
"auth_invalid_login_param" = "Incorrect username and/or password";
"auth_invalid_user_name" = "User names may only contain letters, numbers, dots, hyphens and underscores";
"auth_invalid_password" = "Password too short (min 6)";
"auth_missing_password" = "Missing password";
"auth_missing_optional_email" = "If you don't specify an email address, you won't be able to reset your password. Are you sure?";
"auth_missing_email" = "Missing email address";
"auth_password_dont_match" = "Passwords don't match";
"auth_forgot_password" = "Forgot password?";
"auth_use_server_options" = "Use custom server options (advanced)";
"auth_email_validation_message" = "Please check your email to continue registration";
"auth_recaptcha_message" = "This Home Server would like to make sure you are not a robot";
"auth_username_in_use" = "Username in use";
// Chat creation
"room_creation_title" = "New Chat";

View file

@ -21,6 +21,8 @@
@property (weak, nonatomic) IBOutlet UINavigationItem *mainNavigationItem;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *rightBarButtonItem;
@property (weak, nonatomic) IBOutlet UIView *optionsContainer;
@property (weak, nonatomic) IBOutlet UIButton *forgotPasswordButton;
@property (weak, nonatomic) IBOutlet UIButton *serverOptionsTickButton;

View file

@ -63,6 +63,7 @@
self.submitButton.backgroundColor = kVectorColorGreen;
[self.submitButton setTitle:NSLocalizedStringFromTable(@"auth_login", @"Vector", nil) forState:UIControlStateNormal];
[self.submitButton setTitle:NSLocalizedStringFromTable(@"auth_login", @"Vector", nil) forState:UIControlStateHighlighted];
self.submitButton.enabled = YES;
[self.forgotPasswordButton setTitle:NSLocalizedStringFromTable(@"auth_forgot_password", @"Vector", nil) forState:UIControlStateNormal];
[self.forgotPasswordButton setTitle:NSLocalizedStringFromTable(@"auth_forgot_password", @"Vector", nil) forState:UIControlStateHighlighted];
@ -111,6 +112,14 @@
}
}
- (void)setUserInteractionEnabled:(BOOL)userInteractionEnabled
{
super.userInteractionEnabled = userInteractionEnabled;
// Show/Hide server options
_optionsContainer.hidden = !userInteractionEnabled;
}
- (IBAction)onButtonPressed:(id)sender
{
if (sender == self.serverOptionsTickButton)
@ -140,6 +149,40 @@
[self hideServerOptionsContainer:YES];
}
else if (sender == self.submitButton)
{
// Check whether the user should set the email
if (self.authInputsView.shouldPromptUserForEmailAddress)
{
[self dismissKeyboard];
if (alert)
{
[alert dismiss:NO];
}
__weak typeof(self) weakSelf = self;
alert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"warning", @"Vector", nil) message:NSLocalizedStringFromTable(@"auth_missing_optional_email", @"Vector", nil) style:MXKAlertStyleAlert];
[alert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"continue"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf->alert = nil;
[super onButtonPressed:sender];
}];
alert.cancelButtonIndex = [alert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf->alert = nil;
}];
[alert showInViewController:self];
}
else
{
[super onButtonPressed:sender];
}
}
else
{
[super onButtonPressed:sender];

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AuthenticationViewController">
@ -29,6 +29,7 @@
<outlet property="identityServerTextField" destination="PZC-Hd-Q6a" id="vKg-sd-dzJ"/>
<outlet property="mainNavigationItem" destination="rj9-wP-8QS" id="yNN-Dg-4Yw"/>
<outlet property="noFlowLabel" destination="54b-4O-ip9" id="f18-H1-cQm"/>
<outlet property="optionsContainer" destination="Gg0-TE-OGb" id="RWa-Pl-eaL"/>
<outlet property="retryButton" destination="wIH-Kd-r7q" id="42j-Ad-zVS"/>
<outlet property="rightBarButtonItem" destination="Kwt-KN-aVL" id="Y3F-wA-tf8"/>
<outlet property="serverOptionsContainer" destination="uOi-KN-l9I" id="DPa-Kr-caW"/>
@ -119,180 +120,193 @@
<constraint firstAttribute="centerX" secondItem="30E-gm-z6O" secondAttribute="centerX" id="sSN-PO-Q6t"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AJ2-lJ-NUq">
<rect key="frame" x="19" y="333" width="123" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="1mr-dZ-KtP"/>
</constraints>
<state key="normal" title="Forgot password?">
<color key="titleColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="UVJ-Re-xe2"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k3J-Eg-itz" userLabel="SubmitBtn">
<rect key="frame" x="469" y="333" width="120" height="30"/>
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="width" constant="120" id="H9x-Zc-0sE"/>
<constraint firstAttribute="height" constant="30" id="rR8-KH-2z5"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
<state key="normal" title="Log In">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="Ocd-Ag-6hf"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" hasAttributedTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6yx-o1-vbD">
<rect key="frame" x="19" y="373" width="562" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="buF-NU-DPO"/>
</constraints>
<inset key="titleEdgeInsets" minX="8" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" image="selection_untick.png">
<attributedString key="attributedTitle">
<fragment content="Use custom server options">
<attributes>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="oEd-H1-EDj"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uOi-KN-l9I" userLabel="ServerOptionsContainerView">
<rect key="frame" x="0.0" y="406" width="600" height="140"/>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Gg0-TE-OGb">
<rect key="frame" x="0.0" y="300" width="600" height="300"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1YY-gb-LG4">
<rect key="frame" x="0.0" y="0.0" width="600" height="70"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Home Server:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kHf-s1-cZa">
<rect key="frame" x="18" y="8" width="564" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="SgI-dz-C8b"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="URL (e.g. https://matrix.org)" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="G8l-AP-iRs">
<rect key="frame" x="18" y="36" width="564" height="21"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="RT2-FT-tLZ"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
<connections>
<outlet property="delegate" destination="-1" id="UVr-c4-V8L"/>
</connections>
</textField>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZZP-eI-bXP">
<rect key="frame" x="10" y="69" width="580" height="1"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="XdZ-tB-v6d"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AJ2-lJ-NUq">
<rect key="frame" x="19" y="33" width="123" height="30"/>
<constraints>
<constraint firstItem="G8l-AP-iRs" firstAttribute="leading" secondItem="1YY-gb-LG4" secondAttribute="leading" constant="18" id="0tL-7X-7HQ"/>
<constraint firstAttribute="bottom" secondItem="ZZP-eI-bXP" secondAttribute="bottom" id="1JS-eI-7hU"/>
<constraint firstAttribute="trailing" secondItem="ZZP-eI-bXP" secondAttribute="trailing" constant="10" id="9q3-GY-TrI"/>
<constraint firstItem="kHf-s1-cZa" firstAttribute="leading" secondItem="1YY-gb-LG4" secondAttribute="leading" constant="18" id="Bww-He-GGJ"/>
<constraint firstItem="G8l-AP-iRs" firstAttribute="top" secondItem="kHf-s1-cZa" secondAttribute="bottom" constant="8" id="HUb-A5-Fnn"/>
<constraint firstAttribute="trailing" secondItem="kHf-s1-cZa" secondAttribute="trailing" constant="18" id="K4u-XW-UqK"/>
<constraint firstAttribute="trailing" secondItem="G8l-AP-iRs" secondAttribute="trailing" constant="18" id="O7t-Uf-wPo"/>
<constraint firstItem="kHf-s1-cZa" firstAttribute="top" secondItem="1YY-gb-LG4" secondAttribute="top" constant="8" id="l9i-gw-NaZ"/>
<constraint firstItem="ZZP-eI-bXP" firstAttribute="leading" secondItem="1YY-gb-LG4" secondAttribute="leading" constant="10" id="rbh-mU-NLC"/>
<constraint firstAttribute="height" constant="70" id="wa1-77-Lb4"/>
<constraint firstAttribute="height" constant="30" id="1mr-dZ-KtP"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kjJ-Tb-SIW">
<rect key="frame" x="0.0" y="70" width="600" height="70"/>
<state key="normal" title="Forgot password?">
<color key="titleColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="UVJ-Re-xe2"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k3J-Eg-itz" userLabel="SubmitBtn">
<rect key="frame" x="469" y="33" width="120" height="30"/>
<color key="backgroundColor" red="0.028153735480000001" green="0.82494870580000002" blue="0.051896891280000003" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="width" constant="120" id="H9x-Zc-0sE"/>
<constraint firstAttribute="height" constant="30" id="rR8-KH-2z5"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
<state key="normal" title="Log In">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="Ocd-Ag-6hf"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" hasAttributedTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6yx-o1-vbD">
<rect key="frame" x="19" y="73" width="562" height="30"/>
<constraints>
<constraint firstAttribute="height" constant="30" id="buF-NU-DPO"/>
</constraints>
<inset key="titleEdgeInsets" minX="8" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" image="selection_untick.png">
<attributedString key="attributedTitle">
<fragment content="Use custom server options">
<attributes>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
</state>
<connections>
<action selector="onButtonPressed:" destination="-1" eventType="touchUpInside" id="oEd-H1-EDj"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uOi-KN-l9I" userLabel="ServerOptionsContainerView">
<rect key="frame" x="0.0" y="106" width="600" height="140"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Identity Server:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5CT-Ht-Z3v">
<rect key="frame" x="18" y="8" width="564" height="20"/>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1YY-gb-LG4">
<rect key="frame" x="0.0" y="0.0" width="600" height="70"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Home Server:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kHf-s1-cZa">
<rect key="frame" x="18" y="8" width="564" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="SgI-dz-C8b"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="URL (e.g. https://matrix.org)" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="G8l-AP-iRs">
<rect key="frame" x="18" y="36" width="564" height="21"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="RT2-FT-tLZ"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
<connections>
<outlet property="delegate" destination="-1" id="UVr-c4-V8L"/>
</connections>
</textField>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZZP-eI-bXP">
<rect key="frame" x="10" y="69" width="580" height="1"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="XdZ-tB-v6d"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="aWu-GG-POi"/>
<constraint firstItem="G8l-AP-iRs" firstAttribute="leading" secondItem="1YY-gb-LG4" secondAttribute="leading" constant="18" id="0tL-7X-7HQ"/>
<constraint firstAttribute="bottom" secondItem="ZZP-eI-bXP" secondAttribute="bottom" id="1JS-eI-7hU"/>
<constraint firstAttribute="trailing" secondItem="ZZP-eI-bXP" secondAttribute="trailing" constant="10" id="9q3-GY-TrI"/>
<constraint firstItem="kHf-s1-cZa" firstAttribute="leading" secondItem="1YY-gb-LG4" secondAttribute="leading" constant="18" id="Bww-He-GGJ"/>
<constraint firstItem="G8l-AP-iRs" firstAttribute="top" secondItem="kHf-s1-cZa" secondAttribute="bottom" constant="8" id="HUb-A5-Fnn"/>
<constraint firstAttribute="trailing" secondItem="kHf-s1-cZa" secondAttribute="trailing" constant="18" id="K4u-XW-UqK"/>
<constraint firstAttribute="trailing" secondItem="G8l-AP-iRs" secondAttribute="trailing" constant="18" id="O7t-Uf-wPo"/>
<constraint firstItem="kHf-s1-cZa" firstAttribute="top" secondItem="1YY-gb-LG4" secondAttribute="top" constant="8" id="l9i-gw-NaZ"/>
<constraint firstItem="ZZP-eI-bXP" firstAttribute="leading" secondItem="1YY-gb-LG4" secondAttribute="leading" constant="10" id="rbh-mU-NLC"/>
<constraint firstAttribute="height" constant="70" id="wa1-77-Lb4"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="URL (e.g. https://matrix.org)" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="PZC-Hd-Q6a">
<rect key="frame" x="18" y="36" width="564" height="21"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kjJ-Tb-SIW">
<rect key="frame" x="0.0" y="70" width="600" height="70"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Identity Server:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5CT-Ht-Z3v">
<rect key="frame" x="18" y="8" width="564" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="aWu-GG-POi"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="URL (e.g. https://matrix.org)" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="PZC-Hd-Q6a">
<rect key="frame" x="18" y="36" width="564" height="21"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="XTt-dw-c6p"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
<connections>
<outlet property="delegate" destination="-1" id="nZF-by-6t6"/>
</connections>
</textField>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t08-ua-0mJ">
<rect key="frame" x="10" y="69" width="580" height="1"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="h6p-cH-vPq"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="21" id="XTt-dw-c6p"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done"/>
<connections>
<outlet property="delegate" destination="-1" id="nZF-by-6t6"/>
</connections>
</textField>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="t08-ua-0mJ">
<rect key="frame" x="10" y="69" width="580" height="1"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="h6p-cH-vPq"/>
<constraint firstItem="PZC-Hd-Q6a" firstAttribute="leading" secondItem="kjJ-Tb-SIW" secondAttribute="leading" constant="18" id="Khv-I4-mWb"/>
<constraint firstAttribute="trailing" secondItem="PZC-Hd-Q6a" secondAttribute="trailing" constant="18" id="VJ7-z3-LW3"/>
<constraint firstAttribute="bottom" secondItem="t08-ua-0mJ" secondAttribute="bottom" id="VNJ-sn-cbd"/>
<constraint firstItem="t08-ua-0mJ" firstAttribute="leading" secondItem="kjJ-Tb-SIW" secondAttribute="leading" constant="10" id="aaN-eN-yz7"/>
<constraint firstItem="PZC-Hd-Q6a" firstAttribute="top" secondItem="5CT-Ht-Z3v" secondAttribute="bottom" constant="8" id="bZn-CT-m7K"/>
<constraint firstItem="5CT-Ht-Z3v" firstAttribute="leading" secondItem="kjJ-Tb-SIW" secondAttribute="leading" constant="18" id="e5q-YY-hSP"/>
<constraint firstAttribute="height" constant="70" id="kCj-jw-q4B"/>
<constraint firstItem="5CT-Ht-Z3v" firstAttribute="top" secondItem="kjJ-Tb-SIW" secondAttribute="top" constant="8" id="r5R-Ap-b9I"/>
<constraint firstAttribute="trailing" secondItem="5CT-Ht-Z3v" secondAttribute="trailing" constant="18" id="smO-Tz-CPx"/>
<constraint firstAttribute="trailing" secondItem="t08-ua-0mJ" secondAttribute="trailing" constant="10" id="z9T-Cv-5SH"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="PZC-Hd-Q6a" firstAttribute="leading" secondItem="kjJ-Tb-SIW" secondAttribute="leading" constant="18" id="Khv-I4-mWb"/>
<constraint firstAttribute="trailing" secondItem="PZC-Hd-Q6a" secondAttribute="trailing" constant="18" id="VJ7-z3-LW3"/>
<constraint firstAttribute="bottom" secondItem="t08-ua-0mJ" secondAttribute="bottom" id="VNJ-sn-cbd"/>
<constraint firstItem="t08-ua-0mJ" firstAttribute="leading" secondItem="kjJ-Tb-SIW" secondAttribute="leading" constant="10" id="aaN-eN-yz7"/>
<constraint firstItem="PZC-Hd-Q6a" firstAttribute="top" secondItem="5CT-Ht-Z3v" secondAttribute="bottom" constant="8" id="bZn-CT-m7K"/>
<constraint firstItem="5CT-Ht-Z3v" firstAttribute="leading" secondItem="kjJ-Tb-SIW" secondAttribute="leading" constant="18" id="e5q-YY-hSP"/>
<constraint firstAttribute="height" constant="70" id="kCj-jw-q4B"/>
<constraint firstItem="5CT-Ht-Z3v" firstAttribute="top" secondItem="kjJ-Tb-SIW" secondAttribute="top" constant="8" id="r5R-Ap-b9I"/>
<constraint firstAttribute="trailing" secondItem="5CT-Ht-Z3v" secondAttribute="trailing" constant="18" id="smO-Tz-CPx"/>
<constraint firstAttribute="trailing" secondItem="t08-ua-0mJ" secondAttribute="trailing" constant="10" id="z9T-Cv-5SH"/>
<constraint firstItem="1YY-gb-LG4" firstAttribute="top" secondItem="uOi-KN-l9I" secondAttribute="top" id="6LT-5K-ftH"/>
<constraint firstItem="kjJ-Tb-SIW" firstAttribute="leading" secondItem="uOi-KN-l9I" secondAttribute="leading" id="GJK-3l-t3Y"/>
<constraint firstAttribute="trailing" secondItem="1YY-gb-LG4" secondAttribute="trailing" id="M3s-AR-hKf"/>
<constraint firstAttribute="height" constant="140" id="aWW-v9-LSk"/>
<constraint firstAttribute="trailing" secondItem="kjJ-Tb-SIW" secondAttribute="trailing" id="eIu-yM-Lhs"/>
<constraint firstItem="1YY-gb-LG4" firstAttribute="leading" secondItem="uOi-KN-l9I" secondAttribute="leading" id="mGS-4h-HKB"/>
<constraint firstItem="kjJ-Tb-SIW" firstAttribute="top" secondItem="uOi-KN-l9I" secondAttribute="top" constant="70" id="n8T-xk-7sh"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="1YY-gb-LG4" firstAttribute="top" secondItem="uOi-KN-l9I" secondAttribute="top" id="6LT-5K-ftH"/>
<constraint firstItem="kjJ-Tb-SIW" firstAttribute="leading" secondItem="uOi-KN-l9I" secondAttribute="leading" id="GJK-3l-t3Y"/>
<constraint firstAttribute="trailing" secondItem="1YY-gb-LG4" secondAttribute="trailing" id="M3s-AR-hKf"/>
<constraint firstAttribute="height" constant="140" id="aWW-v9-LSk"/>
<constraint firstAttribute="trailing" secondItem="kjJ-Tb-SIW" secondAttribute="trailing" id="eIu-yM-Lhs"/>
<constraint firstItem="1YY-gb-LG4" firstAttribute="leading" secondItem="uOi-KN-l9I" secondAttribute="leading" id="mGS-4h-HKB"/>
<constraint firstItem="kjJ-Tb-SIW" firstAttribute="top" secondItem="uOi-KN-l9I" secondAttribute="top" constant="70" id="n8T-xk-7sh"/>
<constraint firstAttribute="trailing" secondItem="6yx-o1-vbD" secondAttribute="trailing" constant="19" id="R2S-Ws-WMJ"/>
<constraint firstAttribute="trailing" secondItem="uOi-KN-l9I" secondAttribute="trailing" id="SWf-ih-6pd"/>
<constraint firstAttribute="trailing" secondItem="k3J-Eg-itz" secondAttribute="trailing" constant="11" id="ZyA-Tq-Sfq"/>
<constraint firstItem="uOi-KN-l9I" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" id="aiw-9p-H6e"/>
<constraint firstItem="6yx-o1-vbD" firstAttribute="top" secondItem="k3J-Eg-itz" secondAttribute="bottom" constant="10" id="cg9-yK-6ei"/>
<constraint firstItem="AJ2-lJ-NUq" firstAttribute="centerY" secondItem="k3J-Eg-itz" secondAttribute="centerY" id="dcE-Vs-7Rt"/>
<constraint firstItem="uOi-KN-l9I" firstAttribute="top" secondItem="6yx-o1-vbD" secondAttribute="bottom" constant="3" id="dk7-BQ-XYO"/>
<constraint firstItem="k3J-Eg-itz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="AJ2-lJ-NUq" secondAttribute="trailing" constant="10" id="hr4-Hl-7dk"/>
<constraint firstItem="6yx-o1-vbD" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" constant="19" id="jwU-gh-qcW"/>
<constraint firstAttribute="height" constant="300" id="lXv-gM-CjN"/>
<constraint firstItem="k3J-Eg-itz" firstAttribute="top" secondItem="Gg0-TE-OGb" secondAttribute="top" constant="33" id="mor-t9-7Ke"/>
<constraint firstItem="AJ2-lJ-NUq" firstAttribute="top" secondItem="Gg0-TE-OGb" secondAttribute="top" constant="33" id="v8n-Gp-nQM"/>
<constraint firstItem="AJ2-lJ-NUq" firstAttribute="leading" secondItem="Gg0-TE-OGb" secondAttribute="leading" constant="19" id="xFm-Bs-yzw"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="uOi-KN-l9I" secondAttribute="trailing" id="1Sf-bE-wYd"/>
<constraint firstItem="uOi-KN-l9I" firstAttribute="leading" secondItem="rhx-dD-4EJ" secondAttribute="leading" id="2fA-Yk-wWM"/>
<constraint firstAttribute="height" constant="555" id="6v6-fz-e8o"/>
<constraint firstItem="k3J-Eg-itz" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="AJ2-lJ-NUq" secondAttribute="trailing" constant="10" id="Dqz-kf-feR"/>
<constraint firstItem="6yx-o1-vbD" firstAttribute="leading" secondItem="rhx-dD-4EJ" secondAttribute="leading" constant="19" id="N10-Ro-yH2"/>
<constraint firstAttribute="trailing" secondItem="6yx-o1-vbD" secondAttribute="trailing" constant="19" id="OOw-6o-Tgu"/>
<constraint firstItem="uOi-KN-l9I" firstAttribute="top" secondItem="rhx-dD-4EJ" secondAttribute="top" constant="406" id="XV1-Eu-q2K"/>
<constraint firstItem="Gg0-TE-OGb" firstAttribute="width" secondItem="rhx-dD-4EJ" secondAttribute="width" id="EBX-KN-pRT"/>
<constraint firstItem="Gg0-TE-OGb" firstAttribute="top" secondItem="rhx-dD-4EJ" secondAttribute="top" constant="300" id="UEM-Mh-0H9"/>
<constraint firstItem="xWb-IJ-v7F" firstAttribute="leading" secondItem="rhx-dD-4EJ" secondAttribute="leading" id="YnP-Nk-QxR"/>
<constraint firstItem="6yx-o1-vbD" firstAttribute="top" secondItem="AJ2-lJ-NUq" secondAttribute="bottom" constant="10" id="aKJ-nR-LVK"/>
<constraint firstItem="k3J-Eg-itz" firstAttribute="top" secondItem="rhx-dD-4EJ" secondAttribute="top" constant="333" id="bga-yP-JTC"/>
<constraint firstAttribute="width" constant="600" placeholder="YES" id="hOT-Wn-hIb"/>
<constraint firstAttribute="trailing" secondItem="xWb-IJ-v7F" secondAttribute="trailing" id="hko-ol-XDd"/>
<constraint firstAttribute="trailing" secondItem="k3J-Eg-itz" secondAttribute="trailing" constant="11" id="i9P-es-EQL"/>
<constraint firstItem="AJ2-lJ-NUq" firstAttribute="leading" secondItem="rhx-dD-4EJ" secondAttribute="leading" constant="19" id="j4p-mo-ZxL"/>
<constraint firstItem="xWb-IJ-v7F" firstAttribute="top" secondItem="rhx-dD-4EJ" secondAttribute="top" constant="76" id="khR-Uj-OTH"/>
<constraint firstItem="d8r-TX-pwX" firstAttribute="top" secondItem="rhx-dD-4EJ" secondAttribute="top" constant="30" id="l68-Ta-YKg"/>
<constraint firstAttribute="centerX" secondItem="d8r-TX-pwX" secondAttribute="centerX" id="l6k-EH-Yb8"/>
<constraint firstItem="AJ2-lJ-NUq" firstAttribute="centerY" secondItem="k3J-Eg-itz" secondAttribute="centerY" id="xNG-4j-ETw"/>
<constraint firstItem="Gg0-TE-OGb" firstAttribute="leading" secondItem="rhx-dD-4EJ" secondAttribute="leading" id="rS3-go-zbf"/>
</constraints>
</view>
</subviews>

View file

@ -14,7 +14,7 @@
limitations under the License.
*/
#import "MXKAuthInputsView.h"
#import <MatrixKit/MatrixKit.h>
@interface AuthInputsView : MXKAuthInputsView
@ -36,4 +36,8 @@
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *userLoginContainerTopConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *passwordContainerTopConstraint;
@property (weak, nonatomic) IBOutlet UILabel *messageLabel;
@property (weak, nonatomic) IBOutlet MXKAuthenticationRecaptchaWebView *recaptchaWebView;
@end

View file

@ -18,6 +18,13 @@
#import "VectorDesignValues.h"
@interface AuthInputsView ()
{
MXK3PID *submittedEmail;
}
@end
@implementation AuthInputsView
+ (UINib *)nib
@ -39,8 +46,16 @@
self.passWordTextField.placeholder = NSLocalizedStringFromTable(@"auth_password_placeholder", @"Vector", nil);
self.passWordTextField.textColor = kVectorTextColorBlack;
self.emailTextField.placeholder = NSLocalizedStringFromTable(@"auth_email_placeholder", @"Vector", nil);
self.emailTextField.textColor = kVectorTextColorBlack;
self.messageLabel.numberOfLines = 0;
}
- (void)destroy
{
[super destroy];
submittedEmail = nil;
}
#pragma mark -
@ -50,6 +65,9 @@
// Validate first the provided session
MXAuthenticationSession *validSession = [self validateAuthenticationSession:authSession];
// Reset UI by hidding all items
[self hideInputsContainer];
if ([super setAuthSession:validSession withAuthType:authType])
{
if (authType == MXKAuthenticationTypeLogin)
@ -61,6 +79,8 @@
self.userLoginContainerTopConstraint.constant = 0;
self.passwordContainerTopConstraint.constant = 50;
self.userLoginContainer.hidden = NO;
self.passwordContainer.hidden = NO;
self.emailContainer.hidden = YES;
self.repeatPasswordContainer.hidden = YES;
}
@ -70,39 +90,290 @@
self.userLoginTextField.placeholder = NSLocalizedStringFromTable(@"auth_user_name_placeholder", @"Vector", nil);
self.userLoginContainerTopConstraint.constant = 50;
self.passwordContainerTopConstraint.constant = 100;
if (self.isEmailIdentityFlowSupported)
{
if (self.isEmailIdentityFlowRequired)
{
self.emailTextField.placeholder = NSLocalizedStringFromTable(@"auth_email_placeholder", @"Vector", nil);
}
else
{
self.emailTextField.placeholder = NSLocalizedStringFromTable(@"auth_optional_email_placeholder", @"Vector", nil);
}
self.userLoginContainerTopConstraint.constant = 50;
self.passwordContainerTopConstraint.constant = 100;
self.emailContainer.hidden = NO;
}
else
{
self.userLoginContainerTopConstraint.constant = 0;
self.passwordContainerTopConstraint.constant = 50;
self.emailContainer.hidden = YES;
}
self.emailContainer.hidden = NO;
self.userLoginContainer.hidden = NO;
self.passwordContainer.hidden = NO;
self.repeatPasswordContainer.hidden = NO;
}
CGRect frame = self.repeatPasswordContainer.frame;
self.viewHeightConstraint.constant = frame.origin.y + frame.size.height;
return YES;
}
return NO;
}
- (CGFloat)actualHeight
- (void)prepareParameters:(void (^)(NSDictionary *parameters))callback;
{
return self.viewHeightConstraint.constant;
if (callback)
{
// Prepare here parameters dict by checking each required fields.
NSDictionary *parameters = nil;
// Remove whitespace in user login text field
NSString *userLogin = self.userLoginTextField.text;
self.userLoginTextField.text = [userLogin stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// Handle here the supported login flow
if (type == MXKAuthenticationTypeLogin)
{
if (self.isPasswordBasedFlowSupported)
{
// Check required fields
if (self.userLoginTextField.text.length && self.passWordTextField.text.length)
{
//Check whether user login is an email or a username.
NSString *user = self.userLoginTextField.text;
if ([MXTools isEmailAddress:user])
{
parameters = @{
@"type": kMXLoginFlowTypePassword,
@"medium": @"email",
@"address": user,
@"password": self.passWordTextField.text
};
}
else
{
parameters = @{
@"type": kMXLoginFlowTypePassword,
@"user": user,
@"password": self.passWordTextField.text
};
}
}
else
{
if (inputsAlert)
{
[inputsAlert dismiss:NO];
}
inputsAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"auth_invalid_login_param", @"Vector", nil) message:nil style:MXKAlertStyleAlert];
inputsAlert.cancelButtonIndex = [inputsAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
inputsAlert = nil;
}];
[self.delegate authInputsView:self presentMXKAlert:inputsAlert];
}
}
}
else
{
// Check the validity of the parameters
NSString *alertTitle = nil;
if (!self.userLoginTextField.text.length)
{
// FIXME check validity of the non empty user name
NSLog(@"[AuthInputsView] Invalid user name");
alertTitle = NSLocalizedStringFromTable(@"auth_invalid_user_name", @"Vector", nil);
}
else if (!self.passWordTextField.text.length)
{
NSLog(@"[AuthInputsView] Missing Passwords");
alertTitle = NSLocalizedStringFromTable(@"auth_missing_password", @"Vector", nil);
}
else if (self.passWordTextField.text.length < 6)
{
NSLog(@"[AuthInputsView] Invalid Passwords");
alertTitle = NSLocalizedStringFromTable(@"auth_invalid_password", @"Vector", nil);
}
else if ([self.repeatPasswordTextField.text isEqualToString:self.passWordTextField.text] == NO)
{
NSLog(@"[AuthInputsView] Passwords don't match");
alertTitle = NSLocalizedStringFromTable(@"auth_password_dont_match", @"Vector", nil);
}
else if (self.isEmailIdentityFlowRequired && !self.emailTextField.text.length)
{
NSLog(@"[AuthInputsView] Missing email");
alertTitle = NSLocalizedStringFromTable(@"auth_missing_email", @"Vector", nil);
}
if (alertTitle)
{
if (inputsAlert)
{
[inputsAlert dismiss:NO];
}
inputsAlert = [[MXKAlert alloc] initWithTitle:alertTitle message:nil style:MXKAlertStyleAlert];
inputsAlert.cancelButtonIndex = [inputsAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:MXKAlertActionStyleDefault handler:^(MXKAlert *alert) {
inputsAlert = nil;
}];
[self.delegate authInputsView:self presentMXKAlert:inputsAlert];
}
else
{
// Check whether an email has been set, and if it is not handled yet
if (!self.emailContainer.isHidden && self.emailTextField.text.length && !self.isEmailIdentityFlowCompleted)
{
// Retrieve the REST client from delegate
MXRestClient *restClient;
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsViewEmailValidationRestClient:)])
{
restClient = [self.delegate authInputsViewEmailValidationRestClient:self];
}
if (restClient)
{
// Launch email validation
submittedEmail = [[MXK3PID alloc] initWithMedium:kMX3PIDMediumEmail andAddress:self.emailTextField.text];
[submittedEmail requestValidationTokenWithMatrixRestClient:restClient
success:^{
NSURL *identServerURL = [NSURL URLWithString:restClient.identityServer];
NSDictionary *parameters;
parameters = @{
@"auth": @{@"session":currentSession.session, @"threepid_creds": @{@"client_secret": submittedEmail.clientSecret, @"id_server": identServerURL.host, @"sid": submittedEmail.sid}, @"type": kMXLoginFlowTypeEmailIdentity},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_email": @(YES)
};
[self hideInputsContainer];
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_email_validation_message", @"Vector", nil);
self.messageLabel.hidden = NO;
callback(parameters);
} failure:^(NSError *error) {
NSLog(@"[AuthInputsView] Failed to request email token: %@", error);
callback(nil);
}];
// Async response
return;
}
else if (self.isEmailIdentityFlowRequired)
{
NSLog(@"[AuthInputsView] Authentication failed during the email identity stage");
}
}
else if (self.isRecaptchaFlowRequired)
{
[self displayRecaptchaForm:^(NSString *response) {
if (response.length)
{
NSDictionary *parameters = @{
@"auth": @{@"session":currentSession.session, @"response": response, @"type": kMXLoginFlowTypeRecaptcha},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_email": [NSNumber numberWithBool:self.isEmailIdentityFlowCompleted]
};
callback(parameters);
}
else
{
NSLog(@"[AuthInputsView] reCaptcha stage failed");
callback(nil);
}
}];
// Async response
return;
}
else if (self.isPasswordBasedFlowSupported)
{
parameters = @{
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_email": @(NO)
};
}
}
}
callback(parameters);
}
}
- (void)updateAuthSessionWithCompletedStages:(NSArray *)completedStages didUpdateParameters:(void (^)(NSDictionary *parameters))callback
{
if (callback)
{
if (currentSession)
{
currentSession.completed = completedStages;
// Check the supported use case
if ([completedStages indexOfObject:kMXLoginFlowTypeEmailIdentity] != NSNotFound && self.isRecaptchaFlowRequired)
{
[self displayRecaptchaForm:^(NSString *response) {
if (response.length)
{
// Update the parameters dict
NSDictionary *parameters = @{
@"auth": @{@"session": currentSession.session, @"response": response, @"type": kMXLoginFlowTypeRecaptcha},
@"username": self.userLoginTextField.text,
@"password": self.passWordTextField.text,
@"bind_email": @(YES)
};
callback (parameters);
}
else
{
NSLog(@"[AuthInputsView] reCaptcha stage failed");
callback (nil);
}
}];
return;
}
}
NSLog(@"[AuthInputsView] updateAuthSessionWithCompletedStages failed");
callback (nil);
}
}
- (BOOL)areAllRequiredFieldsFilled
{
if (self.isPasswordBasedFlowSupported)
{
if (type == MXKAuthenticationTypeLogin)
{
return (self.userLoginTextField.text.length && self.passWordTextField.text.length);
}
else
{
return (self.userLoginTextField.text.length && self.passWordTextField.text.length && self.repeatPasswordTextField.text.length);
}
}
return (self.userLoginTextField.text.length && (!self.isEmailIdentityFlowRequired || self.emailTextField.text.length) && self.passWordTextField.text.length && self.repeatPasswordTextField.text.length);
// Input fields are checked during parameters preparation
return YES;
}
- (BOOL)shouldPromptUserForEmailAddress
{
return (self.isEmailIdentityFlowSupported && !self.emailTextField.text.length);
}
- (void)dismissKeyboard
@ -124,11 +395,8 @@
// "Done" key has been pressed
[textField resignFirstResponder];
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsDoneKeyHasBeenPressed:)])
{
// Launch authentication now
[self.delegate authInputsDoneKeyHasBeenPressed:self];
}
// Launch authentication now
[self.delegate authInputsViewDidPressDoneKey:self];
}
else
{
@ -152,6 +420,59 @@
#pragma mark -
- (void)hideInputsContainer
{
// Hide all inputs container
self.userLoginContainer.hidden = YES;
self.passwordContainer.hidden = YES;
self.emailContainer.hidden = YES;
self.repeatPasswordContainer.hidden = YES;
// Hide other items
self.messageLabel.hidden = YES;
self.recaptchaWebView.hidden = YES;
}
- (BOOL)displayRecaptchaForm:(void (^)(NSString *response))callback
{
// Retrieve the site key
NSString *siteKey;
id recaptchaParams = [currentSession.params objectForKey:kMXLoginFlowTypeRecaptcha];
if (recaptchaParams && [recaptchaParams isKindOfClass:NSDictionary.class])
{
NSDictionary *recaptchaParamsDict = (NSDictionary*)recaptchaParams;
siteKey = [recaptchaParamsDict objectForKey:@"public_key"];
}
// Retrieve the REST client from delegate
MXRestClient *restClient;
if (self.delegate && [self.delegate respondsToSelector:@selector(authInputsViewEmailValidationRestClient:)])
{
restClient = [self.delegate authInputsViewEmailValidationRestClient:self];
}
// Sanity check
if (siteKey.length && restClient && callback)
{
[self hideInputsContainer];
self.messageLabel.hidden = NO;
self.messageLabel.text = NSLocalizedStringFromTable(@"auth_recaptcha_message", @"Vector", nil);
self.recaptchaWebView.hidden = NO;
CGRect frame = self.recaptchaWebView.frame;
self.viewHeightConstraint.constant = frame.origin.y + frame.size.height;
[self.recaptchaWebView openRecaptchaWidgetWithSiteKey:siteKey fromHomeServer:restClient.homeserver callback:callback];
return YES;
}
return NO;
}
// Tell whether a flow type is supported or not by this view.
- (BOOL)isSupportedFlowType:(MXLoginFlowType)flowType
{
@ -258,9 +579,9 @@
- (BOOL)isPasswordBasedFlowSupported
{
if (session)
if (currentSession)
{
for (MXLoginFlow *loginFlow in session.flows)
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if ([loginFlow.type isEqualToString:kMXLoginFlowTypePassword] || [loginFlow.stages indexOfObject:kMXLoginFlowTypePassword] != NSNotFound)
{
@ -274,9 +595,9 @@
- (BOOL)isEmailIdentityFlowSupported
{
if (session)
if (currentSession)
{
for (MXLoginFlow *loginFlow in session.flows)
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeEmailIdentity] != NSNotFound || [loginFlow.type isEqualToString:kMXLoginFlowTypeEmailIdentity])
{
@ -290,9 +611,9 @@
- (BOOL)isEmailIdentityFlowRequired
{
if (session && session.flows)
if (currentSession && currentSession.flows)
{
for (MXLoginFlow *loginFlow in session.flows)
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeEmailIdentity] == NSNotFound && ![loginFlow.type isEqualToString:kMXLoginFlowTypeEmailIdentity])
{
@ -306,4 +627,35 @@
return NO;
}
- (BOOL)isEmailIdentityFlowCompleted
{
if (currentSession && currentSession.completed)
{
if ([currentSession.completed indexOfObject:kMXLoginFlowTypeEmailIdentity] != NSNotFound)
{
return YES;
}
}
return NO;
}
- (BOOL)isRecaptchaFlowRequired
{
if (currentSession && currentSession.flows)
{
for (MXLoginFlow *loginFlow in currentSession.flows)
{
if ([loginFlow.stages indexOfObject:kMXLoginFlowTypeRecaptcha] == NSNotFound && ![loginFlow.type isEqualToString:kMXLoginFlowTypeRecaptcha])
{
return NO;
}
}
return YES;
}
return NO;
}
@end

View file

@ -85,7 +85,7 @@
<constraint firstAttribute="height" constant="21" id="Kvu-hz-22A"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" returnKeyType="done" secureTextEntry="YES"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="emailAddress" returnKeyType="done"/>
<connections>
<outlet property="delegate" destination="x74-04-ezp" id="ViI-x8-eWu"/>
</connections>
@ -142,22 +142,41 @@
<constraint firstItem="BQM-LP-8Eq" firstAttribute="top" secondItem="rb1-L5-udI" secondAttribute="top" constant="18" id="yhI-hm-zp5"/>
</constraints>
</view>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="68j-f9-JG4">
<rect key="frame" x="8" y="8" width="38" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<webView hidden="YES" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="whs-Ob-uzD" customClass="MXKAuthenticationRecaptchaWebView">
<rect key="frame" x="0.0" y="26" width="600" height="500"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="500" id="Opu-bi-f6t"/>
</constraints>
</webView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="UfH-jv-6w4" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" constant="50" id="1LY-GW-rgL"/>
<constraint firstItem="rb1-L5-udI" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" constant="150" id="75U-tx-PsQ"/>
<constraint firstItem="UfH-jv-6w4" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" id="7Bk-GF-MZ0"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="68j-f9-JG4" secondAttribute="trailing" constant="8" id="8Aa-YT-MP5"/>
<constraint firstAttribute="trailing" secondItem="UfH-jv-6w4" secondAttribute="trailing" id="8dz-wY-Kxx"/>
<constraint firstItem="whs-Ob-uzD" firstAttribute="centerX" secondItem="x74-04-ezp" secondAttribute="centerX" id="8lX-k1-85c"/>
<constraint firstItem="68j-f9-JG4" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" constant="8" id="BK1-XE-vz5"/>
<constraint firstItem="bXz-VI-5FS" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" id="Frq-sH-HZT"/>
<constraint firstItem="xOW-lo-QGC" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" id="NOu-LR-RvE"/>
<constraint firstAttribute="trailing" secondItem="bXz-VI-5FS" secondAttribute="trailing" id="NiV-pJ-PfV"/>
<constraint firstAttribute="trailing" secondItem="xOW-lo-QGC" secondAttribute="trailing" id="SNm-WQ-Piu"/>
<constraint firstItem="xOW-lo-QGC" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" id="WmX-gO-hPJ"/>
<constraint firstItem="rb1-L5-udI" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" id="XAJ-ST-sWV"/>
<constraint firstItem="68j-f9-JG4" firstAttribute="leading" secondItem="x74-04-ezp" secondAttribute="leading" constant="8" id="aYh-VJ-bss"/>
<constraint firstAttribute="trailing" secondItem="rb1-L5-udI" secondAttribute="trailing" id="c49-Cf-H9a"/>
<constraint firstItem="bXz-VI-5FS" firstAttribute="top" secondItem="x74-04-ezp" secondAttribute="top" id="enV-j0-cgR"/>
<constraint firstItem="whs-Ob-uzD" firstAttribute="top" secondItem="68j-f9-JG4" secondAttribute="bottom" id="g87-rp-bgb"/>
<constraint firstAttribute="height" constant="200" id="qBF-0J-3VM"/>
<constraint firstItem="whs-Ob-uzD" firstAttribute="width" secondItem="x74-04-ezp" secondAttribute="width" id="wa3-pP-FzX"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<nil key="simulatedTopBarMetrics"/>
@ -167,10 +186,12 @@
<outlet property="emailContainer" destination="bXz-VI-5FS" id="4J7-D0-Dmf"/>
<outlet property="emailSeparator" destination="YQ4-Kj-XPh" id="iub-NG-iJR"/>
<outlet property="emailTextField" destination="odF-W1-Vdr" id="DOS-H7-MZy"/>
<outlet property="messageLabel" destination="68j-f9-JG4" id="LfM-qs-gEM"/>
<outlet property="passWordTextField" destination="6rs-rR-DkS" id="VeL-kt-Fpp"/>
<outlet property="passwordContainer" destination="UfH-jv-6w4" id="aGz-rZ-j5q"/>
<outlet property="passwordContainerTopConstraint" destination="1LY-GW-rgL" id="feb-7y-uob"/>
<outlet property="passwordSeparator" destination="vUH-bJ-5gJ" id="mub-of-o9s"/>
<outlet property="recaptchaWebView" destination="whs-Ob-uzD" id="0S8-PN-Ykm"/>
<outlet property="repeatPasswordContainer" destination="rb1-L5-udI" id="NjO-O7-WYX"/>
<outlet property="repeatPasswordSeparator" destination="ddx-5u-PbG" id="MtA-Rf-dhU"/>
<outlet property="repeatPasswordTextField" destination="BQM-LP-8Eq" id="mgM-dU-mJo"/>