diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index dbc570c872..450bec8e77 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -217,7 +217,7 @@ class _MatrixClientPeg { timelineSupport: true, forceTURN: !SettingsStore.getValue('webRtcAllowPeerToPeer', false), fallbackICEServerAllowed: !!SettingsStore.getValue('fallbackICEServerAllowed'), - verificationMethods: [verificationMethods.SAS], + verificationMethods: [verificationMethods.SAS, verificationMethods.QR_CODE_SHOW], unstableClientRelationAggregation: true, identityServer: new IdentityAuthClient(), }; diff --git a/src/components/views/elements/crypto/VerificationQRCode.js b/src/components/views/elements/crypto/VerificationQRCode.js new file mode 100644 index 0000000000..c49dd3faf5 --- /dev/null +++ b/src/components/views/elements/crypto/VerificationQRCode.js @@ -0,0 +1,59 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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 {replaceableComponent} from "../../../../utils/replaceableComponent"; +import * as qs from "qs"; +import QRCode from "qrcode-react"; + +@replaceableComponent("views.elements.crypto.VerificationQRCode") +export default class VerificationQRCode extends React.PureComponent { + static propTypes = { + // Common for all kinds of QR codes + keys: PropTypes.array.isRequired, // array of [Key ID, Key] pairs + action: PropTypes.string.isRequired, + keyholderUserId: PropTypes.string.isRequired, + + // User verification use case only + secret: PropTypes.string, + otherUserKey: PropTypes.string, + verificationKey: PropTypes.string, + verificationAlgorithms: PropTypes.array, + requestEventId: PropTypes.string, + }; + + static defaultProps = { + action: "verify", + }; + + render() { + const query = { + request: this.props.requestEventId, + action: this.props.action, + verification_algorithms: this.props.verificationAlgorithms, + verification_key: this.props.verificationKey, + other_user_key: this.props.otherUserKey, + }; + for (const key of this.props.keys) { + query[`key_${key[0]}`] = key[1]; + } + + const uri = `https://matrix.to/#/${this.props.keyholderUserId}?${qs.stringify(query)}`; + + return + } +} diff --git a/src/components/views/right_panel/VerificationPanel.js b/src/components/views/right_panel/VerificationPanel.js index 0d28e1568f..a2038087fc 100644 --- a/src/components/views/right_panel/VerificationPanel.js +++ b/src/components/views/right_panel/VerificationPanel.js @@ -17,6 +17,9 @@ limitations under the License. import React from 'react'; import * as sdk from '../../../index'; import {verificationMethods} from 'matrix-js-sdk/src/crypto'; +import VerificationQRCode from "../elements/crypto/VerificationQRCode"; +import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; +import {MatrixClientPeg} from "../../../MatrixClientPeg"; export default class VerificationPanel extends React.PureComponent { constructor(props) { @@ -36,15 +39,30 @@ export default class VerificationPanel extends React.PureComponent { renderStatus() { const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const Spinner = sdk.getComponent('elements.Spinner'); - const {request} = this.props; + const {request: req} = this.props; + const request: VerificationRequest = req; if (request.requested) { return (

Waiting for {request.otherUserId} to accept ...

); } else if (request.ready) { + const qrCodeKeys = [ + [MatrixClientPeg.get().getDeviceId(), MatrixClientPeg.get().getDeviceEd25519Key()], + [MatrixClientPeg.get().getCrossSigningId(), MatrixClientPeg.get().getCrossSigningKey("master")], + ]; + // TODO: Await a bunch of this + const otherCrossSigning = MatrixClientPeg.get().getStoredCrossSigningForUser(request.otherUserId); + const otherUserKey = otherCrossSigning ? otherCrossSigning.getCrossSigningKey("master") : null; + const qrCode = ; const verifyButton = Verify by emoji ; - return (

{request.otherUserId} is ready, start {verifyButton}

); + return (

{request.otherUserId} is ready, start {verifyButton} or have them scan: {qrCode}

); } else if (request.started) { if (this.state.sasWaitingForOtherParty) { return

Waiting for {request.otherUserId} to confirm ...

;