SAS verification screen matching design

This commit is contained in:
David Baker 2019-01-18 16:56:49 +00:00
parent 1d2538a7bc
commit ec2d51cbbb
6 changed files with 168 additions and 7 deletions

View file

@ -60,6 +60,7 @@
@import "./views/elements/_DirectorySearchBox.scss"; @import "./views/elements/_DirectorySearchBox.scss";
@import "./views/elements/_Dropdown.scss"; @import "./views/elements/_Dropdown.scss";
@import "./views/elements/_EditableItemList.scss"; @import "./views/elements/_EditableItemList.scss";
@import "./views/elements/_HexVerify.scss";
@import "./views/elements/_ImageView.scss"; @import "./views/elements/_ImageView.scss";
@import "./views/elements/_InlineSpinner.scss"; @import "./views/elements/_InlineSpinner.scss";
@import "./views/elements/_MemberEventListSummary.scss"; @import "./views/elements/_MemberEventListSummary.scss";

View file

@ -0,0 +1,34 @@
/*
Copyright 2019 New Vector Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_HexVerify {
text-align: center;
}
.mx_HexVerify_pair {
display: inline-block;
font-weight: bold;
padding-left: 3px;
padding-right: 3px;
}
.mx_HexVerify_pair_verified {
color: $accent-color;
}
.mx_HexVerify_pair:hover{
color: $accent-color;
}

View file

@ -50,6 +50,7 @@ export default class DeviceVerifyDialog extends React.Component {
this.state = { this.state = {
phase: PHASE_START, phase: PHASE_START,
mode: SettingsStore.isFeatureEnabled("feature_sas") ? MODE_SAS : MODE_LEGACY, mode: SettingsStore.isFeatureEnabled("feature_sas") ? MODE_SAS : MODE_LEGACY,
sasVerified: false,
}; };
} }
@ -102,6 +103,10 @@ export default class DeviceVerifyDialog extends React.Component {
}); });
} }
_onVerifyStateChanged = (newVal) => {
this.setState({sasVerified: newVal});
}
_onSasMatchesClick = () => { _onSasMatchesClick = () => {
this._showSasEvent.confirm(); this._showSasEvent.confirm();
this.setState({ this.setState({
@ -127,7 +132,6 @@ export default class DeviceVerifyDialog extends React.Component {
body = this._renderSasVerificationPhaseStart(); body = this._renderSasVerificationPhaseStart();
break; break;
case PHASE_WAIT_FOR_PARTNER_TO_ACCEPT: case PHASE_WAIT_FOR_PARTNER_TO_ACCEPT:
//body = this._renderSasVerificationPhaseWaitForPartnerToAccept();
body = renderSasWaitAccept(this.props.userId); body = renderSasWaitAccept(this.props.userId);
break; break;
case PHASE_SHOW_SAS: case PHASE_SHOW_SAS:
@ -180,6 +184,7 @@ export default class DeviceVerifyDialog extends React.Component {
_renderSasVerificationPhaseShowSas() { _renderSasVerificationPhaseShowSas() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const HexVerify = sdk.getComponent('views.elements.HexVerify');
return <div> return <div>
<p>{_t( <p>{_t(
"Verify this user by confirming the following number appears on their screen" "Verify this user by confirming the following number appears on their screen"
@ -188,9 +193,15 @@ export default class DeviceVerifyDialog extends React.Component {
"For maximum security, we reccommend you do this in person or use another " + "For maximum security, we reccommend you do this in person or use another " +
"trusted means of communication" "trusted means of communication"
)}</p> )}</p>
<pre>{this._showSasEvent.sas}</pre> <HexVerify text={this._showSasEvent.sas}
onVerifiedStateChange={this._onVerifyStateChanged}
/>
<p>{_t(
"To continue, click on each pair to confirm it's correct.",
)}</p>
<DialogButtons onPrimaryButtonClick={this._onSasMatchesClick} <DialogButtons onPrimaryButtonClick={this._onSasMatchesClick}
primaryButton={_t("This Matches")} primaryButton={_t("Continue")}
primaryDisabled={!this.state.sasVerified}
hasCancel={true} hasCancel={true}
onCancel={this._onCancelClick} onCancel={this._onCancelClick}
/> />

View file

@ -38,6 +38,7 @@ export default class IncomingSasDialog extends React.Component {
this._showSasEvent = null; this._showSasEvent = null;
this.state = { this.state = {
phase: PHASE_START, phase: PHASE_START,
sasVerified: false,
}; };
this.props.verifier.on('show_sas', this._onVerifierShowSas); this.props.verifier.on('show_sas', this._onVerifierShowSas);
this.props.verifier.on('cancel', this._onVerifierCancel); this.props.verifier.on('cancel', this._onVerifierCancel);
@ -81,6 +82,10 @@ export default class IncomingSasDialog extends React.Component {
}); });
} }
_onVerifiedStateChange = (newVal) => {
this.setState({sasVerified: newVal});
}
_onSasMatchesClick = () => { _onSasMatchesClick = () => {
this._showSasEvent.confirm(); this._showSasEvent.confirm();
this.setState({ this.setState({
@ -121,6 +126,7 @@ export default class IncomingSasDialog extends React.Component {
_renderPhaseShowSas() { _renderPhaseShowSas() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const HexVerify = sdk.getComponent('views.elements.HexVerify');
return <div> return <div>
<p>{_t( <p>{_t(
"Verify this user by confirming the following number appears on their screen" "Verify this user by confirming the following number appears on their screen"
@ -129,9 +135,15 @@ export default class IncomingSasDialog extends React.Component {
"For maximum security, we reccommend you do this in person or use another " + "For maximum security, we reccommend you do this in person or use another " +
"trusted means of communication" "trusted means of communication"
)}</p> )}</p>
<pre>{this._showSasEvent.sas}</pre> <HexVerify text={this._showSasEvent.sas}
onVerifiedStateChange={this._onVerifiedStateChange}
/>
<p>{_t(
"To continue, click on each pair to confirm it's correct.",
)}</p>
<DialogButtons onPrimaryButtonClick={this._onSasMatchesClick} <DialogButtons onPrimaryButtonClick={this._onSasMatchesClick}
primaryButton={_t("This Matches")} primaryButton={_t("Continue")}
primaryDisabled={!this.state.sasVerified}
hasCancel={true} hasCancel={true}
onCancel={this._onCancelClick} onCancel={this._onCancelClick}
/> />
@ -184,7 +196,6 @@ export default class IncomingSasDialog extends React.Component {
} }
render() { render() {
console.log("rendering pahse "+this.state.phase);
let body; let body;
switch (this.state.phase) { switch (this.state.phase) {
case PHASE_START: case PHASE_START:

View file

@ -0,0 +1,104 @@
/*
Copyright 2019 New Vector Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import PropTypes from "prop-types";
import { _t } from '../../../languageHandler';
import classnames from 'classnames';
import sdk from '../../../index';
class HexVerifyPair extends React.Component {
static propTypes = {
text: PropTypes.string.isRequired,
index: PropTypes.number,
verified: PropTypes.bool,
onChange: PropTypes.func.isRequired,
}
_onClick = () => {
this.setState({verified: !this.props.verified});
this.props.onChange(this.props.index, !this.props.verified);
}
render() {
const classNames = {
mx_HexVerify_pair: true,
mx_HexVerify_pair_verified: this.props.verified,
};
const AccessibleButton = sdk.getComponent('views.elements.AccessibleButton');
return <AccessibleButton className={classnames(classNames)}
onClick={this._onClick}
>
{this.props.text}
</AccessibleButton>
}
}
/**
* Helps a user verify a hexadecimal code matches one displayed
* elsewhere (eg. on a different device)
*/
export default class HexVerify extends React.Component {
static propTypes = {
text: PropTypes.string.isRequired,
onVerifiedStateChange: PropTypes.func,
}
static defaultProps = {
onVerifiedStateChange: function() {},
}
constructor(props) {
super(props);
this.state = {
pairsVerified: [],
};
for (let i = 0; i < props.text.length; i += 2) {
this.state.pairsVerified.push(false);
}
}
_onPairChange = (index, newVal) => {
const oldVerified = this.state.pairsVerified.reduce((acc, val) => {
return acc && val;
}, true);
const newPairsVerified = this.state.pairsVerified.slice(0);
newPairsVerified[index] = newVal;
const newVerified = newPairsVerified.reduce((acc, val) => {
return acc && val;
}, true);
this.setState({pairsVerified: newPairsVerified});
if (oldVerified !== newVerified) {
this.props.onVerifiedStateChange(newVerified);
}
}
render() {
const pairs = [];
for (let i = 0; i < this.props.text.length / 2; ++i) {
pairs.push(<HexVerifyPair key={i} index={i}
text={this.props.text.substr(i * 2, 2)}
verified={this.state.pairsVerified[i]}
onChange={this._onPairChange}
/>);
}
return <div className="mx_HexVerify">
{pairs}
</div>;
}
}

View file

@ -947,7 +947,7 @@
"Send Verification Request": "Send Verification Request", "Send Verification Request": "Send Verification Request",
"Verify this user by confirming the following number appears on their screen": "Verify this user by confirming the following number appears on their screen", "Verify this user by confirming the following number appears on their screen": "Verify this user by confirming the following number appears on their screen",
"For maximum security, we reccommend you do this in person or use another trusted means of communication": "For maximum security, we reccommend you do this in person or use another trusted means of communication", "For maximum security, we reccommend you do this in person or use another trusted means of communication": "For maximum security, we reccommend you do this in person or use another trusted means of communication",
"This Matches": "This Matches", "To continue, click on each pair to confirm it's correct.": "To continue, click on each pair to confirm it's correct.",
"Verification complete!": "Verification complete!", "Verification complete!": "Verification complete!",
"Done": "Done", "Done": "Done",
"%(userId)s cancelled the verification.": "%(userId)s cancelled the verification.", "%(userId)s cancelled the verification.": "%(userId)s cancelled the verification.",