First working version of SAS
							parent
							
								
									2a20d9d67e
								
							
						
					
					
						commit
						1d2538a7bc
					
				|  | @ -29,6 +29,7 @@ import SettingsStore from './settings/SettingsStore'; | |||
| import MatrixActionCreators from './actions/MatrixActionCreators'; | ||||
| import {phasedRollOutExpiredForUser} from "./PhasedRollOut"; | ||||
| import Modal from './Modal'; | ||||
| import {verificationMethods} from 'matrix-js-sdk/lib/crypto'; | ||||
| 
 | ||||
| interface MatrixClientCreds { | ||||
|     homeserverUrl: string, | ||||
|  | @ -184,6 +185,7 @@ class MatrixClientPeg { | |||
|             deviceId: creds.deviceId, | ||||
|             timelineSupport: true, | ||||
|             forceTURN: SettingsStore.getValue('webRtcForceTURN', false), | ||||
|             verificationMethods: [verificationMethods.SAS] | ||||
|         }; | ||||
| 
 | ||||
|         this.matrixClient = createMatrixClient(opts, useIndexedDb); | ||||
|  |  | |||
|  | @ -1277,6 +1277,7 @@ export default React.createClass({ | |||
|         this.firstSyncComplete = false; | ||||
|         this.firstSyncPromise = Promise.defer(); | ||||
|         const cli = MatrixClientPeg.get(); | ||||
|         const IncomingSasDialog = sdk.getComponent('views.dialogs.IncomingSasDialog'); | ||||
| 
 | ||||
|         // Allow the JS SDK to reap timeline events. This reduces the amount of
 | ||||
|         // memory consumed as the JS SDK stores multiple distinct copies of room
 | ||||
|  | @ -1476,6 +1477,12 @@ export default React.createClass({ | |||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         cli.on("crypto.verification.start", (verifier) => { | ||||
|             Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, { | ||||
|                 verifier, | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|         // Fire the tinter right on startup to ensure the default theme is applied
 | ||||
|         // A later sync can/will correct the tint to be the right value for the user
 | ||||
|         const colorScheme = SettingsStore.getValue("roomColor"); | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| /* | ||||
| Copyright 2016 OpenMarket Ltd | ||||
| Copyright 2017 Vector Creations Ltd | ||||
| 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. | ||||
|  | @ -21,58 +22,273 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; | |||
| import sdk from '../../../index'; | ||||
| import * as FormattingUtils from '../../../utils/FormattingUtils'; | ||||
| import { _t } from '../../../languageHandler'; | ||||
| import SettingsStore from '../../../settings/SettingsStore'; | ||||
| import {verificationMethods} from 'matrix-js-sdk/lib/crypto'; | ||||
| import {renderSasWaitAccept} from '../../../sas_ui'; | ||||
| 
 | ||||
| export default function DeviceVerifyDialog(props) { | ||||
|     const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); | ||||
| const MODE_LEGACY = 'legacy'; | ||||
| const MODE_SAS = 'sas'; | ||||
| 
 | ||||
|     const key = FormattingUtils.formatCryptoKey(props.device.getFingerprint()); | ||||
|     const body = ( | ||||
|         <div> | ||||
|             <p> | ||||
|                 { _t("To verify that this device can be trusted, please contact its " + | ||||
|                     "owner using some other means (e.g. in person or a phone call) " + | ||||
|                     "and ask them whether the key they see in their User Settings " + | ||||
|                     "for this device matches the key below:") } | ||||
|             </p> | ||||
|             <div className="mx_UserSettings_cryptoSection"> | ||||
|                 <ul> | ||||
|                     <li><label>{ _t("Device name") }:</label> <span>{ props.device.getDisplayName() }</span></li> | ||||
|                     <li><label>{ _t("Device ID") }:</label> <span><code>{ props.device.deviceId }</code></span></li> | ||||
|                     <li><label>{ _t("Device key") }:</label> <span><code><b>{ key }</b></code></span></li> | ||||
|                 </ul> | ||||
|             </div> | ||||
|             <p> | ||||
|                 { _t("If it matches, press the verify button below. " + | ||||
|                     "If it doesn't, then someone else is intercepting this device " + | ||||
|                     "and you probably want to press the blacklist button instead.") } | ||||
|             </p> | ||||
|             <p> | ||||
|                 { _t("In future this verification process will be more sophisticated.") } | ||||
|             </p> | ||||
|         </div> | ||||
|     ); | ||||
| const PHASE_START = 0; | ||||
| const PHASE_WAIT_FOR_PARTNER_TO_ACCEPT = 1; | ||||
| const PHASE_SHOW_SAS = 2; | ||||
| const PHASE_WAIT_FOR_PARTNER_TO_CONFIRM = 3; | ||||
| const PHASE_VERIFIED = 4; | ||||
| const PHASE_CANCELLED = 5; | ||||
| 
 | ||||
|     function onFinished(confirm) { | ||||
|         if (confirm) { | ||||
|             MatrixClientPeg.get().setDeviceVerified( | ||||
|                 props.userId, props.device.deviceId, true, | ||||
|             ); | ||||
|         } | ||||
|         props.onFinished(confirm); | ||||
| export default class DeviceVerifyDialog extends React.Component { | ||||
|     static propTypes = { | ||||
|         userId: PropTypes.string.isRequired, | ||||
|         device: PropTypes.object.isRequired, | ||||
|         onFinished: PropTypes.func.isRequired, | ||||
|     }; | ||||
| 
 | ||||
|     constructor() { | ||||
|         super(); | ||||
|         this._verifier = null; | ||||
|         this._showSasEvent = null; | ||||
|         this.state = { | ||||
|             phase: PHASE_START, | ||||
|             mode: SettingsStore.isFeatureEnabled("feature_sas") ? MODE_SAS : MODE_LEGACY, | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|         <QuestionDialog | ||||
|             title={_t("Verify device")} | ||||
|             description={body} | ||||
|             button={_t("I verify that the keys match")} | ||||
|             onFinished={onFinished} | ||||
|         /> | ||||
|     ); | ||||
|     componentWillUnmount() { | ||||
|         if (this._verifier) { | ||||
|             this._verifier.removeListener('show_sas', this._onVerifierShowSas); | ||||
|             this._verifier.cancel('User cancel'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     _onSwitchToLegacyClick = () => { | ||||
|         this.setState({mode: MODE_LEGACY}); | ||||
|     } | ||||
| 
 | ||||
|     _onSwitchToSasClick = () => { | ||||
|         this.setState({mode: MODE_SAS}); | ||||
|     } | ||||
| 
 | ||||
|     _onCancelClick = () => { | ||||
|         this.props.onFinished(false); | ||||
|     } | ||||
| 
 | ||||
|     _onLegacyFinished = (confirm) => { | ||||
|         if (confirm) { | ||||
|             MatrixClientPeg.get().setDeviceVerified( | ||||
|                 this.props.userId, this.props.device.deviceId, true, | ||||
|             ); | ||||
|         } | ||||
|         this.props.onFinished(confirm); | ||||
|     } | ||||
| 
 | ||||
|     _onSasRequestClick = () => { | ||||
|         this.setState({ | ||||
|             phase: PHASE_WAIT_FOR_PARTNER_TO_ACCEPT, | ||||
|         }); | ||||
|         this._verifier = MatrixClientPeg.get().beginKeyVerification( | ||||
|             verificationMethods.SAS, this.props.userId, this.props.device.deviceId, | ||||
|         ); | ||||
|         this._verifier.on('show_sas', this._onVerifierShowSas); | ||||
|         this._verifier.verify().then(() => { | ||||
|             this.setState({phase: PHASE_VERIFIED}); | ||||
|             this._verifier.removeListener('show_sas', this._onVerifierShowSas); | ||||
|             this._verifier = null; | ||||
|         }).catch((e) => { | ||||
|             console.log("Verification failed", e); | ||||
|             this.setState({ | ||||
|                 phase: PHASE_CANCELLED, | ||||
|             }); | ||||
|             this._verifier = null; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _onSasMatchesClick = () => { | ||||
|         this._showSasEvent.confirm(); | ||||
|         this.setState({ | ||||
|             phase: PHASE_WAIT_FOR_PARTNER_TO_CONFIRM, | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _onVerifiedDoneClick = () => { | ||||
|         this.props.onFinished(true); | ||||
|     } | ||||
| 
 | ||||
|     _onVerifierShowSas = (e) => { | ||||
|         this._showSasEvent = e; | ||||
|         this.setState({ | ||||
|             phase: PHASE_SHOW_SAS, | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _renderSasVerification() { | ||||
|         let body; | ||||
|         switch (this.state.phase) { | ||||
|             case PHASE_START: | ||||
|                 body = this._renderSasVerificationPhaseStart(); | ||||
|                 break; | ||||
|             case PHASE_WAIT_FOR_PARTNER_TO_ACCEPT: | ||||
|                 //body = this._renderSasVerificationPhaseWaitForPartnerToAccept();
 | ||||
|                 body = renderSasWaitAccept(this.props.userId); | ||||
|                 break; | ||||
|             case PHASE_SHOW_SAS: | ||||
|                 body = this._renderSasVerificationPhaseShowSas(); | ||||
|                 break; | ||||
|             case PHASE_WAIT_FOR_PARTNER_TO_CONFIRM: | ||||
|                 body = this._renderSasVerificationPhaseWaitForPartnerToConfirm(); | ||||
|                 break; | ||||
|             case PHASE_VERIFIED: | ||||
|                 body = this._renderSasVerificationPhaseVerified(); | ||||
|                 break; | ||||
|             case PHASE_CANCELLED: | ||||
|                 body = this._renderSasVerificationPhaseCancelled(); | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         const BaseDialog = sdk.getComponent("dialogs.BaseDialog"); | ||||
|         return ( | ||||
|             <BaseDialog | ||||
|                 title={_t("Verify device")} | ||||
|                 onFinished={this._onCancelClick} | ||||
|             > | ||||
|                 {body} | ||||
|             </BaseDialog> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     _renderSasVerificationPhaseStart() { | ||||
|         const AccessibleButton = sdk.getComponent('views.elements.AccessibleButton'); | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
|         return ( | ||||
|             <div> | ||||
|                 <AccessibleButton | ||||
|                     element="span" className="mx_linkButton" onClick={this._onSwitchToLegacyClick} | ||||
|                 > | ||||
|                     {_t("Use Legacy Verification (for older clients)")} | ||||
|                 </AccessibleButton> | ||||
|                 <p> | ||||
|                     { _t("Do clicky clicky button press request verify user send to do.") } | ||||
|                 </p> | ||||
|                 <DialogButtons | ||||
|                     primaryButton={_t('Send Verification Request')} | ||||
|                     hasCancel={true} | ||||
|                     onPrimaryButtonClick={this._onSasRequestClick} | ||||
|                     onCancel={this._onCancelClick} | ||||
|                 /> | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     _renderSasVerificationPhaseShowSas() { | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
|         return <div> | ||||
|             <p>{_t( | ||||
|                 "Verify this user by confirming the following number appears on their screen" | ||||
|             )}</p> | ||||
|             <p>{_t( | ||||
|                 "For maximum security, we reccommend you do this in person or use another " + | ||||
|                 "trusted means of communication" | ||||
|             )}</p> | ||||
|             <pre>{this._showSasEvent.sas}</pre> | ||||
|             <DialogButtons onPrimaryButtonClick={this._onSasMatchesClick} | ||||
|                 primaryButton={_t("This Matches")} | ||||
|                 hasCancel={true} | ||||
|                 onCancel={this._onCancelClick} | ||||
|             /> | ||||
|         </div>; | ||||
|     } | ||||
| 
 | ||||
|     _renderSasVerificationPhaseWaitForPartnerToConfirm() { | ||||
|         const Spinner = sdk.getComponent('views.elements.Spinner'); | ||||
|         return <div> | ||||
|             <Spinner /> | ||||
|             <p>{_t( | ||||
|                 "Waiting for %(userId)s to confirm...", {userId: this.props.userId}, | ||||
|             )}</p> | ||||
|         </div>; | ||||
|     } | ||||
| 
 | ||||
|     _renderSasVerificationPhaseVerified() { | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
|         return <div> | ||||
|             <p>{_t("Verification complete!")}</p> | ||||
|             <DialogButtons onPrimaryButtonClick={this._onVerifiedDoneClick} | ||||
|                 primaryButton={_t("Done")} | ||||
|                 hasCancel={false} | ||||
|             /> | ||||
|         </div>; | ||||
|     } | ||||
| 
 | ||||
|     _renderSasVerificationPhaseCancelled() { | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
|                 <p>{_t( | ||||
|                     "%(userId)s cancelled the verification.", {userId: this.props.userId}, | ||||
|                 )}</p> | ||||
|                 <DialogButtons | ||||
|                     primaryButton={_t('Cancel')} | ||||
|                     hasCancel={false} | ||||
|                     onPrimaryButtonClick={this._onCancelClick} | ||||
|                 /> | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     _renderLegacyVerification() { | ||||
|         const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); | ||||
|         const AccessibleButton = sdk.getComponent('views.elements.AccessibleButton'); | ||||
| 
 | ||||
|         const key = FormattingUtils.formatCryptoKey(this.props.device.getFingerprint()); | ||||
|         const body = ( | ||||
|             <div> | ||||
|                 <AccessibleButton | ||||
|                     element="span" className="mx_linkButton" onClick={this._onSwitchToSasClick} | ||||
|                 > | ||||
|                     {_t("Use two-way text verification")} | ||||
|                 </AccessibleButton> | ||||
|                 <p> | ||||
|                     { _t("To verify that this device can be trusted, please contact its " + | ||||
|                         "owner using some other means (e.g. in person or a phone call) " + | ||||
|                         "and ask them whether the key they see in their User Settings " + | ||||
|                         "for this device matches the key below:") } | ||||
|                 </p> | ||||
|                 <div className="mx_UserSettings_cryptoSection"> | ||||
|                     <ul> | ||||
|                         <li><label>{ _t("Device name") }:</label> <span>{ this.props.device.getDisplayName() }</span></li> | ||||
|                         <li><label>{ _t("Device ID") }:</label> <span><code>{ this.props.device.deviceId }</code></span></li> | ||||
|                         <li><label>{ _t("Device key") }:</label> <span><code><b>{ key }</b></code></span></li> | ||||
|                     </ul> | ||||
|                 </div> | ||||
|                 <p> | ||||
|                     { _t("If it matches, press the verify button below. " + | ||||
|                         "If it doesn't, then someone else is intercepting this device " + | ||||
|                         "and you probably want to press the blacklist button instead.") } | ||||
|                 </p> | ||||
|                 <p> | ||||
|                     { _t("In future this verification process will be more sophisticated.") } | ||||
|                 </p> | ||||
|             </div> | ||||
|         ); | ||||
| 
 | ||||
|         return ( | ||||
|             <QuestionDialog | ||||
|                 title={_t("Verify device")} | ||||
|                 description={body} | ||||
|                 button={_t("I verify that the keys match")} | ||||
|                 onFinished={this._onLegacyFinished} | ||||
|             /> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     render() { | ||||
|         if (this.state.mode === MODE_LEGACY) { | ||||
|             return this._renderLegacyVerification(); | ||||
|         } else { | ||||
|             return <div> | ||||
|                 {this._renderSasVerification()} | ||||
|             </div>; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| DeviceVerifyDialog.propTypes = { | ||||
|     userId: PropTypes.string.isRequired, | ||||
|     device: PropTypes.object.isRequired, | ||||
|     onFinished: PropTypes.func.isRequired, | ||||
| }; | ||||
|  |  | |||
|  | @ -0,0 +1,218 @@ | |||
| /* | ||||
| 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 MatrixClientPeg from '../../../MatrixClientPeg'; | ||||
| import sdk from '../../../index'; | ||||
| import { _t } from '../../../languageHandler'; | ||||
| import {verificationMethods} from 'matrix-js-sdk/lib/crypto'; | ||||
| 
 | ||||
| const PHASE_START = 0; | ||||
| const PHASE_SHOW_SAS = 1; | ||||
| const PHASE_WAIT_FOR_PARTNER_TO_CONFIRM = 2; | ||||
| const PHASE_VERIFIED = 3; | ||||
| const PHASE_CANCELLED = 4; | ||||
| 
 | ||||
| export default class IncomingSasDialog extends React.Component { | ||||
|     static propTypes = { | ||||
|         verifier: PropTypes.object.isRequired, | ||||
|     }; | ||||
| 
 | ||||
|     constructor(props) { | ||||
|         super(props); | ||||
| 
 | ||||
|         this._showSasEvent = null; | ||||
|         this.state = { | ||||
|             phase: PHASE_START, | ||||
|         }; | ||||
|         this.props.verifier.on('show_sas', this._onVerifierShowSas); | ||||
|         this.props.verifier.on('cancel', this._onVerifierCancel); | ||||
|     } | ||||
| 
 | ||||
|     componentWillUnmount() { | ||||
|         if (this.state.phase !== PHASE_CANCELLED && this.state.phase !== PHASE_VERIFIED) { | ||||
|             this.props.verifier.cancel('User cancel'); | ||||
|         } | ||||
|         this.props.verifier.removeListener('show_sas', this._onVerifierShowSas); | ||||
|     } | ||||
| 
 | ||||
|     _onFinished = () => { | ||||
|         this.props.onFinished(this.state.phase === PHASE_VERIFIED); | ||||
|     } | ||||
| 
 | ||||
|     _onCancelClick = () => { | ||||
|         this.props.onFinished(this.state.phase === PHASE_VERIFIED); | ||||
|     } | ||||
| 
 | ||||
|     _onContinueClick = () => { | ||||
|         this.setState({phase: PHASE_WAIT_FOR_PARTNER_TO_CONFIRM}); | ||||
|         this.props.verifier.verify().then(() => { | ||||
|             this.setState({phase: PHASE_VERIFIED}); | ||||
|         }).catch((e) => { | ||||
|             console.log("Verification failed", e); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _onVerifierShowSas = (e) => { | ||||
|         this._showSasEvent = e; | ||||
|         this.setState({ | ||||
|             phase: PHASE_SHOW_SAS, | ||||
|             sas: e.sas, | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _onVerifierCancel = (e) => { | ||||
|         this.setState({ | ||||
|             phase: PHASE_CANCELLED, | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _onSasMatchesClick = () => { | ||||
|         this._showSasEvent.confirm(); | ||||
|         this.setState({ | ||||
|             phase: PHASE_WAIT_FOR_PARTNER_TO_CONFIRM, | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     _onVerifiedDoneClick = () => { | ||||
|         this.props.onFinished(true); | ||||
|     } | ||||
| 
 | ||||
|     _renderPhaseStart() { | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
|                 <h2>{this.props.verifier.userId}</h2> | ||||
|                 <p>{_t( | ||||
|                     "Verify this user to mark them as trusted. " + | ||||
|                     "Trusting users gives you extra peace of mind when using " + | ||||
|                     "end-to-end encrypted messages." | ||||
|                 )}</p> | ||||
|                 <p>{_t( | ||||
|                     // NB. Below wording adjusted to singular 'device' until we have
 | ||||
|                     // cross-signing
 | ||||
|                     "Verifying this user will mark their device as trusted, and " + | ||||
|                     "also mark your device as trusted to them" | ||||
|                 )}</p> | ||||
|                 <DialogButtons | ||||
|                     primaryButton={_t('Continue')} | ||||
|                     hasCancel={true} | ||||
|                     onPrimaryButtonClick={this._onContinueClick} | ||||
|                     onCancel={this._onCancelClick} | ||||
|                 /> | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     _renderPhaseShowSas() { | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
|         return <div> | ||||
|             <p>{_t( | ||||
|                 "Verify this user by confirming the following number appears on their screen" | ||||
|             )}</p> | ||||
|             <p>{_t( | ||||
|                 "For maximum security, we reccommend you do this in person or use another " + | ||||
|                 "trusted means of communication" | ||||
|             )}</p> | ||||
|             <pre>{this._showSasEvent.sas}</pre> | ||||
|             <DialogButtons onPrimaryButtonClick={this._onSasMatchesClick} | ||||
|                 primaryButton={_t("This Matches")} | ||||
|                 hasCancel={true} | ||||
|                 onCancel={this._onCancelClick} | ||||
|             /> | ||||
|         </div>; | ||||
|     } | ||||
| 
 | ||||
|     _renderPhaseWaitForPartnerToConfirm() { | ||||
|         const Spinner = sdk.getComponent("views.elements.Spinner"); | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
|                 <Spinner /> | ||||
|                 <p>{_t("Waiting for partner to confirm...")}</p> | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     _renderPhaseVerified() { | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
|                 <p>{_t( | ||||
|                     "Verification Complete!" | ||||
|                 )}</p> | ||||
|                 <DialogButtons | ||||
|                     primaryButton={_t('Done')} | ||||
|                     hasCancel={false} | ||||
|                     onPrimaryButtonClick={this._onVerifiedDoneClick} | ||||
|                 /> | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     _renderPhaseCancelled() { | ||||
|         const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
|                 <p>{_t( | ||||
|                     "The other party cancelled the verification." | ||||
|                 )}</p> | ||||
|                 <DialogButtons | ||||
|                     primaryButton={_t('Cancel')} | ||||
|                     hasCancel={false} | ||||
|                     onPrimaryButtonClick={this._onCancelClick} | ||||
|                 /> | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     render() { | ||||
|         console.log("rendering pahse "+this.state.phase); | ||||
|         let body; | ||||
|         switch (this.state.phase) { | ||||
|             case PHASE_START: | ||||
|                 body = this._renderPhaseStart(); | ||||
|                 break; | ||||
|             case PHASE_SHOW_SAS: | ||||
|                 body = this._renderPhaseShowSas(); | ||||
|                 break; | ||||
|             case PHASE_WAIT_FOR_PARTNER_TO_CONFIRM: | ||||
|                 body = this._renderPhaseWaitForPartnerToConfirm(); | ||||
|                 break; | ||||
|             case PHASE_VERIFIED: | ||||
|                 body = this._renderPhaseVerified(); | ||||
|                 break; | ||||
|             case PHASE_CANCELLED: | ||||
|                 body = this._renderPhaseCancelled(); | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         const BaseDialog = sdk.getComponent("dialogs.BaseDialog"); | ||||
|         return ( | ||||
|             <BaseDialog | ||||
|                 title={_t("Incoming Verification Request")} | ||||
|                 onFinished={this._onFinished} | ||||
|             > | ||||
|                 {body} | ||||
|             </BaseDialog> | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -114,6 +114,8 @@ | |||
|     "Failed to invite": "Failed to invite", | ||||
|     "Failed to invite users to the room:": "Failed to invite users to the room:", | ||||
|     "Failed to invite the following users to the %(roomName)s room:": "Failed to invite the following users to the %(roomName)s room:", | ||||
|     "Waiting for %(userId)s to accept...": "Waiting for %(userId)s to accept...", | ||||
|     "Waiting for %(userId)s to confirm...": "Waiting for %(userId)s to confirm...", | ||||
|     "You need to be logged in.": "You need to be logged in.", | ||||
|     "You need to be able to invite users to do that.": "You need to be able to invite users to do that.", | ||||
|     "Unable to create widget.": "Unable to create widget.", | ||||
|  | @ -264,6 +266,7 @@ | |||
|     "Backup of encryption keys to server": "Backup of encryption keys to server", | ||||
|     "Render simple counters in room header": "Render simple counters in room header", | ||||
|     "Allow up to 6 rooms in a community to be shown simultaneously in a grid via the context menu": "Allow up to 6 rooms in a community to be shown simultaneously in a grid via the context menu", | ||||
|     "Two-way device verification using short text": "Two-way device verification using short text", | ||||
|     "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", | ||||
|     "Use compact timeline layout": "Use compact timeline layout", | ||||
|     "Hide removed messages": "Hide removed messages", | ||||
|  | @ -938,12 +941,22 @@ | |||
|     "Please forget all messages I have sent when my account is deactivated (<b>Warning:</b> this will cause future users to see an incomplete view of conversations)": "Please forget all messages I have sent when my account is deactivated (<b>Warning:</b> this will cause future users to see an incomplete view of conversations)", | ||||
|     "To continue, please enter your password:": "To continue, please enter your password:", | ||||
|     "password": "password", | ||||
|     "Verify device": "Verify device", | ||||
|     "Use Legacy Verification (for older clients)": "Use Legacy Verification (for older clients)", | ||||
|     "Do clicky clicky button press request verify user send to do.": "Do clicky clicky button press request verify user send to do.", | ||||
|     "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", | ||||
|     "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", | ||||
|     "Verification complete!": "Verification complete!", | ||||
|     "Done": "Done", | ||||
|     "%(userId)s cancelled the verification.": "%(userId)s cancelled the verification.", | ||||
|     "Use two-way text verification": "Use two-way text verification", | ||||
|     "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:", | ||||
|     "Device name": "Device name", | ||||
|     "Device key": "Device key", | ||||
|     "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.", | ||||
|     "In future this verification process will be more sophisticated.": "In future this verification process will be more sophisticated.", | ||||
|     "Verify device": "Verify device", | ||||
|     "I verify that the keys match": "I verify that the keys match", | ||||
|     "Back": "Back", | ||||
|     "Send Custom Event": "Send Custom Event", | ||||
|  | @ -960,6 +973,12 @@ | |||
|     "Toolbox": "Toolbox", | ||||
|     "Developer Tools": "Developer Tools", | ||||
|     "An error has occurred.": "An error has occurred.", | ||||
|     "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.", | ||||
|     "Verifying this user will mark their device as trusted, and also mark your device as trusted to them": "Verifying this user will mark their device as trusted, and also mark your device as trusted to them", | ||||
|     "Waiting for partner to confirm...": "Waiting for partner to confirm...", | ||||
|     "Verification Complete!": "Verification Complete!", | ||||
|     "The other party cancelled the verification.": "The other party cancelled the verification.", | ||||
|     "Incoming Verification Request": "Incoming Verification Request", | ||||
|     "You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.", | ||||
|     "Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.", | ||||
|     "Start verification": "Start verification", | ||||
|  |  | |||
|  | @ -114,6 +114,12 @@ export const SETTINGS = { | |||
|         supportedLevels: LEVELS_FEATURE, | ||||
|         default: false, | ||||
|     }, | ||||
|     "feature_sas": { | ||||
|         isFeature: true, | ||||
|         displayName: _td("Two-way device verification using short text"), | ||||
|         supportedLevels: LEVELS_FEATURE, | ||||
|         default: false, | ||||
|     }, | ||||
|     "MessageComposerInput.dontSuggestEmoji": { | ||||
|         supportedLevels: LEVELS_ACCOUNT_SETTINGS, | ||||
|         displayName: _td('Disable Emoji suggestions while typing'), | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 David Baker
						David Baker