From cb0392b78d8e84cf9bfeb39b444936adb692deb6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 29 Jan 2020 13:24:45 +0000 Subject: [PATCH 001/268] use forms to wrap password fields so Chrome doesn't go wild and prefill all the things Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../CreateSecretStorageDialog.js | 75 +++++++++---------- src/components/structures/SearchBox.js | 1 + .../AccessSecretStorageDialog.js | 45 +++++------ 3 files changed, 57 insertions(+), 64 deletions(-) diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 4068f72217..35cd5aa819 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -295,31 +295,27 @@ export default class CreateSecretStorageDialog extends React.PureComponent { }); } - _onPassPhraseNextClick = () => { - this.setState({phase: PHASE_PASSPHRASE_CONFIRM}); - } - - _onPassPhraseKeyPress = async (e) => { - if (e.key === 'Enter') { - // If we're waiting for the timeout before updating the result at this point, - // skip ahead and do it now, otherwise we'll deny the attempt to proceed - // even if the user entered a valid passphrase - if (this._setZxcvbnResultTimeout !== null) { - clearTimeout(this._setZxcvbnResultTimeout); - this._setZxcvbnResultTimeout = null; - await new Promise((resolve) => { - this.setState({ - zxcvbnResult: scorePassword(this.state.passPhrase), - }, resolve); - }); - } - if (this._passPhraseIsValid()) { - this._onPassPhraseNextClick(); - } + _onPassPhraseNextClick = async () => { + // If we're waiting for the timeout before updating the result at this point, + // skip ahead and do it now, otherwise we'll deny the attempt to proceed + // even if the user entered a valid passphrase + if (this._setZxcvbnResultTimeout !== null) { + clearTimeout(this._setZxcvbnResultTimeout); + this._setZxcvbnResultTimeout = null; + await new Promise((resolve) => { + this.setState({ + zxcvbnResult: scorePassword(this.state.passPhrase), + }, resolve); + }); } - } + if (this._passPhraseIsValid()) { + this.setState({phase: PHASE_PASSPHRASE_CONFIRM}); + } + }; _onPassPhraseConfirmNextClick = async () => { + if (this.state.passPhrase !== this.state.passPhraseConfirm) return; + const [keyInfo, encodedRecoveryKey] = await MatrixClientPeg.get().createRecoveryKeyFromPassphrase(this.state.passPhrase); this._keyInfo = keyInfo; @@ -332,12 +328,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent { }); } - _onPassPhraseConfirmKeyPress = (e) => { - if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) { - this._onPassPhraseConfirmNextClick(); - } - } - _onSetAgainClick = () => { this.setState({ passPhrase: '', @@ -407,7 +397,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent { } else if (this.state.canUploadKeysWithPasswordOnly) { authPrompt =
{_t("Enter your account password to confirm the upgrade:")}
-
; } - return
+ return

{_t( "Set up encryption on this device to allow it to verify other devices, " + "granting them access to encrypted messages and marking them as trusted for other users.", @@ -480,13 +471,14 @@ export default class CreateSecretStorageDialog extends React.PureComponent { )}

-
{strengthMeter} @@ -499,10 +491,12 @@ export default class CreateSecretStorageDialog extends React.PureComponent { onChange={this._onUseKeyBackupChange} value={this.state.useKeyBackup} /> -
; + ; } _renderPhasePassPhraseConfirm() { @@ -549,27 +543,30 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
; } const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - return
+ return

{_t( "Enter your passphrase a second time to confirm it.", )}

-
{passPhraseMatch}
- -
; + ; } _renderPhaseShowKey() { diff --git a/src/components/structures/SearchBox.js b/src/components/structures/SearchBox.js index 873efb64c2..e169e09752 100644 --- a/src/components/structures/SearchBox.js +++ b/src/components/structures/SearchBox.js @@ -160,6 +160,7 @@ export default createReactClass({ onKeyDown={ this._onKeyDown } onBlur={this._onBlur} placeholder={ placeholder } + autoComplete="off" /> { clearButton }
diff --git a/src/components/views/dialogs/secretstorage/AccessSecretStorageDialog.js b/src/components/views/dialogs/secretstorage/AccessSecretStorageDialog.js index c976eb81d0..ed65c9d2a6 100644 --- a/src/components/views/dialogs/secretstorage/AccessSecretStorageDialog.js +++ b/src/components/views/dialogs/secretstorage/AccessSecretStorageDialog.js @@ -1,6 +1,6 @@ /* Copyright 2018, 2019 New Vector Ltd -Copyright 2019 The Matrix.org Foundation C.I.C. +Copyright 2019, 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. @@ -21,7 +21,6 @@ import * as sdk from '../../../../index'; import {MatrixClientPeg} from '../../../../MatrixClientPeg'; import { _t } from '../../../../languageHandler'; -import { Key } from "../../../../Keyboard"; /* * Access Secure Secret Storage by requesting the user's passphrase. @@ -69,6 +68,8 @@ export default class AccessSecretStorageDialog extends React.PureComponent { } _onPassPhraseNext = async () => { + if (this.state.passPhrase.length <= 0) return; + this.setState({ keyMatches: null }); const input = { passphrase: this.state.passPhrase }; const keyMatches = await this.props.checkPrivateKey(input); @@ -80,6 +81,8 @@ export default class AccessSecretStorageDialog extends React.PureComponent { } _onRecoveryKeyNext = async () => { + if (!this.state.recoveryKeyValid) return; + this.setState({ keyMatches: null }); const input = { recoveryKey: this.state.recoveryKey }; const keyMatches = await this.props.checkPrivateKey(input); @@ -97,18 +100,6 @@ export default class AccessSecretStorageDialog extends React.PureComponent { }); } - _onPassPhraseKeyPress = (e) => { - if (e.key === Key.ENTER && this.state.passPhrase.length > 0) { - this._onPassPhraseNext(); - } - } - - _onRecoveryKeyKeyPress = (e) => { - if (e.key === Key.ENTER && this.state.recoveryKeyValid) { - this._onRecoveryKeyNext(); - } - } - render() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); @@ -135,7 +126,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent { )}
; } else { - keyStatus =
; + keyStatus =
; } content =
@@ -149,23 +140,26 @@ export default class AccessSecretStorageDialog extends React.PureComponent { "identity for verifying other devices by entering your passphrase.", )}

-
- + {keyStatus} - -
+ {_t( "If you've forgotten your passphrase you can "+ "use your recovery key or " + @@ -192,7 +186,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent { let keyStatus; if (this.state.recoveryKey.length === 0) { - keyStatus =
; + keyStatus =
; } else if (this.state.recoveryKeyValid) { keyStatus =
{"\uD83D\uDC4D "}{_t("This looks like a valid recovery key!")} @@ -221,22 +215,23 @@ export default class AccessSecretStorageDialog extends React.PureComponent { "identity for verifying other devices by entering your recovery key.", )}

-
+
{keyStatus} - -
+ {_t( "If you've forgotten your recovery key you can "+ "." From fe71fe6033a59e0dcc20c62527ad5b7ec7f71895 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 29 Jan 2020 13:38:50 +0000 Subject: [PATCH 002/268] Sprinkle forms and new-password designators to make autofill and password completion less wild Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../keybackup/CreateKeyBackupDialog.js | 66 ++++++++----------- src/components/views/auth/RegistrationForm.js | 2 + .../views/dialogs/DeactivateAccountDialog.js | 1 + .../keybackup/RestoreKeyBackupDialog.js | 15 ++--- .../views/settings/ChangePassword.js | 8 ++- 5 files changed, 43 insertions(+), 49 deletions(-) diff --git a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js index 8940239cfd..1557159e5c 100644 --- a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js +++ b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js @@ -192,31 +192,27 @@ export default class CreateKeyBackupDialog extends React.PureComponent { }); } - _onPassPhraseNextClick = () => { - this.setState({phase: PHASE_PASSPHRASE_CONFIRM}); - } - - _onPassPhraseKeyPress = async (e) => { - if (e.key === 'Enter') { - // If we're waiting for the timeout before updating the result at this point, - // skip ahead and do it now, otherwise we'll deny the attempt to proceed - // even if the user entered a valid passphrase - if (this._setZxcvbnResultTimeout !== null) { - clearTimeout(this._setZxcvbnResultTimeout); - this._setZxcvbnResultTimeout = null; - await new Promise((resolve) => { - this.setState({ - zxcvbnResult: scorePassword(this.state.passPhrase), - }, resolve); - }); - } - if (this._passPhraseIsValid()) { - this._onPassPhraseNextClick(); - } + _onPassPhraseNextClick = async () => { + // If we're waiting for the timeout before updating the result at this point, + // skip ahead and do it now, otherwise we'll deny the attempt to proceed + // even if the user entered a valid passphrase + if (this._setZxcvbnResultTimeout !== null) { + clearTimeout(this._setZxcvbnResultTimeout); + this._setZxcvbnResultTimeout = null; + await new Promise((resolve) => { + this.setState({ + zxcvbnResult: scorePassword(this.state.passPhrase), + }, resolve); + }); } - } + if (this._passPhraseIsValid()) { + this.setState({phase: PHASE_PASSPHRASE_CONFIRM}); + } + }; _onPassPhraseConfirmNextClick = async () => { + if (this.state.passPhrase !== this.state.passPhraseConfirm) return; + this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase); this.setState({ setPassPhrase: true, @@ -224,13 +220,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent { downloaded: false, phase: PHASE_SHOWKEY, }); - } - - _onPassPhraseConfirmKeyPress = (e) => { - if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) { - this._onPassPhraseConfirmNextClick(); - } - } + }; _onSetAgainClick = () => { this.setState({ @@ -301,7 +291,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
; } - return
+ return

{_t( "Warning: You should only set up key backup from a trusted computer.", {}, { b: sub => {sub} }, @@ -316,7 +306,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {

- @@ -341,7 +332,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent { {_t("Set up with a Recovery Key")}

-
; + ; } _renderPhasePassPhraseConfirm() { @@ -373,7 +364,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
; } const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - return
+ return

{_t( "Please enter your passphrase a second time to confirm.", )}

@@ -382,7 +373,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
- -
; + ; } _renderPhaseShowKey() { diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index 91f8e1b226..8ca454dabd 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -486,6 +486,7 @@ export default createReactClass({ id="mx_RegistrationForm_password" ref={field => this[FIELD_PASSWORD] = field} type="password" + autoComplete="new-password" label={_t("Password")} value={this.state.password} onChange={this.onPasswordChange} @@ -499,6 +500,7 @@ export default createReactClass({ id="mx_RegistrationForm_passwordConfirm" ref={field => this[FIELD_PASSWORD_CONFIRM] = field} type="password" + autoComplete="new-password" label={_t("Confirm")} value={this.state.passwordConfirm} onChange={this.onPasswordConfirmChange} diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index 7e36232eb0..d7468933df 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -118,6 +118,7 @@ export default class DeactivateAccountDialog extends React.Component { const Field = sdk.getComponent('elements.Field'); + // this is on purpose not a
to prevent Enter triggering submission, to further prevent accidents return ( { - if (e.key === Key.ENTER) { - this._onPassPhraseNext(); - } - } - _onRecoveryKeyKeyPress = (e) => { if (e.key === Key.ENTER && this.state.recoveryKeyValid) { this._onRecoveryKeyNext(); @@ -305,21 +299,22 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { "messaging by entering your recovery passphrase.", )}

-
+ - -
+ {_t( "If you've forgotten your recovery passphrase you can "+ "use your recovery key or " + diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 2d8c4c4178..8cbe455af3 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -253,20 +253,24 @@ export default createReactClass({
{ currentPassword }
-
-
From 920daa3125c229697a25daa65788d909839c71e1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 29 Jan 2020 13:43:08 +0000 Subject: [PATCH 003/268] Get rid of custom enter handling and protect handlers, disabling button isn't foolproof Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/dialogs/keybackup/RestoreKeyBackupDialog.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js b/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js index 814f5a4980..fc9a21c51b 100644 --- a/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js +++ b/src/components/views/dialogs/keybackup/RestoreKeyBackupDialog.js @@ -22,7 +22,6 @@ import {MatrixClientPeg} from '../../../../MatrixClientPeg'; import { MatrixClient } from 'matrix-js-sdk'; import Modal from '../../../../Modal'; import { _t } from '../../../../languageHandler'; -import {Key} from "../../../../Keyboard"; import { accessSecretStorage } from '../../../../CrossSigningManager'; const RESTORE_TYPE_PASSPHRASE = 0; @@ -125,6 +124,8 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { } _onRecoveryKeyNext = async () => { + if (!this.state.recoveryKeyValid) return; + this.setState({ loading: true, restoreError: null, @@ -157,12 +158,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { }); } - _onRecoveryKeyKeyPress = (e) => { - if (e.key === Key.ENTER && this.state.recoveryKeyValid) { - this._onRecoveryKeyNext(); - } - } - async _restoreWithSecretStorage() { this.setState({ loading: true, @@ -366,7 +361,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
From 724cff6a2e889aa62b45790a839408476ea436c7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 30 Jan 2020 16:55:43 +0000 Subject: [PATCH 004/268] Update QR code rendering to support VerificationRequests Makes for building the QR code easier and more common. --- .../elements/crypto/VerificationQRCode.js | 73 ++++++++++++++++++- .../views/right_panel/VerificationPanel.js | 38 +++++----- 2 files changed, 89 insertions(+), 22 deletions(-) diff --git a/src/components/views/elements/crypto/VerificationQRCode.js b/src/components/views/elements/crypto/VerificationQRCode.js index 630a06a07c..f9fea2dc78 100644 --- a/src/components/views/elements/crypto/VerificationQRCode.js +++ b/src/components/views/elements/crypto/VerificationQRCode.js @@ -19,6 +19,9 @@ import PropTypes from "prop-types"; import {replaceableComponent} from "../../../../utils/replaceableComponent"; import * as qs from "qs"; import QRCode from "qrcode-react"; +import {MatrixClientPeg} from "../../../../MatrixClientPeg"; +import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; +import {ToDeviceChannel} from "matrix-js-sdk/src/crypto/verification/request/ToDeviceChannel"; @replaceableComponent("views.elements.crypto.VerificationQRCode") export default class VerificationQRCode extends React.PureComponent { @@ -31,13 +34,81 @@ export default class VerificationQRCode extends React.PureComponent { // User verification use case only secret: PropTypes.string, otherUserKey: PropTypes.string, // Base64 key being verified - requestEventId: PropTypes.string, + otherUserDeviceKey: PropTypes.string, // Base64 key of the other user's device (optional) + requestEventId: PropTypes.string, // for DM verification only }; static defaultProps = { action: "verify", }; + static async getPropsForRequest(verificationRequest: VerificationRequest) { + const cli = MatrixClientPeg.get(); + const myUserId = cli.getUserId(); + const otherUserId = verificationRequest.otherUserId; + const myDeviceId = cli.getDeviceId(); + const otherDevice = verificationRequest.estimatedTargetDevice; + const otherDeviceId = otherDevice ? otherDevice.deviceId : null; + + const qrProps = { + secret: verificationRequest.encodedSharedSecret, + keyholderUserId: myUserId, + action: "verify", + keys: [], // array of pairs: keyId, base64Key + otherUserKey: "", // base64key + otherUserDeviceKey: "", // base64key + requestEventId: "", // we figure this out in a moment + }; + + const requestEvent = verificationRequest.requestEvent; + qrProps.requestEventId = requestEvent.getId() + ? requestEvent.getId() + : ToDeviceChannel.getTransactionId(requestEvent); + + // Populate the keys we need depending on which direction and users are involved in the verification. + if (myUserId === otherUserId) { + if (!otherDeviceId) { + // New -> Existing session QR code + qrProps.otherUserDeviceKey = null; + } else { + // Existing -> New session QR code + const myDevices = (await cli.getStoredDevicesForUser(myUserId)) || []; + const device = myDevices.find(d => d.deviceId === otherDeviceId); + if (device) qrProps.otherUserDeviceKey = device.getFingerprint(); + } + + // Either direction shares these next few props + + const xsignInfo = cli.getStoredCrossSigningForUser(myUserId); + qrProps.otherUserKey = xsignInfo.getId("master"); + + qrProps.keys = [ + [myDeviceId, cli.getDeviceEd25519Key()], + [xsignInfo.getId("master"), xsignInfo.getId("master")], + ]; + } else { + // Doesn't matter which direction the verification is, we always show the same QR code + // for not-ourself verification. + const myXsignInfo = cli.getStoredCrossSigningForUser(myUserId); + const otherXsignInfo = cli.getStoredCrossSigningForUser(otherUserId); + const otherDevices = (await cli.getStoredDevicesForUser(otherUserId)) || []; + const otherDevice = otherDevices.find(d => d.deviceId === otherDeviceId); + + qrProps.keys = [ + [myDeviceId, cli.getDeviceEd25519Key()], + [myXsignInfo.getId("master"), myXsignInfo.getId("master")], + ]; + qrProps.otherUserKey = otherXsignInfo.getId("master"); + if (otherDevice) qrProps.otherUserDeviceKey = otherDevice.getFingerprint(); + } + + return qrProps; + } + + constructor(props) { + super(props); + } + render() { const query = { request: this.props.requestEventId, diff --git a/src/components/views/right_panel/VerificationPanel.js b/src/components/views/right_panel/VerificationPanel.js index 3527747a66..ad1aaf598c 100644 --- a/src/components/views/right_panel/VerificationPanel.js +++ b/src/components/views/right_panel/VerificationPanel.js @@ -20,7 +20,6 @@ import PropTypes from "prop-types"; import * as sdk from '../../../index'; import {verificationMethods} from 'matrix-js-sdk/src/crypto'; import VerificationQRCode from "../elements/crypto/VerificationQRCode"; -import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {_t} from "../../../languageHandler"; import E2EIcon from "../rooms/E2EIcon"; import { @@ -29,7 +28,7 @@ import { PHASE_READY, PHASE_DONE, PHASE_STARTED, - PHASE_CANCELLED, + PHASE_CANCELLED, VerificationRequest, } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; import Spinner from "../elements/Spinner"; @@ -50,12 +49,24 @@ export default class VerificationPanel extends React.PureComponent { constructor(props) { super(props); - this.state = {}; + this.state = { + qrCodeProps: null, // generated by the VerificationQRCode component itself + }; this._hasVerifier = false; + this._generateQRCodeProps(props.request); + } + + async _generateQRCodeProps(verificationRequest: VerificationRequest) { + try { + this.setState({qrCodeProps: await VerificationQRCode.getPropsForRequest(verificationRequest)}); + } catch (e) { + console.error(e); + // Do nothing - we won't render a QR code. + } } renderQRPhase(pending) { - const {member, request} = this.props; + const {member} = this.props; const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); let button; @@ -69,10 +80,7 @@ export default class VerificationPanel extends React.PureComponent { ); } - const cli = MatrixClientPeg.get(); - const crossSigningInfo = cli.getStoredCrossSigningForUser(request.otherUserId); - if (!crossSigningInfo || !request.requestEvent || !request.requestEvent.getId()) { - // for whatever reason we can't generate a QR code, offer only SAS Verification + if (!this.state.qrCodeProps) { return

Verify by emoji

{_t("Verify by comparing unique emoji.")}

@@ -81,12 +89,6 @@ export default class VerificationPanel extends React.PureComponent {
; } - const myKeyId = cli.getCrossSigningId(); - const qrCodeKeys = [ - [cli.getDeviceId(), cli.getDeviceEd25519Key()], - [myKeyId, myKeyId], - ]; - // TODO: add way to open camera to scan a QR code return
@@ -96,13 +98,7 @@ export default class VerificationPanel extends React.PureComponent { })}

- +
From bf9f473ed9689b822263a650aeed1f9e2796b3ab Mon Sep 17 00:00:00 2001 From: Stasiek Michalski Date: Fri, 31 Jan 2020 00:09:08 +0100 Subject: [PATCH 005/268] Add a class for styling room directory permissions Fixes vector-im/riot-web#11174 --- res/css/structures/_RoomDirectory.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/res/css/structures/_RoomDirectory.scss b/res/css/structures/_RoomDirectory.scss index 4b49332af7..5ae8df7176 100644 --- a/res/css/structures/_RoomDirectory.scss +++ b/res/css/structures/_RoomDirectory.scss @@ -119,6 +119,16 @@ limitations under the License. display: inline-block; } +.mx_RoomDirectory_perm { + border-radius: 10px; + display: inline-block; + height: 20px; + line-height: 20px; + padding: 0 5px; + color: $accent-fg-color; + background-color: $rte-room-pill-color; +} + .mx_RoomDirectory_topic { cursor: initial; color: $light-fg-color; From fde30577e4b370cf952338f058085ef65ef54972 Mon Sep 17 00:00:00 2001 From: BobVul Date: Fri, 31 Jan 2020 12:33:10 +1100 Subject: [PATCH 006/268] Fix escaped markdown passing backslashes through Fixes https://github.com/vector-im/riot-web/issues/11230 Signed-off-by: Bob Rao --- src/editor/serialize.js | 4 ++++ test/editor/serialize-test.js | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/editor/serialize.js b/src/editor/serialize.js index ba380f2809..075c462b37 100644 --- a/src/editor/serialize.js +++ b/src/editor/serialize.js @@ -41,6 +41,10 @@ export function htmlSerializeIfNeeded(model, {forceHTML = false} = {}) { if (!parser.isPlainText() || forceHTML) { return parser.toHTML(); } + // Format "plain" text to ensure removal of backslash escapes + // https://github.com/vector-im/riot-web/issues/11230 + // https://github.com/vector-im/riot-web/issues/2870 + return parser.toPlaintext(); } export function textSerialize(model) { diff --git a/test/editor/serialize-test.js b/test/editor/serialize-test.js index 7517e46437..f846e0d79e 100644 --- a/test/editor/serialize-test.js +++ b/test/editor/serialize-test.js @@ -43,4 +43,10 @@ describe('editor/serialize', function() { const html = htmlSerializeIfNeeded(model, {}); expect(html).toBe("hello world"); }); + it('escaped markdown should not retain backslashes', function() { + const pc = createPartCreator(); + const model = new EditorModel([pc.plain('\\*hello\\* world')]); + const html = htmlSerializeIfNeeded(model, {}); + expect(html).toBe('*hello* world'); + }) }); From 9cf53aa9d89986139c5ea4b7a9447281b882d981 Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 2 Feb 2020 16:34:19 +1100 Subject: [PATCH 007/268] Only return formatted text when necessary (for escaped chars) Signed-off-by: Bob Rao --- src/editor/serialize.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/editor/serialize.js b/src/editor/serialize.js index 075c462b37..03f3759ea0 100644 --- a/src/editor/serialize.js +++ b/src/editor/serialize.js @@ -44,7 +44,11 @@ export function htmlSerializeIfNeeded(model, {forceHTML = false} = {}) { // Format "plain" text to ensure removal of backslash escapes // https://github.com/vector-im/riot-web/issues/11230 // https://github.com/vector-im/riot-web/issues/2870 - return parser.toPlaintext(); + const postParsePlaintext = parser.toPlaintext(); + if (postParsePlaintext !== md) { + // only return "formatted" text if it differs from the source text + return postParsePlaintext; + } } export function textSerialize(model) { From aa52118fa1b81bad21fa1fd9ba5a8928ce36cf9b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Feb 2020 17:31:06 +0100 Subject: [PATCH 008/268] the width was not properly set to other languages than english, a min-width will keep the proper size of the button while leaving some room for more word expensive languages such as french --- res/css/views/dialogs/_InviteDialog.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/views/dialogs/_InviteDialog.scss b/res/css/views/dialogs/_InviteDialog.scss index 71fab50339..5e0893b8fd 100644 --- a/res/css/views/dialogs/_InviteDialog.scss +++ b/res/css/views/dialogs/_InviteDialog.scss @@ -62,7 +62,7 @@ limitations under the License. } .mx_InviteDialog_goButton { - width: 48px; + min-width: 48px; margin-left: 10px; height: 25px; line-height: 25px; @@ -131,7 +131,7 @@ limitations under the License. height: 24px; grid-column: 1; grid-row: 1; - mask-image: url('$(res)/img/feather-customised/check.svg'); + mask-image: url("$(res)/img/feather-customised/check.svg"); mask-size: 100%; mask-repeat: no-repeat; position: absolute; From 20fc8514a5270db4167cb707bb7a730e7c01551e Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Feb 2020 18:47:16 +0100 Subject: [PATCH 009/268] I have added spacing, as devices are very hard to read otherwise --- res/css/views/settings/_DevicesPanel.scss | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/res/css/views/settings/_DevicesPanel.scss b/res/css/views/settings/_DevicesPanel.scss index 581ff47fc1..49debe842f 100644 --- a/res/css/views/settings/_DevicesPanel.scss +++ b/res/css/views/settings/_DevicesPanel.scss @@ -18,7 +18,7 @@ limitations under the License. display: table; table-layout: fixed; width: 880px; - border-spacing: 2px; + border-spacing: 10px; } .mx_DevicesPanel_header { @@ -32,7 +32,11 @@ limitations under the License. .mx_DevicesPanel_header > div { display: table-cell; - vertical-align: bottom; + vertical-align: middle; +} + +.mx_DevicesPanel_header .mx_DevicesPanel_deviceName { + width: 50%; } .mx_DevicesPanel_header .mx_DevicesPanel_deviceLastSeen { From 41f4b38fe8a3f9a8bd2b5e12b591ec218e5ecbb4 Mon Sep 17 00:00:00 2001 From: Zoe Date: Mon, 3 Feb 2020 16:51:36 +0000 Subject: [PATCH 010/268] Do not show alarming red shields on large encrypted rooms for your own device Fixes: https://github.com/vector-im/riot-web/issues/12214 --- src/components/structures/RoomView.js | 4 +++- src/components/views/rooms/RoomTile.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 24eaa7a410..acc87d9616 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -811,7 +811,9 @@ export default createReactClass({ debuglog("e2e verified", verified, "unverified", unverified); /* Check all verified user devices. */ - for (const userId of [...verified, cli.getUserId()]) { + /* Don't alarm if no other users are verified */ + const targets = (verified.length > 0) ? [...verified, cli.getUserId()] : verified; + for (const userId of targets) { const devices = await cli.getStoredDevicesForUser(userId); const anyDeviceNotVerified = devices.some(({deviceId}) => { return !cli.checkDeviceTrust(userId, deviceId).isVerified(); diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index 41d43476ea..393ed0976f 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -166,7 +166,9 @@ export default createReactClass({ }); /* Check all verified user devices. */ - for (const userId of [...verified, cli.getUserId()]) { + /* Don't alarm if no other users are verified */ + const targets = (verified.length > 0) ? [...verified, cli.getUserId()] : verified; + for (const userId of targets) { const devices = await cli.getStoredDevicesForUser(userId); const allDevicesVerified = devices.every(({deviceId}) => { return cli.checkDeviceTrust(userId, deviceId).isVerified(); From 1df6837649e31dcde0f72458e4568f2331ea126e Mon Sep 17 00:00:00 2001 From: BobVul Date: Tue, 4 Feb 2020 10:38:43 +1100 Subject: [PATCH 011/268] Missing semicolon --- test/editor/serialize-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/editor/serialize-test.js b/test/editor/serialize-test.js index f846e0d79e..9d116cdc4b 100644 --- a/test/editor/serialize-test.js +++ b/test/editor/serialize-test.js @@ -48,5 +48,5 @@ describe('editor/serialize', function() { const model = new EditorModel([pc.plain('\\*hello\\* world')]); const html = htmlSerializeIfNeeded(model, {}); expect(html).toBe('*hello* world'); - }) + }); }); From e23a3e98be1693a060623d219f3330972b605fd8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 4 Feb 2020 15:27:38 +0000 Subject: [PATCH 012/268] Only enumerate settings handlers which are supported currently --- src/settings/SettingsStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/SettingsStore.js b/src/settings/SettingsStore.js index b1d61197a0..a65137631d 100644 --- a/src/settings/SettingsStore.js +++ b/src/settings/SettingsStore.js @@ -564,7 +564,7 @@ export default class SettingsStore { const handlers = {}; for (const level of SETTINGS[settingName].supportedLevels) { if (!LEVEL_HANDLERS[level]) throw new Error("Unexpected level " + level); - handlers[level] = LEVEL_HANDLERS[level]; + if (SettingsStore.isLevelSupported(level)) handlers[level] = LEVEL_HANDLERS[level]; } // Always support 'default' From b92fe594369c3dffad51d2a20af188d222897f95 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 4 Feb 2020 00:01:58 +0000 Subject: [PATCH 013/268] Improve event indexing status strings for translation The strings used for the count of rooms was hard to translate, so this adds a bit more context. --- .../views/dialogs/eventindex/ManageEventIndexDialog.js | 6 ++++-- src/i18n/strings/en_EN.json | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js index b98fecf22f..5ae90b694e 100644 --- a/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js +++ b/src/async-components/views/dialogs/eventindex/ManageEventIndexDialog.js @@ -144,8 +144,10 @@ export default class ManageEventIndexDialog extends React.Component {
{_t("Space used:")} {formatBytes(this.state.eventIndexSize, 0)}
{_t("Indexed messages:")} {formatCountLong(this.state.eventCount)}
- {_t("Number of rooms:")} {formatCountLong(this.state.crawlingRoomsCount)} {_t("of ")} - {formatCountLong(this.state.roomCount)}
+ {_t("Indexed rooms:")} {_t("%(crawlingRooms)s out of %(totalRooms)s", { + crawlingRooms: formatCountLong(this.state.crawlingRoomsCount), + totalRooms: formatCountLong(this.state.roomCount), + })}
{crawlerState}
Date: Tue, 4 Feb 2020 23:13:55 +0000 Subject: [PATCH 014/268] Fix listener removal in verification tile Fixes https://github.com/matrix-org/riot-web-rageshakes/issues/2202 --- src/components/views/messages/MKeyVerificationConclusion.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/views/messages/MKeyVerificationConclusion.js b/src/components/views/messages/MKeyVerificationConclusion.js index 76370ba148..ececfc60ed 100644 --- a/src/components/views/messages/MKeyVerificationConclusion.js +++ b/src/components/views/messages/MKeyVerificationConclusion.js @@ -40,7 +40,10 @@ export default class MKeyVerificationConclusion extends React.Component { if (request) { request.off("change", this._onRequestChanged); } - MatrixClientPeg.removeListener("userTrustStatusChanged", this._onTrustChanged); + const cli = MatrixClientPeg.get(); + if (cli) { + cli.removeListener("userTrustStatusChanged", this._onTrustChanged); + } } _onRequestChanged = () => { From a0c2a39dc7d2f4984855306c5711fb65d22fc72b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 3 Feb 2020 17:59:13 +0100 Subject: [PATCH 015/268] make a static dialog close again if background is clicked --- src/Modal.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index b6215b2b5a..54e56edd72 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -217,9 +217,13 @@ class ModalManager { } closeAll() { - const modalsToClose = [...this._modals, this._priorityModal]; + const modalsToClose = this._modals.slice(); this._modals = []; - this._priorityModal = null; + + if (this._priorityModal) { + modalsToClose.push(this._priorityModal); + this._priorityModal = null; + } if (this._staticModal && modalsToClose.length === 0) { modalsToClose.push(this._staticModal); From b522d785330550404fc6e12f4f9292eacc68f0e4 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 5 Feb 2020 12:43:39 +0000 Subject: [PATCH 016/268] Let pointer events fall through to scroll button This makes it easier to click the entire visible area of the scroll button, including the green circle at the top. --- res/css/views/rooms/_TopUnreadMessagesBar.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_TopUnreadMessagesBar.scss b/res/css/views/rooms/_TopUnreadMessagesBar.scss index 505af9691d..a3916f321a 100644 --- a/res/css/views/rooms/_TopUnreadMessagesBar.scss +++ b/res/css/views/rooms/_TopUnreadMessagesBar.scss @@ -32,9 +32,9 @@ limitations under the License. width: 4px; height: 4px; border-radius: 16px; - overflow: hidden; background-color: $secondary-accent-color; border: 6px solid $accent-color; + pointer-events: none; } .mx_TopUnreadMessagesBar_scrollUp { From 7e07a42dc14594e640598ae4613e87e61b9e3155 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 6 Feb 2020 13:07:13 +0100 Subject: [PATCH 017/268] resolve finished promise when closing dialog by clicking background ... by calling the same close method as otherwise and not have a special path that just calls the onFinished callback. This will also not close all the dialogs anymore, but that sort of seems like the intented behaviour? --- src/Modal.js | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 54e56edd72..33c3140ff1 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -47,7 +47,7 @@ class ModalManager { } */ ]; - this.closeAll = this.closeAll.bind(this); + this.onBackgroundClick = this.onBackgroundClick.bind(this); } hasDialogs() { @@ -124,6 +124,7 @@ class ModalManager { ); modal.onFinished = props ? props.onFinished : null; modal.className = className; + modal.close = closeDialog; return {modal, closeDialog, onFinishedProm}; } @@ -216,28 +217,16 @@ class ModalManager { }; } - closeAll() { - const modalsToClose = this._modals.slice(); - this._modals = []; - - if (this._priorityModal) { - modalsToClose.push(this._priorityModal); - this._priorityModal = null; + onBackgroundClick() { + const modal = this._getCurrentModal(); + if (!modal) { + return; } + modal.close(); + } - if (this._staticModal && modalsToClose.length === 0) { - modalsToClose.push(this._staticModal); - this._staticModal = null; - } - - for (let i = 0; i < modalsToClose.length; i++) { - const m = modalsToClose[i]; - if (m && m.onFinished) { - m.onFinished(false); - } - } - - this._reRender(); + _getCurrentModal() { + return this._priorityModal ? this._priorityModal : (this._modals[0] || this._staticModal); } _reRender() { @@ -268,7 +257,7 @@ class ModalManager {
{ this._staticModal.elem }
-
+
); @@ -278,8 +267,8 @@ class ModalManager { ReactDOM.unmountComponentAtNode(this.getOrCreateStaticContainer()); } - const modal = this._priorityModal ? this._priorityModal : this._modals[0]; - if (modal) { + const modal = this._getCurrentModal(); + if (modal !== this._staticModal) { const classes = "mx_Dialog_wrapper " + (this._staticModal ? "mx_Dialog_wrapperWithStaticUnder " : '') + (modal.className ? modal.className : ''); @@ -289,7 +278,7 @@ class ModalManager {
{modal.elem}
-
+
); From c44ebef06f3298e5abc34cb453a27ddf7ae26287 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 6 Feb 2020 13:10:06 +0100 Subject: [PATCH 018/268] add onBeforeClose option to Modal so we can throw up another "are you sure" dialog in the cases we want to do so. This also passes a reason so we can only do so for ways of dismissing (like backgroundClick) that are easy to do by accident. --- src/Modal.js | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 33c3140ff1..2e5624aa67 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -106,7 +106,7 @@ class ModalManager { return this.appendDialogAsync(...rest); } - _buildModal(prom, props, className) { + _buildModal(prom, props, className, options) { const modal = {}; // never call this from onFinished() otherwise it will loop @@ -124,14 +124,27 @@ class ModalManager { ); modal.onFinished = props ? props.onFinished : null; modal.className = className; + modal.onBeforeClose = options.onBeforeClose; + modal.beforeClosePromise = null; modal.close = closeDialog; + modal.closeReason = null; return {modal, closeDialog, onFinishedProm}; } _getCloseFn(modal, props) { const deferred = defer(); - return [(...args) => { + return [async (...args) => { + if (modal.beforeClosePromise) { + await modal.beforeClosePromise; + } else if (modal.onBeforeClose) { + modal.beforeClosePromise = modal.onBeforeClose(modal.closeReason); + const shouldClose = await modal.beforeClosePromise; + modal.beforeClosePromise = null; + if (!shouldClose) { + return; + } + } deferred.resolve(args); if (props && props.onFinished) props.onFinished.apply(null, args); const i = this._modals.indexOf(modal); @@ -186,9 +199,9 @@ class ModalManager { * static at a time. * @returns {object} Object with 'close' parameter being a function that will close the dialog */ - createDialogAsync(prom, props, className, isPriorityModal, isStaticModal) { - const {modal, closeDialog, onFinishedProm} = this._buildModal(prom, props, className); - + createDialogAsync(prom, props, className, isPriorityModal, isStaticModal, options = {}) { + const {modal, closeDialog, onFinishedProm} = this._buildModal(prom, props, className, options); + modal.close = closeDialog; if (isPriorityModal) { // XXX: This is destructive this._priorityModal = modal; @@ -207,7 +220,7 @@ class ModalManager { } appendDialogAsync(prom, props, className) { - const {modal, closeDialog, onFinishedProm} = this._buildModal(prom, props, className); + const {modal, closeDialog, onFinishedProm} = this._buildModal(prom, props, className, {}); this._modals.push(modal); this._reRender(); @@ -222,7 +235,13 @@ class ModalManager { if (!modal) { return; } + // we want to pass a reason to the onBeforeClose + // callback, but close is currently defined to + // pass all number of arguments to the onFinished callback + // so, pass the reason to close through a member variable + modal.closeReason = "backgroundClick"; modal.close(); + modal.closeReason = null; } _getCurrentModal() { From 70a4d3415eae1356fc3d3228a5a5d9e054264b4e Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 6 Feb 2020 13:11:24 +0100 Subject: [PATCH 019/268] confirm to close the passphrase dialog if it was done by backgroundClick as it is easy to do by accident --- src/CrossSigningManager.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index a560c956f1..8feb651ea5 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -70,6 +70,7 @@ async function getSecretStorageKey({ keys: keyInfos }) { sdk.getComponent("dialogs.secretstorage.AccessSecretStorageDialog"); const { finished } = Modal.createTrackedDialog("Access Secret Storage dialog", "", AccessSecretStorageDialog, + /* props= */ { keyInfo: info, checkPrivateKey: async (input) => { @@ -77,6 +78,22 @@ async function getSecretStorageKey({ keys: keyInfos }) { return MatrixClientPeg.get().checkSecretStoragePrivateKey(key, info.pubkey); }, }, + /* className= */ null, + /* isPriorityModal= */ false, + /* isStaticModal= */ false, + /* options= */ { + onBeforeClose: async (reason) => { + if (reason !== "backgroundClick") { + return true; + } + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const [sure] = await Modal.createDialog(QuestionDialog, { + title: _t("Cancel entering passphrase?"), + description: _t("If you cancel now, you won't complete your SSSS operation!"), + }).finished; + return sure; + }, + }, ); const [input] = await finished; if (!input) { From 4cd4110a52d867c4e22bf1ef87f7b43a1f97edd4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 6 Feb 2020 13:13:37 +0100 Subject: [PATCH 020/268] fixup: this is already done in _buildModal --- src/Modal.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Modal.js b/src/Modal.js index 2e5624aa67..f55e497e6f 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -201,7 +201,6 @@ class ModalManager { */ createDialogAsync(prom, props, className, isPriorityModal, isStaticModal, options = {}) { const {modal, closeDialog, onFinishedProm} = this._buildModal(prom, props, className, options); - modal.close = closeDialog; if (isPriorityModal) { // XXX: This is destructive this._priorityModal = modal; From 5b04ad46e0ff77515b56dcaace8c9ccc34a88dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanislav=20Luke=C5=A1?= Date: Thu, 6 Feb 2020 10:29:28 +0000 Subject: [PATCH 021/268] Translated using Weblate (Czech) Currently translated at 94.7% (1990 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 155 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 66af5b931e..3adc393e0a 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -1419,7 +1419,7 @@ "View Servers in Room": "Zobrazit servery v místnosti", "Sign out and remove encryption keys?": "Odhlásit a odstranit šifrovací klíče?", "To help us prevent this in future, please send us logs.": "Abychom tomu mohli pro příště předejít, pošlete nám prosím logy.", - "Missing session data": "Chybějící data sezení", + "Missing session data": "Chybějící data relace", "Some session data, including encrypted message keys, is missing. Sign out and sign in to fix this, restoring keys from backup.": "Některá data sezení, například klíče od šifrovaných zpráv, nám chybí. Přihlašte se prosím znovu a obnovte si klíče ze zálohy.", "Your browser likely removed this data when running low on disk space.": "Prohlížeč data možná smazal aby ušetřil místo na disku.", "Upload files (%(current)s of %(total)s)": "Nahrát soubory (%(current)s z %(total)s)", @@ -1825,7 +1825,7 @@ "This usually only affects how the room is processed on the server. If you're having problems with your Riot, please report a bug.": "Toto běžně ovlivňuje jak je místnost zpracovávána na serveru. Pokud máte problém s Riotem, nahlaste nám prosím bug.", "You'll upgrade this room from to .": "Upgradujeme tuto místnost z na .", "Upgrade": "Upgradovat", - "Enter secret storage passphrase": "Zadejte tajné heslo k úložišti", + "Enter secret storage passphrase": "Zadejte tajné heslo k bezpečnému úložišti", "Unable to access secret storage. Please verify that you entered the correct passphrase.": "Nepovedlo se přistoupit k bezpečnému úložišti. Zkontrolujte prosím, že je zadané správné heslo.", "Warning: You should only access secret storage from a trusted computer.": "Varování: Přistupujte k bezpečnému úložišti pouze z důvěryhodných počítačů.", "If you've forgotten your passphrase you can use your recovery key or set up new recovery options.": "Pokud si nepamatujete heslo, můžete použít váš obnovovací klíč nebo si nastavte nové možnosti obnovení.", @@ -1861,5 +1861,154 @@ "%(count)s verified sessions|one": "1 ověřená relace", "Language Dropdown": "Menu jazyků", "Help": "Pomoc", - "Country Dropdown": "Menu států" + "Country Dropdown": "Menu států", + "There are unknown sessions in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "V místnosti jsou neověřené relace: pokud budete pokračovat bez ověření, bude možné váš hovor odposlouchávat.", + "Verify this session": "Ověřit tuto relaci", + "Encryption upgrade available": "Je dostupná aktualizace šifrování", + "Set up encryption": "Nastavit šifrování", + "Unverified session": "Neověřená relace", + "Verifies a user, session, and pubkey tuple": "Ověří uživatele, relaci a veřejné klíče", + "Unknown (user, session) pair:": "Neznámý pár (uživatel, relace):", + "Session already verified!": "Relace je už ověřená!", + "WARNING: Session already verified, but keys do NOT MATCH!": "VAROVÁNÍ: Relace je už ověřená, ale klíče NEODPOVÍDAJÍ!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "VAROVÁNÍ: OVĚŘENÍ KLÍČŮ SELHALO! Podpisový klíč pro uživatele %(userId)s a relaci %(deviceId)s je \"%(fprint)s\", což neodpovídá klíči \"%(fingerprint)s\". Může to znamenat, že je vaše komunikace rušena!", + "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "Zadaný podpisový klíč odpovídá klíči relace %(deviceId)s od uživatele %(userId)s. Relace byla označena za platnou.", + "%(senderName)s added %(addedAddresses)s and %(count)s other addresses to this room|other": "%(senderName)s přidal/a této místnosti %(addedAddresses)s a dalších %(count)s adres", + "%(senderName)s removed %(removedAddresses)s and %(count)s other addresses from this room|other": "%(senderName)s odstranil/a této místnosti %(removedAddresses)s a dalších %(count)s adres", + "%(senderName)s removed %(countRemoved)s and added %(countAdded)s addresses to this room": "%(senderName)s odstranil/a této místnosti %(countRemoved)s adres a přidal/a %(countAdded)s adres", + "a few seconds ago": "před pár vteřinami", + "about a minute ago": "před minutou", + "%(num)s minutes ago": "před %(num)s minutami", + "about an hour ago": "asi před hodinou", + "%(num)s hours ago": "před %(num)s hodinami", + "about a day ago": "před jedním dnem", + "%(num)s days ago": "před %(num)s dny", + "a few seconds from now": "za pár vteřin", + "about a minute from now": "asi za minutu", + "%(num)s minutes from now": "za %(num)s minut", + "about an hour from now": "asi za hodinu", + "%(num)s hours from now": "za %(num)s hodin", + "about a day from now": "asi za den", + "%(num)s days from now": "za %(num)s dní", + "Show a presence dot next to DMs in the room list": "V seznamu místností zobrazovat informaci o přítomnosti", + "Enable cross-signing to verify per-user instead of per-session (in development)": "Povolit cross-signing pro verifikaci uživatelů místo zařízení (experimentální)", + "Show info about bridges in room settings": "Zobrazovat v nastavení místnosti informace o propojeních", + "Show padlocks on invite only rooms": "Zobrazovat zámek u místností vyžadujících pozvání", + "Never send encrypted messages to unverified sessions from this session": "Nikdy neposílat šifrované zprávy neověřených zařízením", + "Never send encrypted messages to unverified sessions in this room from this session": "Nikdy v této místnosti neposílat šifrované zprávy neověřeným relacím", + "Enable message search in encrypted rooms": "Povolit vyhledávání v zašifrovaných místnostech", + "Keep secret storage passphrase in memory for this session": "Pro toto přihlášení si uchovat heslo k bezpečnému úložišti", + "How fast should messages be downloaded.": "Jak rychle se mají zprávy stahovat.", + "Confirm the emoji below are displayed on both devices, in the same order:": "Ověřte, že následující emotikony jsou zobrazeny na obou zařízeních ve stejném pořadí:", + "Verify this device by confirming the following number appears on its screen.": "Ověřit zařízení potvrzením, že jsou následující čísla zobrazena na jeho obrazovce.", + "Waiting for %(displayName)s to verify…": "Čekám až nás %(displayName)s ověří…", + "They match": "Odpovídají", + "They don't match": "Neodpovídají", + "To be secure, do this in person or use a trusted way to communicate.": "Aby to bylo bezpečné, udělejte to osobně nebo použijte důvěryhodný komunikační prostředek.", + "Lock": "Zamknout", + "Verify yourself & others to keep your chats safe": "Ověřte sebe a ostatní, aby byla vaše komunikace bezpečná", + "Other users may not trust it": "Ostatní uživatelé této relaci nemusí věřit", + "Later": "Později", + "Review": "Prohlédnout", + "This bridge was provisioned by .": "Toto propojení poskytuje .", + "This bridge is managed by .": "Toto propojení spravuje .", + "Workspace: %(networkName)s": "Workspace: %(networkName)s", + "Channel: %(channelName)s": "Kanál: %(channelName)s", + "Show less": "Skrýt detaily", + "Show more": "Zobrazit víc", + "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Změna hesla resetuje šifrovací klíče pro všechny vaše relace. Pokud si nejdřív nevyexportujete klíče místností a po změně je znovu neimportujete, nedostanete se k historickým zprávám. V budoucnu se toto zjednoduší.", + "Cross-signing and secret storage are enabled.": "Cross-signing a bezpečné úložiště jsou zapnuté.", + "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Váš účet má v bezpečném úložišti identitu pro cross-signing, ale v této relaci jí zatím nevěříte.", + "Cross-signing and secret storage are not yet set up.": "Zatím nemáte nastavený cross-signing a bezpečné úložiště.", + "Bootstrap cross-signing and secret storage": "Zapnout cross-signing a bezpečné úložiště", + "Cross-signing public keys:": "Veřejné klíče pro cross-signing:", + "in memory": "v paměti", + "Cross-signing private keys:": "Soukromé klíče pro cross-signing:", + "in secret storage": "v bezpečném úložišti", + "Secret storage public key:": "Veřejný klíč bezpečného úložiště:", + "in account data": "v datech účtu", + "Your homeserver does not support session management.": "Váš domovský server nepodporuje správu relací.", + "Unable to load session list": "Nepovedlo se načíst seznam relací", + "Delete %(count)s sessions|other": "Smazat %(count)s relací", + "Delete %(count)s sessions|one": "Smazat %(count)s relaci", + "Securely cache encrypted messages locally for them to appear in search results, using ": "Bezpečně uchovávat šifrované zprávy na tomto zařízení, aby se v nich dalo vyhledávat pomocí ", + " to store messages from ": " na uchování zpráv z ", + "rooms.": "místností.", + "Manage": "Spravovat", + "Securely cache encrypted messages locally for them to appear in search results.": "Bezpečně uchovávat zprávy na tomto zařízení aby se v nich dalo vyhledávat.", + "Enable": "Povolit", + "Riot can't securely cache encrypted messages locally while running in a web browser. Use Riot Desktop for encrypted messages to appear in search results.": "Riot neumí bezpečně uchovávat zprávy když běží v prohlížeči. Pokud chcete vyhledávat v šifrovaných zprávách, použijte Riot Desktop.", + "This session is backing up your keys. ": "Tato relace zálohuje vaše klíče. ", + "This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "Tato relace nezálohuje vaše klíče, ale už máte zálohu ze které je můžete obnovit.", + "Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Než se odhlásíce, připojte tuto relaci k záloze klíčů abyste nepřišli o klíče, které můžou být jen v této relaci.", + "Connect this session to Key Backup": "Připojit k zálohování klíčů", + "not stored": "není uložen", + "Backup has a signature from unknown session with ID %(deviceId)s": "Záloha je podepsaná z neznámé relace s ID %(deviceId)s", + "Backup has a valid signature from this session": "Záloha má platný podpis z této relace", + "Backup has an invalid signature from this session": "Záloha má neplatný podpis z této relace", + "Backup has a valid signature from verified session ": "Záloha má platný podpis z ověřené relace ", + "Backup has a valid signature from unverified session ": "Záloha má platný podpis z neověřené relace ", + "Backup has an invalid signature from verified session ": "Záloha má neplatný podpis z ověřené relace ", + "Backup has an invalid signature from unverified session ": "Záloha má neplatný podpis z neověřené relace ", + "Backup is not signed by any of your sessions": "Záloha nemá podpis z žádné vaší relace", + "This backup is trusted because it has been restored on this session": "Záloze věříme, protože už byla v této relaci načtena", + "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "Zálohovací klíč je uložen v bezpečném úložišti, ale jeho načtení není v této relaci povolené. Zapněte prosím cross-signing v Experimentálních funkcích abyste mohli modifikovat stav zálohy.", + "Backup key stored: ": "Zálohovací klíč je uložen: ", + "Your keys are not being backed up from this session.": "Vaše klíče nejsou z této relace zálohovány.", + "Enable desktop notifications for this session": "Povolit v této relaci notifikace", + "Enable audible notifications for this session": "Povolit v této relaci hlasové notifikace", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Heslo bylo změněno. Dokud se znovu nepřihlásíte na ostatních zařízeních, nebudete na nich dostávat notifikace", + "Session ID:": "ID relace:", + "Session key:": "Klíč relace:", + "Message search": "Vyhledávání ve zprávách", + "Cross-signing": "Cross-signing", + "Sessions": "Relace", + "A session's public name is visible to people you communicate with": "Lidé se kterými komunikujete si můžou jméno relace zobrazit", + "This room is bridging messages to the following platforms. Learn more.": "Tato místnost je propojena s následujícími platformami. Více informací", + "This room isn’t bridging messages to any platforms. Learn more.": "Tato místnost není propojená s žádnými dalšími platformami. Více informací.", + "Bridges": "Propojení", + "This user has not verified all of their sessions.": "Tento uživatel zatím neověřil všechny své relace.", + "You have not verified this user.": "Tohoto uživatele jste neověřil.", + "You have verified this user. This user has verified all of their sessions.": "Tohoto uživatele jste ověřili a on ověřil všechny své relace.", + "Someone is using an unknown session": "Někdo používá neznámou relaci", + "This room is end-to-end encrypted": "Místnost je E2E šifrovaná", + "Everyone in this room is verified": "V této místnosti jsou všichni ověřeni", + "Some sessions for this user are not trusted": "Některé relace tohoto uživatele jsou nedůvěryhodné", + "All sessions for this user are trusted": "Všem relacím tohoto uživatele věříme", + "Some sessions in this encrypted room are not trusted": "Některé relace v této místnosti jsou nedůvěryhodné", + "All sessions in this encrypted room are trusted": "Všem relacím v této místosti věříme", + "Mod": "Moderátor", + "Your key share request has been sent - please check your other sessions for key share requests.": "Požadavek k nasdílení klíčů byl odeslán - podívejte se prosím na své ostatní relace, jestli vám přišel.", + "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Požadavek se sdílení klíčů se vaše ostatní relace odesílá automaticky. Pokud jste ho zamítli nebo ignorovali, tímto tlačítkem si jej můžete poslat znovu.", + "If your other sessions do not have the key for this message you will not be able to decrypt them.": "Pokud vaše ostatní relace nemají klíč pro tuto zprávu, nebudete mít možnost jí dešifrovat.", + "Re-request encryption keys from your other sessions.": "Znovu zažádat o šifrovací klíče z vašich ostatních relací.", + "Encrypted by an unverified session": "Zašifrované v neověřené relaci", + "Encrypted by a deleted session": "Zašifrované smazanou relací", + "Invite only": "Pouze na pozvání", + "No sessions with registered encryption keys": "Žádné relace se šifrovacími klíči", + "Send a reply…": "Odpovědět…", + "Send a message…": "Napsat zprávu…", + "Direct Messages": "Přímé zprávy", + "Reject & Ignore user": "Odmítnout & ignorovat uživatele", + "Unknown Command": "Neznámý příkaz", + "Unrecognised command: %(commandText)s": "Nerozpoznaný příkaz: %(commandText)s", + "You can use /help to list available commands. Did you mean to send this as a message?": "Můžete použít /help na vypsání všech příkazů. Nebo jste text chtěli odeslat jako zprávu?", + "Hint: Begin your message with // to start it with a slash.": "Tip: Zprávu můžete začít //, pokud chcete aby začínala lomítkem.", + "Send as message": "Odeslat jako zprávu", + "Waiting for %(displayName)s to accept…": "Čekáme, než %(displayName)s přijme…", + "Start Verification": "Začít s verifikací", + "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Vaše zprávy jsou zabezpečené - pouze Vy a příjemce mají klíče k jejich přečtení.", + "Verify User": "Ověřit uživatele", + "For extra security, verify this user by checking a one-time code on both of your devices.": "Pro lepší bezpečnost, ověřte uživatele zkontrolováním jednorázového kódu na vašich zařízeních.", + "Your messages are not secure": "Vaše zprávy nejsou zabezpečené", + "One of the following may be compromised:": "Něco z následujích věcí může být kompromitováno:", + "Your homeserver": "Váš domovský server", + "The homeserver the user you’re verifying is connected to": "Domovský server ověřovaného uživatele", + "Yours, or the other users’ internet connection": "Vaše připojení k internetu a nebo připojení ověřovaného uživatele", + "Yours, or the other users’ session": "Vaše relace a nebo relace ověřovaného uživatele", + "%(count)s sessions|other": "%(count)s relací", + "%(count)s sessions|one": "%(count)s relace", + "Hide sessions": "Skrýt relace", + "Verify by emoji": "Ověřit emotikonami", + "Verify by comparing unique emoji.": "Oveření porovnáním několika emotikon." } From 05fc6c11b0fd02d3f3d2568c17c5340a5c33f53e Mon Sep 17 00:00:00 2001 From: "J. A. Durieux" Date: Mon, 3 Feb 2020 11:23:24 +0000 Subject: [PATCH 022/268] Translated using Weblate (Dutch) Currently translated at 83.6% (1756 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/nl/ --- src/i18n/strings/nl.json | 93 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index cfd829d718..6574a09bc2 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -388,7 +388,7 @@ "To continue, please enter your password.": "Voer uw wachtwoord in om verder te gaan.", "Blacklist": "Blokkeren", "Unblacklist": "Deblokkeren", - "I verify that the keys match": "Ik verifieer dat de sleutels overeenkomen", + "I verify that the keys match": "Ik verklaar dat de sleutels overeenkomen", "Unable to restore session": "Sessieherstel lukt niet", "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Als u reeds een recentere versie van Riot heeft gebruikt is uw sessie mogelijk onverenigbaar met deze versie. Sluit dit venster en ga terug naar die recentere versie.", "Unknown Address": "Onbekend adres", @@ -1679,5 +1679,94 @@ "Verify this session": "Deze sessie verifiëren", "Encryption upgrade available": "Er is een bijgewerkte versleuteling beschikbaar", "You can use /help to list available commands. Did you mean to send this as a message?": "Type /help om alle opdrachten te zien. Was het uw bedoeling dit als bericht te sturen?", - "Help": "Hulp" + "Help": "Hulp", + "Set up encryption": "Versleuteling instellen", + "Unverified session": "Ongeverifieerde sessie", + "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Dit vergt toegang tot de verstek-identiteitsserver om emailadres of telefoonummer te valideren, maar die server heeft kent geen gebruiksvoorwaarden.", + "Trust": "Vertrouw", + "Custom (%(level)s)": "Aangepast (%(level)s)", + "Error upgrading room": "Bijwerken gesprek mislukt", + "Double check that your server supports the room version chosen and try again.": "Ga nogmaals na dat de server de gekozen gespreksversie ondersteunt, en probeer dan opnieuw.", + "Verifies a user, session, and pubkey tuple": "Verifieert een combinatie van gebruiker+sessie+publieke sleutel", + "Unknown (user, session) pair:": "Onbekende combinatie gebruiker+sessie:", + "Session already verified!": "Sessie al geverifieerd!", + "WARNING: Session already verified, but keys do NOT MATCH!": "PAS OP: De sessie is al geverifieerd, maar de sleutels komen NIET OVEREEN!", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "PAS OP: Sleutelverificatie MISLUKT! De combinatie %userId)s + sessie %(deviceId)s is ondertekend met \"%(fprint)s\" - maar de opgegeven sleutel is \"%(fingerprint)s\". Wellicht worden uw berichten onderschept!", + "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "De door u verschafte en de van %(userId)ss sessie %(deviceId)s verkregen sleutels komen overeen. De sessie is daarmee geverifieerd.", + "%(senderName)s added %(addedAddresses)s and %(count)s other addresses to this room|other": "%(senderName) heeft %(addedAddresses)s en %(count)d andere adressen aan dit gesprek toegevoegd", + "%(senderName)s removed %(removedAddresses)s and %(count)s other addresses from this room|other": "%(senderName)s heeft dit gesprek ontdaan van %(removedAddresses)s en %(count)s andere adressen", + "%(senderName)s removed %(countRemoved)s and added %(countAdded)s addresses to this room": "%(senderName)s heeft dit gesprek ontdaan van %(countRemoved)s adressen, en er %(countAdded)s toegevoegd", + "%(senderName)s placed a voice call.": "%(senderName)s probeert u te bellen.", + "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s poogt u te bellen, maar uw browser ondersteunt dat niet", + "%(senderName)s placed a video call.": "%(senderName)s doet een video-oproep.", + "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s doet een video-oproep, maar uw browser ondersteunt dat niet", + "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s heeft de banregel voor gebruikers die met %(glob)s stroken verwijderd", + "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s heeft de banregel voor gesprekken die met %(glob)s stroken verwijderd", + "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s heeft de banregel voor servers die met %(glob)s stroken verwijderd", + "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s heeft een banregel die met %(glob)s strookt verwijderd", + "%(senderName)s updated an invalid ban rule": "%(senderName)s heeft een ongeldige banregel bijgewerkt", + "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s heeft de regel bijgewerkt die gebruikers die met %(glob)s sporen verbant vanwege %(reason)s", + "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s heeft de regel bijgewerkt die gesprekken die met %(glob)s sporen verbant vanwege %(reason)s", + "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s heeft de regel bijgewerkt die servers die met %(glob)s sporen verbant vanwege %(reason)s", + "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s heeft een banregel vanwege %(reason)s die met %(glob)s spoort bijgewerkt", + "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s heeft geregeld dat gebruikers die met %(glob)s sporen verbannen worden vanwege %(reason)s", + "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s heeft geregeld dat gesprekken die met %(glob)s sporen verbannen worden vanwege %(reason)s", + "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s heeft geregeld dat servers die met %(glob)s sporen verbannen worden vanwege %(reason)s", + "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s heeft geregeld dat alles wat met %(glob)s spoort verbannen wordt vanwege %(reason)s", + "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s heeft het patroon van een banregel voor gebruikers wegens %(reason)s aangepast van %(oldGlob)s tot %(newGlob)s", + "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s heeft het patroon van een banregel voor gesprekken wegens %(reason)s aangepast van %(oldGlob)s tot %(newGlob)s", + "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s heeft het patroon van een banregel voor servers wegens %(reason)s aangepast van %(oldGlob)s tot %(newGlob)s", + "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s heeft het patroon van een banregel wegens %(reason)s aangepast van %(oldGlob)s tot %(newGlob)s", + "The message you are trying to send is too large.": "Uw bericht is te lang om te verzenden.", + "a few seconds ago": "enige tellen geleden", + "about a minute ago": "een minuut of zo geleden", + "%(num)s minutes ago": "%(num)s minuten geleden", + "about an hour ago": "een uur of zo geleden", + "%(num)s hours ago": "%(num)s uren geleden", + "about a day ago": "een dag of zo geleden", + "%(num)s days ago": "%(num)s dagen geleden", + "a few seconds from now": "over een paar tellen", + "about a minute from now": "over een minuut of zo", + "%(num)s minutes from now": "over %(num)s minuten", + "about an hour from now": "over een uur of zo", + "%(num)s hours from now": "over %(num)s uur", + "about a day from now": "over een dag of zo", + "%(num)s days from now": "over %(num)s dagen", + "%(name)s (%(userId)s)": "%(name)s (%(userId)s)", + "Try out new ways to ignore people (experimental)": "Nieuwe manieren om mensen te negeren uitproberen (nog in ontwikkeling)", + "Show a presence dot next to DMs in the room list": "Toon aanwezigheid bij tweegesprekken in de gesprekkenlijst", + "Enable cross-signing to verify per-user instead of per-session (in development)": "Gebruik gebruikersverificatie in plaats van sessieverificatie (nog in ontwikkeling)", + "Enable local event indexing and E2EE search (requires restart)": "Indexeer lokaal gebeurtenissen en maak zo E2EE-zoeken mogelijk (vergt een herstart)", + "Show info about bridges in room settings": "Toon bruginformatie in gespreksinstellingen", + "Show padlocks on invite only rooms": "Toon hangsloten op besloten gesprekken", + "Match system theme": "Pas aan aan systeemthema", + "Never send encrypted messages to unverified sessions from this session": "Zend vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies", + "Never send encrypted messages to unverified sessions in this room from this session": "Zend vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies in dit gesprek", + "Enable message search in encrypted rooms": "Sta zoeken in versleutelde gesprekken toe", + "Keep secret storage passphrase in memory for this session": "Onthoud in deze sessie het wachtwoord voor sleutelopslag", + "How fast should messages be downloaded.": "Ophaalfrequentie van berichten.", + "My Ban List": "Mijn banlijst", + "This is your list of users/servers you have blocked - don't leave the room!": "Dit is de lijst van door u geblokkeerde servers/gebruikers. Verlaat dit gesprek niet!", + "Confirm the emoji below are displayed on both devices, in the same order:": "Bevestig dat beide apparaten dezelfde emojis in dezelfde volgorde tonen:", + "Verify this device by confirming the following number appears on its screen.": "Verifieer dit apparaat door te bevestigen dat het scherm het volgende getal toont.", + "Waiting for %(displayName)s to verify…": "Wachten tot %(displayName)s geverifieerd heeft…", + "They match": "Ze komen overeen", + "They don't match": "Ze komen niet overeen", + "To be secure, do this in person or use a trusted way to communicate.": "Doe dit voor de zekerheid in persona, of via een betrouwbaar communicatiemedium.", + "Lock": "Hangslot", + "Verify yourself & others to keep your chats safe": "Verifieer jezelf en anderen om je gesprekken veilig te houden", + "Other users may not trust it": "Mogelijk wantrouwen anderen het", + "Upgrade": "Bijwerken", + "Verify": "Verifiëren", + "Later": "Later", + "Review": "Contrôle", + "Decline (%(counter)s)": "Afwijzen (%(counter)s)", + "This bridge was provisioned by .": "Dank aan voor de brug.", + "This bridge is managed by .": "Brug onderhouden door .", + "Workspace: %(networkName)s": "Werkruimte: %(networkName)s", + "Channel: %(channelName)s": "Kanaal: %(channelName)s", + "Show less": "Minder tonen", + "Show more": "Meer tonen", + "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Momenteel stelt een wachtwoordswijziging alle berichtsleutels in alle sessies opnieuw in, en maakt zo oude versleutelde berichten onleesbaar - tenzij u uw sleutels eerst wegschrijft, en na afloop weer inleest. Dit zal verbeterd worden.", + "Add users and servers you want to ignore here. Use asterisks to have Riot match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Geef hier te negeren gebruikers en servers in. Asterisken staan voor willekeurige tekenreeksen; zo leidt @bot:* tot het negeren van gebruikers die 'bot' heten op alle servers." } From a6dd0d01e4fe11a24cc64b635e2c0e5393874252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Thu, 6 Feb 2020 07:55:40 +0000 Subject: [PATCH 023/268] Translated using Weblate (French) Currently translated at 100.0% (2101 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index bd491ad7f5..cc79b5c9fc 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -387,7 +387,7 @@ "Accept": "Accepter", "Active call (%(roomName)s)": "Appel en cours (%(roomName)s)", "Alias (optional)": "Alias (facultatif)", - "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Impossible de se connecter au serveur d'accueil - veuillez vérifier votre connexion, assurez-vous que le certificat SSL de votre serveur d'accueil est un certificat de confiance, et qu'aucune extension du navigateur ne bloque les requêtes.", + "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Impossible de se connecter au serveur d’accueil - veuillez vérifier votre connexion, assurez-vous que le certificat SSL de votre serveur d’accueil est un certificat de confiance, et qu’aucune extension du navigateur ne bloque les requêtes.", "Close": "Fermer", "Custom": "Personnaliser", "Decline": "Refuser", @@ -493,7 +493,7 @@ "%(senderName)s changed the pinned messages for the room.": "%(senderName)s a changé les messages épinglés du salon.", "Jump to read receipt": "Aller à l'accusé de lecture", "World readable": "Lisible publiquement", - "Guests can join": "Accessible aux invités", + "Guests can join": "Accessible aux visiteurs", "Invalid community ID": "Identifiant de communauté non valide", "'%(groupId)s' is not a valid community ID": "\"%(groupId)s\" n'est pas un identifiant de communauté valide", "%(senderName)s sent an image": "%(senderName)s a envoyé une image", @@ -1149,7 +1149,7 @@ "Begin Verifying": "Commencer la vérification", "Waiting for partner to accept...": "Nous attendons que le partenaire accepte…", "Use two-way text verification": "Utiliser la vérification textuelle bidirectionnelle", - "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Vérifier cet utilisateur pour que ce soit un utilisateur de confiance. Faire confiance aux utilisateurs vous apporte une tranquillité d’esprit quand vous utilisez des messages chiffrés de bout en bout.", + "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Vérifier cet utilisateur pour le marquer comme fiable. Faire confiance aux utilisateurs vous permet d’être serein quand vous utilisez des messages chiffrés de bout en bout.", "Waiting for partner to confirm...": "Nous attendons que le partenaire confirme…", "Incoming Verification Request": "Demande de vérification entrante", "Go back": "Revenir en arrière", @@ -1178,7 +1178,7 @@ "Premium hosting for organisations Learn more": "Hébergement premium pour les organisations En savoir plus", "Other": "Autre", "Find other public servers or use a custom server": "Trouvez d'autres serveurs publics ou utilisez un serveur personnalisé", - "Guest": "Invité", + "Guest": "Visiteur", "Sign in instead": "Se connecter", "Set a new password": "Définir un nouveau mot de passe", "Create account": "Créer un compte", @@ -1193,9 +1193,9 @@ "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s a rendu le salon public à tous ceux qui en connaissent le lien.", "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s a rendu le salon disponible sur invitation seulement.", "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s a changé la règle d’adhésion en %(rule)s", - "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s a autorisé les invités à rejoindre le salon.", - "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s a empêché les invités de rejoindre le salon.", - "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s a changé l'accès des invités en %(rule)s", + "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s a autorisé les visiteurs à rejoindre le salon.", + "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s a empêché les visiteurs de rejoindre le salon.", + "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s a changé l'accès des visiteurs en %(rule)s", "Group & filter rooms by custom tags (refresh to apply changes)": "Grouper et filtrer les salons grâce à des étiquettes personnalisées (actualiser pour appliquer les changements)", "Verify this user by confirming the following emoji appear on their screen.": "Vérifier cet utilisateur en confirmant que les émojis suivant apparaissent sur son écran.", "Unable to find a supported verification method.": "Impossible de trouver une méthode de vérification prise en charge.", @@ -1754,7 +1754,7 @@ "You have ignored this user, so their message is hidden. Show anyways.": "Vous avez ignoré cet utilisateur, donc ses messages sont cachés. Les montrer quand même.", "Custom (%(level)s)": "Personnalisé (%(level)s)", "Trusted": "Fiable", - "Not trusted": "Non vérifié", + "Not trusted": "Non fiable", "Direct message": "Message direct", "%(role)s in %(roomName)s": "%(role)s dans %(roomName)s", "Messages in this room are end-to-end encrypted.": "Les messages dans ce salon sont chiffrés de bout en bout.", @@ -1850,7 +1850,7 @@ "Enter secret storage recovery key": "Saisir la clé de récupération du coffre secret", "Unable to access secret storage. Please verify that you entered the correct recovery key.": "Impossible d’accéder au coffre secret. Vérifiez que vous avez saisi la bonne clé de récupération.", "If you've forgotten your recovery key you can .": "Si vous avez oublié votre clé de récupération vous pouvez .", - "Warning: You should only set up key backup from a trusted computer.": "Attention : Vous devriez uniquement configurer une sauvegarde de clés depuis un ordinateur de confiance.", + "Warning: You should only set up key backup from a trusted computer.": "Attention : Vous ne devriez configurer la sauvegarde de clés que depuis un ordinateur de confiance.", "If you've forgotten your recovery key you can ": "Si vous avez oublié votre clé de récupération, vous pouvez ", "Set up with a recovery key": "Configurer avec une clé de récupération", "As a safety net, you can use it to restore your access to encrypted messages if you forget your passphrase.": "Par mesure de sécurité, vous pouvez l’utiliser pour récupérer l’accès aux messages chiffrés si vous oubliez votre phrase de passe.", @@ -1918,7 +1918,7 @@ "Other users may not trust it": "D’autres utilisateurs pourraient ne pas lui faire confiance", "Later": "Plus tard", "Verify User": "Vérifier l’utilisateur", - "For extra security, verify this user by checking a one-time code on both of your devices.": "Pour une meilleure sécurité, vérifiez cet utilisateur en comparant un code à usage unique sur vos deux appareils.", + "For extra security, verify this user by checking a one-time code on both of your devices.": "Pour une sécurité supplémentaire, vérifiez cet utilisateur en comparant un code à usage unique sur vos deux appareils.", "Start Verification": "Commencer la vérification", "Unknown Command": "Commande inconnue", "Unrecognised command: %(commandText)s": "Commande non reconnue : %(commandText)s", @@ -2051,7 +2051,7 @@ "You have not verified this user. This user has verified all of their sessions.": "Vous n’avez pas vérifié cet utilisateur. Cet utilisateur a vérifié toutes ses sessions.", "You have verified this user. This user has verified all of their sessions.": "Vous avez vérifié cet utilisateur. Cet utilisateur a vérifié toutes ses sessions.", "Someone is using an unknown session": "Quelqu'un utilise une session inconnue", - "Some sessions for this user are not trusted": "Certaines sessions de cet utilisateur ne sont par fiables", + "Some sessions for this user are not trusted": "Certaines sessions de cet utilisateur ne sont pas fiables", "All sessions for this user are trusted": "Toutes les sessions de cet utilisateur sont fiables", "Some sessions in this encrypted room are not trusted": "Certaines sessions dans ce salon chiffré ne sont pas fiables", "All sessions in this encrypted room are trusted": "Toutes les sessions dans ce salon chiffré sont fiables", @@ -2101,7 +2101,7 @@ "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Récupérez l’accès à votre compte et restaurez les clés de chiffrement dans cette session. Sans elles, vous ne pourrez pas lire tous vos messages chiffrés dans n’importe quelle session.", "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Attention : Vos données personnelles (y compris les clés de chiffrement) seront stockées dans cette session. Effacez-les si vous n’utilisez plus cette session ou si vous voulez vous connecter à un autre compte.", "Sender session information": "Informations de session de l’expéditeur", - "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Mettez à niveau cette session pour l’autoriser de vérifier d’autres sessions, ce qui leur permettra d’accéder aux messages chiffrés et de les marquer comme fiables pour les autres utilisateurs.", + "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Mettez à niveau cette session pour l’autoriser à vérifier d’autres sessions, ce qui leur permettra d’accéder aux messages chiffrés et de les marquer comme fiables pour les autres utilisateurs.", "Set up encryption on this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Configurez le chiffrement sur cette session pour lui permettre de vérifier d’autres sessions, ce qui leur permettra d’accéder aux messages chiffrés et de les marquer comme fiables pour les autres utilisateurs.", "This session can now verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Cette session peut à présent vérifier d’autres sessions, ce qui leur permettra d’accéder aux messages chiffrés et de les marquer comme fiables pour les autres utilisateurs.", "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Si vous ne configurez pas la récupération de messages sécurisée, vous ne pourrez pas restaurer l’historique de vos messages chiffrés si vous vous déconnectez ou si vous utilisez une autre session.", From 34a67bf1446ecb34718626d92c576b331f889a42 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 5 Feb 2020 18:22:29 +0000 Subject: [PATCH 024/268] Translated using Weblate (Hungarian) Currently translated at 98.4% (2068 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 86 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 32f5b237e7..b8d14774d6 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2006,5 +2006,89 @@ "Unable to load session list": "A munkamenet listát nem lehet betölteni", "Delete %(count)s sessions|other": "%(count)s munkamenet törlése", "Delete %(count)s sessions|one": "%(count)s munkamenet törlése", - "This session is backing up your keys. ": "Ez a munkamenet elmenti a kulcsaidat. " + "This session is backing up your keys. ": "Ez a munkamenet elmenti a kulcsaidat. ", + "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "FIGYELEM: KULCS ELLENŐRZÉS HIBÁS! %(userId)s aláírási kulcsa és a munkamenet: %(deviceId)s ujjlenyomata \"%(fprint)s\" ami nem egyezik meg a megadott ujjlenyomattal ami \"%(fingerprint)s\". Ez jelentheti azt, hogy a kommunikációt lehallgatják!", + "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "A megadott aláírási kulcs megegyezik %(userId)s felhasználótól kapott aláírási kulccsal ebben a munkamenetben: %(deviceId)s. A munkamenet hitelesnek lett jelölve.", + "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Jelenleg a jelszó változtatás minden munkamenet végpontok közötti titkosító kulcsait alaphelyzetbe állítja, ezáltal a titkosított üzenetek olvashatatlanok lesznek, hacsak először nem mented ki a szobák kulcsait és töltöd vissza jelszóváltoztatás után. A jövőben ezt egyszerűsítjük majd.", + "This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "Ez az munkamenet nem menti el a kulcsaidat, de van létező mentésed ahonnan vissza tudsz állni és továbbléphetsz.", + "Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Állítsd be ezen az munkameneten a Kulcs Mentést kijelentkezés előtt, hogy ne veszíts el olyan kulcsot ami csak ezen az eszközön van meg.", + "Connect this session to Key Backup": "Munkamenet csatlakoztatása a Kulcs Mentéshez", + "Backup has a signature from unknown session with ID %(deviceId)s": "A mentésnek ismeretlen munkamenetből származó aláírása van ezzel az azonosítóval: %(deviceId)s", + "Backup has a valid signature from this session": "A mentés érvényes aláírást tartalmaz ebből a munkamenetből", + "Backup has an invalid signature from this session": "A mentés érvénytelen aláírást tartalmaz ebből a munkamenetből", + "Backup has a valid signature from verified session ": "A mentés érvénes aláírást tartalmaz érvényes munkamenetből ", + "Backup has a valid signature from unverified session ": "A mentés érvénes aláírást tartalmaz ellenőrizetlen munkamenetből ", + "Backup has an invalid signature from verified session ": "A mentés érvénytelen aláírást tartalmaz érvényes munkamenetből ", + "Backup has an invalid signature from unverified session ": "A mentés érvénytelen aláírást tartalmaz ellenőrizetlen munkamenetből ", + "Backup is not signed by any of your sessions": "A mentés nem tartalmaz aláírást egyetlen munkamenetedből sem", + "This backup is trusted because it has been restored on this session": "Ez a mentés megbízható mert ebben a munkamenetben lett visszaállítva", + "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "A mentési kulcs a biztonsági tárolóban van elmentve, de ebben a munkamenetben ez a lehetőség nincs engedélyezve. Kérlek engedélyezd az eszközök közötti hitelesítést a Laborokban a kulcs mentés állapotának megváltoztatásához.", + "Your keys are not being backed up from this session.": "A kulcsaid nem kerülnek elmentésre erről a munkamenetről.", + "Enable desktop notifications for this session": "Asztali értesítések engedélyezése ebben a munkamenetben", + "Enable audible notifications for this session": "Hallható értesítések engedélyezése ebben a munkamenetben", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "A jelszavad sikeresen megváltozott. Addig nem kapsz push értesítéseket más munkamenetekben amíg nem jelentkezel vissza bennük", + "Session ID:": "Munkamenet azonosító:", + "Session key:": "Munkamenet kulcs:", + "Sessions": "Munkamenetek", + "A session's public name is visible to people you communicate with": "A munkamenet nyilvános neve megjelenik azoknál az embereknél, akikkel beszélgetsz", + "This user has not verified all of their sessions.": "Ez a felhasználó még nem ellenőrizte az összes munkamenetét.", + "You have not verified this user.": "Még nem ellenőrizted ezt a felhasználót.", + "You have verified this user. This user has verified all of their sessions.": "Ezt a felhasználót ellenőrizted. Ez a felhasználó hitelesítette az összes munkamenetét.", + "Someone is using an unknown session": "Valaki ismeretlen munkamenetet használ", + "Some sessions for this user are not trusted": "Ennek a felhasználónak néhány munkamenete nem megbízható", + "All sessions for this user are trusted": "A felhasználónak minden munkamenete megbízható", + "Some sessions in this encrypted room are not trusted": "Ebben a titkosított szobában nem minden munkamenet megbízható", + "All sessions in this encrypted room are trusted": "Ebben a titkosított szobában minden munkamenet megbízható", + "Mod": "Mod", + "Your key share request has been sent - please check your other sessions for key share requests.": "A kulcs megosztás kérésed el lett küldve - ellenőrizd a többi munkamenetedet a kulcskérések után.", + "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Kulcs megosztás kérés automatikusan el lett küldve neked a másik munkamenetekből. Ha elutasítottad vagy bezártad a kérést másik munkamenetedben, ide kattintva újrakérheted őket ehhez a munkamenethez.", + "If your other sessions do not have the key for this message you will not be able to decrypt them.": "Ha a többi munkameneted közül egyik sem tartalmazza a kulcsot ehhez az üzenethez, akkor ezt az üzenetet nem fogod tudni elolvasni.", + "Re-request encryption keys from your other sessions.": "Titkosítási kulcsok újrakérése a többi munkamenetből.", + "Encrypted by an unverified session": "Ellenőrizetlen munkamenet titkosította", + "Encrypted by a deleted session": "Törölt munkamenet által lett titkosítva", + "No sessions with registered encryption keys": "Nincs munkamenet regisztrált titkosítási kulcsokkal", + "Waiting for %(displayName)s to accept…": "%(displayName)s felhasználóra várakozás az elfogadáshoz…", + "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Az üzeneted biztonságban van és csak neked és a címzetteknek van meg az egyedi kulcs a visszafejtéshez.", + "Your messages are not secure": "Az üzeneteid nincsenek biztonságban", + "One of the following may be compromised:": "Valamelyik az alábbiak közül kompromittált:", + "Your homeserver": "Matrix szervered", + "The homeserver the user you’re verifying is connected to": "Az ellenőrizendő felhasználó ehhez a matrix szerverhez kapcsolódik:", + "Yours, or the other users’ internet connection": "A te vagy a másik felhasználó Internet kapcsolata", + "Yours, or the other users’ session": "A te vagy a másik felhasználó munkamenete", + "%(count)s sessions|other": "%(count)s munkamenet", + "%(count)s sessions|one": "%(count)s munkamenet", + "Hide sessions": "Munkamenetek elrejtése", + "Verify by emoji": "Ellenőrzés emodzsival", + "Verify by comparing unique emoji.": "Ellenőrzés egyedi emodzsik összehasonlításával.", + "Ask %(displayName)s to scan your code:": "Kérd meg %(displayName)s felhasználót, hogy olvassa be a kódot:", + "If you can't scan the code above, verify by comparing unique emoji.": "Ha nem tudod beolvasni az alábbi kódot, ellenőrizd az egyedi emodzsik összehasonlításával.", + "You've successfully verified %(displayName)s!": "Sikeresen ellenőrizted a felhasználót: %(displayName)s!", + "Got it": "Értem", + "Verification timed out. Start verification again from their profile.": "Ellenőrzés időtúllépés. Kezd újra az ellenőrzést a másik felhasználó profiljából.", + "%(displayName)s cancelled verification. Start verification again from their profile.": "%(displayName)s törölte az ellenőrzést. Kezd újra az ellenőrzést a felhasználó profiljából.", + "You cancelled verification. Start verification again from their profile.": "Törölted az ellenőrzést. Kezd újra az ellenőrzést a felhasználó profiljából.", + "Encryption enabled": "Titkosítás engedélyezve", + "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Ebben a szobában az üzenetek végpontok között titkosítottak. Tudj meg többet és ellenőrizd ezt a felhasználót a profiljában.", + "Encryption not enabled": "Titkosítás nincs engedélyezve", + "The encryption used by this room isn't supported.": "A szobában használt titkosítás nem támogatott.", + "Clear all data in this session?": "Minden adat törlése ebben a munkamenetben?", + "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Az adatok törlése ebből a munkamenetből végleges. A titkosított üzenetek elvesznek hacsak nincsenek elmentve a kulcsai.", + "Verify session": "Munkamenet ellenőrzése", + "To verify that this session can be trusted, please check that the key you see in User Settings on that device matches the key below:": "A munkamenet megbízhatóságának eldöntéséhez ellenőrizd a kulcsot a Felhasználói Beállításokban ezen az eszközön, hogy megegyezik-e az alábbi kulccsal:", + "To verify that this session 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 session matches the key below:": "A munkamenet megbízhatóságának eldöntéséhez vedd fel a kapcsolatot a tulajdonosával valami másik módon (pl. személyesen vagy telefonhívással) és kérdezd meg, hogy a Felhasználói Beállításokban ugyanazt a kulcsot látja-e mint ami alul van:", + "Session name": "Munkamenet neve", + "Session key": "Munkamenet kulcs", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this session and you probably want to press the blacklist button instead.": "Ha egyezik akkor nyomd meg az ellenőriz gombot alul. Ha nem akkor valaki lehallgatja a munkamenetet és valószínű, hogy inkább a tiltólista gombra kellene kattintani.", + "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "A felhasználót ellenőrizve a munkamenet megbízhatónak lesz jelölve és ugyanakkor a munkamenetedet is megbízhatónak fogja jelölni náluk.", + "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Eszköz ellenőrzése és beállítás megbízhatónak. Az eszközben való megbízás megnyugtató lehet, ha végpontok közötti titkosítást használsz.", + "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Az eszköz ellenőrzése megbízhatónak fogja jelezni az eszközt és azok akik téged ellenőriztek megbíznak majd ebben az eszközödben.", + "You added a new session '%(displayName)s', which is requesting encryption keys.": "Új munkamenetet adtál hozzá '%(displayName)s' néven ami kéri a titkosítási kulcsokat.", + "Your unverified session '%(displayName)s' is requesting encryption keys.": "Az ellenőrizetlen munkameneted '%(displayName)s' néven titkosítási kulcsokat kér.", + "Loading session info...": "Munkamenet információk betöltése...", + "This will allow you to return to your account after signing out, and sign in on other sessions.": "Ezzel visszatérhetsz a fiókodba miután kijelentkeztél majd vissza egy másik munkamenetbe.", + "You are currently blacklisting unverified sessions; to send messages to these sessions you must verify them.": "Jelenleg tiltólistán vannak az ellenőrizetlen munkamenetek; hogy üzeneteket tudj küldeni ezekbe a munkamenetekbe ellenőrizned kell őket.", + "We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Javasoljuk, hogy minden munkamenetet ellenőrizz, hogy a tényleges tulajdonosához tartoznak vagy újraküldheted az üzenetet ha akarod anélkül, hogy ellenőriznéd őket.", + "Room contains unknown sessions": "A szoba ismeretlen munkameneteket tartalmaz", + "\"%(RoomName)s\" contains sessions that you haven't seen before.": "\"%(RoomName)s\" még nem látott munkameneteket tartalmaz.", + "Unknown sessions": "Ismeretlen munkamenetek" } From f1d7cf6a564549e18f5632de13a47ee3ee1c5f4c Mon Sep 17 00:00:00 2001 From: random Date: Mon, 3 Feb 2020 09:44:29 +0000 Subject: [PATCH 025/268] Translated using Weblate (Italian) Currently translated at 99.9% (2100 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 116 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index f6ee0f82ff..dd6b697fb7 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2009,5 +2009,119 @@ "Verify this device by confirming the following number appears on its screen.": "Verifica questo dispositivo confermando che il seguente numero appare sullo schermo.", "Verify yourself & others to keep your chats safe": "Verifica te stesso e gli altri per mantenere sicure le chat", "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "Backup chiavi salvato nell'archivio segreto, ma questa funzione non è attiva in questa sessione. Attiva la firma incrociata in Laboratori per modificare lo stato del backup chiavi.", - "Your keys are not being backed up from this session.": "Il backup chiavi non viene fatto per questa sessione." + "Your keys are not being backed up from this session.": "Il backup chiavi non viene fatto per questa sessione.", + "Enable desktop notifications for this session": "Attiva le notifiche desktop per questa sessione", + "Enable audible notifications for this session": "Attiva le notifiche audio per questa sessione", + "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "La tua password è stata cambiata correttamente. Non riceverai notifiche push in altre sessioni finchè non riesegui l'accesso in esse", + "Session ID:": "ID sessione:", + "Session key:": "Chiave sessione:", + "Message search": "Ricerca messaggio", + "Sessions": "Sessioni", + "A session's public name is visible to people you communicate with": "Il nome pubblico di una sessione è visibile alle persone con cui comunichi", + "This room is bridging messages to the following platforms. Learn more.": "Questa stanza fa un bridge dei messaggi con le seguenti piattaforme. Maggiori informazioni.", + "This room isn’t bridging messages to any platforms. Learn more.": "Questa stanza non fa un bridge dei messaggi con alcuna piattaforma. Maggiori informazioni.", + "Bridges": "Bridge", + "This user has not verified all of their sessions.": "Questo utente non ha verificato tutte le sue sessioni.", + "You have not verified this user.": "Non hai verificato questo utente.", + "You have verified this user. This user has verified all of their sessions.": "Hai verificato questo utente. Questo utente ha verificato tutte le sue sessioni.", + "Someone is using an unknown session": "Qualcuno sta usando una sessione sconosciuta", + "Some sessions for this user are not trusted": "Alcune sessioni di questo utente non sono fidate", + "All sessions for this user are trusted": "Tutte le sessioni di questo utente sono fidate", + "Some sessions in this encrypted room are not trusted": "Alcune sessioni in questa stanza cifrata non sono fidate", + "All sessions in this encrypted room are trusted": "Tutte le sessioni in questa stanza cifrata sono fidate", + "Your key share request has been sent - please check your other sessions for key share requests.": "La tua richiesta di condivisione chiavi è stata inviata - controlla le tue altre sessioni per le richieste.", + "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Le richieste di condivisione chiavi vengono inviate alle tue altre sessioni automaticamente. Se sulle altre sessioni l'hai rifiutata o annullata, clicca qui per chiedere di nuovo le chiavi per questa sessione.", + "If your other sessions do not have the key for this message you will not be able to decrypt them.": "Se le altre sessioni non hanno la chiave per questo messaggio non sarai in grado di decifrarlo.", + "Re-request encryption keys from your other sessions.": "Chiedi di nuovo le chiavi di cifratura dalle altre sessioni.", + "Encrypted by an unverified session": "Cifrato da una sessione non verificata", + "Encrypted by a deleted session": "Cifrato da una sessione eliminata", + "No sessions with registered encryption keys": "Nessuna sessione con chiavi di cifratura registrate", + "Waiting for %(displayName)s to accept…": "In attesa che %(displayName)s accetti…", + "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "I tuoi messaggi sono protetti e solo tu ed il destinatario avete le chiavi univoche per sbloccarli.", + "Your messages are not secure": "I tuoi messaggi non sono sicuri", + "One of the following may be compromised:": "Uno dei seguenti potrebbe essere compromesso:", + "Your homeserver": "Il tuo homeserver", + "The homeserver the user you’re verifying is connected to": "L'homeserver al quale è connesso l'utente che stai verificando", + "Yours, or the other users’ internet connection": "La tua connessione internet o quella degli altri utenti", + "Yours, or the other users’ session": "La tua sessione o quella degli altri utenti", + "%(count)s sessions|other": "%(count)s sessioni", + "%(count)s sessions|one": "%(count)s sessione", + "Hide sessions": "Nascondi sessione", + "Verify by emoji": "Verifica via emoji", + "Verify by comparing unique emoji.": "Verifica confrontando emoji specifici.", + "Ask %(displayName)s to scan your code:": "Chiedi a %(displayName)s di scansionare il tuo codice:", + "If you can't scan the code above, verify by comparing unique emoji.": "Se non riesci a scansionare il codice sopra, verifica confrontando emoji specifiche.", + "You've successfully verified %(displayName)s!": "Hai verificato correttamente %(displayName)s!", + "Got it": "Capito", + "Verification timed out. Start verification again from their profile.": "Verifica scaduta. Inizia di nuovo la verifica dal suo profilo.", + "%(displayName)s cancelled verification. Start verification again from their profile.": "%(displayName)s ha annullato la verifica. Inizia di nuovo la verifica dal suo profilo.", + "You cancelled verification. Start verification again from their profile.": "Hai annullato la verifica. Inizia di nuovo la verifica dal suo profilo.", + "Encryption enabled": "Cifratura attivata", + "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "I messaggi in questa stanza sono cifrati end-to-end. Maggiori info e verifica di questo utente nel suo profilo.", + "Encryption not enabled": "Cifratura non attivata", + "The encryption used by this room isn't supported.": "La cifratura usata da questa stanza non è supportata.", + "Clear all data in this session?": "Svuotare tutti i dati in questa sessione?", + "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Lo svuotamento dei dati di questa sessione è permanente. I messaggi cifrati andranno persi a meno non si abbia un backup delle loro chiavi.", + "Verify session": "Verifica sessione", + "To verify that this session can be trusted, please check that the key you see in User Settings on that device matches the key below:": "Per verficare che questa sessione sia fidata, controlla che la chiave che vedi nelle impostazioni utente su quel dispositivo corrisponda a questa sotto:", + "To verify that this session 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 session matches the key below:": "Per verificare che questa sessione sia fidata, contatta il suo proprietario usando altri metodi (es. di persona o per telefono) e chiedi se la chiave che vede nelle sue impostazioni utente di questa sessione corrisponde con questa sotto:", + "Session name": "Nome sessione", + "Session key": "Chiave sessione", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this session and you probably want to press the blacklist button instead.": "Se corrisponde, premi il pulsante di verifica sottostante. Se non corrisponde, qualcuno sta intercettando questa sessione e dovresti invece premere il pulsante della lista nera.", + "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "La verifica di questo utente contrassegnerà come fidata la sua sessione a te e viceversa.", + "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Verifica questo dispositivo per segnarlo come fidato. Fidarsi di questo dispositivo offre a te e agli altri utenti una maggiore tranquillità nell'uso di messaggi cifrati end-to-end.", + "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "La verifica di questo dispositivo lo segnerà come fidato e gli utenti che si sono verificati con te si fideranno di questo dispositivo.", + "If you can't find someone, ask them for their username, share your username (%(userId)s) or profile link.": "Se non riesci a trovare qualcuno, chiedigli il nome utente, condividi il tuo (%(userId)s) o il collegamento al profilo.", + "You added a new session '%(displayName)s', which is requesting encryption keys.": "Hai aggiunto una nuova sessione '%(displayName)s', che sta chiedendo le chiavi di cifratura.", + "Your unverified session '%(displayName)s' is requesting encryption keys.": "La tua sessione non verificata '%(displayName)s' sta chiedendo le chiavi di cifratura.", + "Loading session info...": "Caricamento info di sessione...", + "New session": "Nuova sessione", + "Use this session to verify your new one, granting it access to encrypted messages:": "Usa questa sessione per verificare quella nuova, dandole accesso ai messaggi cifrati:", + "If you didn’t sign in to this session, your account may be compromised.": "Se non hai fatto l'accesso a questa sessione, il tuo account potrebbe essere compromesso.", + "This wasn't me": "Non ero io", + "This will allow you to return to your account after signing out, and sign in on other sessions.": "Ciò ti permetterà di tornare al tuo account dopo la disconnessione e di accedere in altre sessioni.", + "You are currently blacklisting unverified sessions; to send messages to these sessions you must verify them.": "Stai attualmente bloccando sessioni non verificate; per inviare messaggi a queste sessioni devi verificarle.", + "We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Ti consigliamo di eseguire il processo di verifica per ogni sessione per confermare l'appartenenza al loro legittimo proprietario, ma puoi reinviare il messaggio senza la verifica se lo preferisci.", + "Room contains unknown sessions": "La stanza contiene sessioni sconosciute", + "\"%(RoomName)s\" contains sessions that you haven't seen before.": "\"%(RoomName)s\" contiene sessioni che non hai mai visto prima.", + "Unknown sessions": "Sessioni sconosciute", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your passphrase.": "Accedi alla tua cronologia di messaggi sicuri e all'identità a firma incrociata per verificare altre sessioni inserendo la tua password.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.": "Accedi alla tua cronologia di messaggi sicuri e all'identità a firma incrociata per verificare altre sessioni inserendo la tua chiave di recupero.", + "Recovery key mismatch": "La chiave di recupero non corrisponde", + "Incorrect recovery passphrase": "Password di recupero errata", + "Backup restored": "Backup ripristinato", + "Enter recovery passphrase": "Inserisci password di recupero", + "Enter recovery key": "Inserisci chiave di recupero", + "Confirm your identity by entering your account password below.": "Conferma la tua identità inserendo la password dell'account sotto.", + "Message not sent due to unknown sessions being present": "Messaggio non inviato a causa della presenza di sessioni sconosciute", + "Show sessions, send anyway or cancel.": "Mostra le sessioni, invia comunque o annulla.", + "Your new session is now verified. Other users will see it as trusted.": "La tua nuova sessione è ora verificata. Gli altri utenti la vedranno come fidata.", + "Without completing security on this session, it won’t have access to encrypted messages.": "Senza completare la sicurezza di questa sessione, essa non avrà accesso ai messaggi cifrati.", + "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "La modifica della password reimposterà qualsiasi chiave di cifratura end-to-end su tutte le sessioni, rendendo illeggibile la cronologia delle chat cifrate. Configura il Backup Chiavi o esporta le tue chiavi della stanza da un'altra sessione prima di reimpostare la password.", + "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Sei stato disconnesso da tutte le sessioni e non riceverai più notifiche push. Per riattivare le notifiche, riaccedi su ogni dispositivo.", + "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Riprendi l'accesso al tuo account e recupera le chiavi di cifratura memorizzate in questa sessione. Senza di esse, non sarai in grado di leggere tutti i tuoi messaggi sicuri in qualsiasi sessione.", + "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Attenzione: i tuoi dati personali (incluse le chiavi di cifratura) sono ancora memorizzati in questa sessione. Cancellali se hai finito di usare questa sessione o se vuoi accedere ad un altro account.", + "Sender session information": "Informazioni sessione del mittente", + "Restore your key backup to upgrade your encryption": "Ripristina il tuo backup chiavi per aggiornare la cifratura", + "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Aggiorna questa sessione per consentirle di verificare altre sessioni, garantendo loro l'accesso ai messaggi cifrati e contrassegnandole come fidate per gli altri utenti.", + "Set up encryption on this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Imposta la cifratura su questa sessione per consentirle di verificare le altre sessioni, garantendo loro l'accesso ai messaggi cifrati e contrassegnandole come fidate per gli altri utenti.", + "Back up my encryption keys, securing them with the same passphrase": "Fai il backup delle mie chiavi di cifratura, proteggendole con la stessa password", + "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Conservane una copia in un luogo sicuro, come un gestore di password o una cassaforte.", + "Your recovery key": "La tua chiave di recupero", + "Copy": "Copia", + "You can now verify your other devices, and other users to keep your chats safe.": "Ora puoi verificare i tuoi altri dispositivi e gli altri utenti per tenere al sicuro le tue chat.", + "Make a copy of your recovery key": "Fai una copia della chiave di recupero", + "You're done!": "Hai finito!", + "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Senza configurare il Recupero Messaggi Sicuri, non potrai ripristinare la cronologia di messaggi cifrati se ti disconnetti o se usi un'altra sessione.", + "Create key backup": "Crea backup chiavi", + "This session is encrypting history using the new recovery method.": "Questa sessione sta cifrando la cronologia usando il nuovo metodo di recupero.", + "This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "Questa sessione ha rilevato che la tua password di recupero e la chiave per i Messaggi Sicuri sono state rimosse.", + "If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "Se l'hai fatto accidentalmente, puoi configurare Messaggi Sicuri su questa sessione che cripterà nuovamente la cronologia dei messaggi con un nuovo metodo di recupero.", + "If disabled, messages from encrypted rooms won't appear in search results.": "Se disattivato, i messaggi delle stanze cifrate non appariranno nei risultati di ricerca.", + "Disable": "Disattiva", + "Not currently downloading messages for any room.": "Nessuno scaricamento di messaggi in corso per alcuna stanza.", + "Downloading mesages for %(currentRoom)s.": "Scaricamento messaggi per %(currentRoom)s.", + "Riot is securely caching encrypted messages locally for them to appear in search results:": "Riot sta tenendo in cache localmente i messaggi cifrati in modo sicuro affinché appaiano nei risultati di ricerca:", + "of ": "di ", + "Message downloading sleep time(ms)": "Tempo di attesa scaricamento messaggi (ms)" } From c93e098d4cd3485f6b4c5d11711b7ee15a2f1731 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 6 Feb 2020 13:27:51 +0000 Subject: [PATCH 026/268] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2101 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 668725c4aa..8cf4f7706e 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2126,5 +2126,7 @@ "You're done!": "您已經完成了!", "Create key backup": "建立金鑰備份", "Message downloading sleep time(ms)": "訊息下載休眠時間(毫秒)", - "of ": "的 " + "of ": "的 ", + "Indexed rooms:": "已索引的聊天室:", + "%(crawlingRooms)s out of %(totalRooms)s": "%(totalRooms)s 中的 %(crawlingRooms)s" } From fba314d65f0b7f8bada5077f992a506ea5da0b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanislav=20Luke=C5=A1?= Date: Thu, 6 Feb 2020 12:55:20 +0000 Subject: [PATCH 027/268] Translated using Weblate (Czech) Currently translated at 96.1% (2020 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 3adc393e0a..5941fdedb4 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -2010,5 +2010,35 @@ "%(count)s sessions|one": "%(count)s relace", "Hide sessions": "Skrýt relace", "Verify by emoji": "Ověřit emotikonami", - "Verify by comparing unique emoji.": "Oveření porovnáním několika emotikon." + "Verify by comparing unique emoji.": "Oveření porovnáním několika emotikon.", + "Ask %(displayName)s to scan your code:": "Ověříte se, když %(displayName)s naskenuje váš kód:", + "If you can't scan the code above, verify by comparing unique emoji.": "Pokud vám skenování kódů nefunguje, ověřte se porovnáním emotikon.", + "You've successfully verified %(displayName)s!": "%(displayName)s je úspěšně ověřen/a!", + "Got it": "Dobře", + "Verification timed out. Start verification again from their profile.": "Čas na verifikaci vypršel. Začněte s verifikací znovu z druhého profilu.", + "%(displayName)s cancelled verification. Start verification again from their profile.": "%(displayName)s zrušil/a verifikaci. Začněte s verifikací znovu z druhého profilu.", + "Encryption enabled": "Šifrování je zapnuté", + "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Zprávy v této místnosti jsou E2E šifrované. Více informací & verifikace uživatele je v jeho profilu.", + "Encryption not enabled": "Šifrování je vypnuté", + "The encryption used by this room isn't supported.": "Šifrování používané v této místnosti není podporované.", + "Clear all data in this session?": "Smazat všechna data v této relaci?", + "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Výmaz všech dat v relaci je nevratný. Pokud nemáte zálohované šifrovací klíče, přijdete o šifrované zprávy.", + "Verify session": "Ověřit relaci", + "To verify that this session can be trusted, please check that the key you see in User Settings on that device matches the key below:": "Abychom ověřili, že je relace důvěryhodná, zkontrolujte prosím, že klíč v uživatelském nastavení na tom zařízení odpovídá následujícímu klíči:", + "To verify that this session 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 session matches the key below:": "Abychom ověřili, že tato relace je důvěryhodná, kontaktujte prosím jejího vlastníka nějakým dalším způsobem (osobně, telefonicky, apod.). Zkontrolujte spolu, že klíč v uživatelském nastavení na druhém zařízení odpovídá následujícímu klíči:", + "Session name": "Jméno relace", + "Session key": "Klíč relace", + "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this session and you probably want to press the blacklist button instead.": "Pokud odpovídá, zmáčkněte tlačítko ověřit. Pokud ne, druhé zařízení je pravděpodobně falešné a chcete ho zablokovat.", + "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Ověření uživatele označí jeho relace za důvěryhodné a Vaše relace budou důvěryhodné pro něj.", + "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Ověření zařízení ho označí za důvěryhodné. Ověření konkrétního zařízení vám dát trochu klidu mysli navíc při používání šifrovaných zpráv.", + "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Ověření zařízení ho označí za důvěryhodné a uživatelé, kteří věří vám budou také tomuto zařízení důvěřovat.", + "Failed to invite the following users to chat: %(csvUsers)s": "Následující uživatele se nepovedlo pozvat do chatu: %(csvUsers)s", + "We couldn't create your DM. Please check the users you want to invite and try again.": "Nepovedlo se nám vyrobit soukromou konverzaci. Zkontrolujte prosím, že pozvaný uživatel opravdu existuje a pak to zkuste znovu.", + "Something went wrong trying to invite the users.": "Při odesílání pozvánek se něco pokazilo.", + "We couldn't invite those users. Please check the users you want to invite and try again.": "Nemůžeme pozvat tyto uživatele. Zkontrolujte prosím, že opravdu existují a zkuste to znovu.", + "Failed to find the following users": "Nepovedlo se najít následující uživatele", + "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Následující uživatelé asi neexistují nebo jsou neplatní a nelze je pozvat: %(csvNames)s", + "Recent Conversations": "Nedávné konverzace", + "Suggestions": "Návrhy", + "Recently Direct Messaged": "Nedávno kontaktovaní" } From cf7ad725a60765f8d98cbe1234e172e895cdaf39 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 6 Feb 2020 15:06:36 +0100 Subject: [PATCH 028/268] copy and i18n --- src/CrossSigningManager.js | 2 +- src/i18n/strings/en_EN.json | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index 8feb651ea5..15daede92b 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -89,7 +89,7 @@ async function getSecretStorageKey({ keys: keyInfos }) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const [sure] = await Modal.createDialog(QuestionDialog, { title: _t("Cancel entering passphrase?"), - description: _t("If you cancel now, you won't complete your SSSS operation!"), + description: _t("If you cancel now, you won't complete your secret storage operation!"), }).finished; return sure; }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index d125d10cfb..6fb4b86aac 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -60,6 +60,8 @@ "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", "The server does not support the room version specified.": "The server does not support the room version specified.", "Failure to create room": "Failure to create room", + "Cancel entering passphrase?": "Cancel entering passphrase?", + "If you cancel now, you won't complete your secret storage operation!": "If you cancel now, you won't complete your secret storage operation!", "Setting up keys": "Setting up keys", "Send anyway": "Send anyway", "Send": "Send", From a8958458aae19f546c185b67cc6b6ba153a48fb4 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 6 Feb 2020 15:29:35 +0100 Subject: [PATCH 029/268] fix lint, add jsdoc --- src/Modal.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Modal.js b/src/Modal.js index f55e497e6f..de441740f1 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -170,6 +170,12 @@ class ModalManager { }, deferred.promise]; } + /** + * @callback onBeforeClose + * @param {string?} reason either "backgroundClick" or null + * @return {Promise} whether the dialog should close + */ + /** * Open a modal view. * @@ -197,6 +203,8 @@ class ModalManager { * also be removed from the stack. This is not compatible * with being a priority modal. Only one modal can be * static at a time. + * @param {Object} options? extra options for the dialog + * @param {onBeforeClose} options.onBeforeClose a callback to decide whether to close the dialog * @returns {object} Object with 'close' parameter being a function that will close the dialog */ createDialogAsync(prom, props, className, isPriorityModal, isStaticModal, options = {}) { From 02d169060daa466df4b3db45b0e373f0c90c057b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 6 Feb 2020 16:51:02 +0100 Subject: [PATCH 030/268] differentiate dismiss dialog based on name passed from js-sdk also make dialog a bit nicer with more descriptive button --- src/CrossSigningManager.js | 34 +++++++++++++++++++++++++--------- src/i18n/strings/en_EN.json | 8 +++++--- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index 15daede92b..694b2b0a25 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -43,7 +43,28 @@ export class AccessCancelledError extends Error { } } -async function getSecretStorageKey({ keys: keyInfos }) { +async function confirmToDismiss(name) { + let description; + if (name === "m.cross_signing.user_signing") { + description = _t("If you cancel now, you won't complete verifying the other user."); + } else if (name === "m.cross_signing.self_signing") { + description = _t("If you cancel now, you won't complete verifying your other session."); + } else { + description = _t("If you cancel now, you won't complete your secret storage operation."); + } + + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const [sure] = await Modal.createDialog(QuestionDialog, { + title: _t("Cancel entering passphrase?"), + description, + danger: true, + cancelButton: _t("Enter passphrase"), + button: _t("Cancel"), + }).finished; + return sure; +} + +async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) { const keyInfoEntries = Object.entries(keyInfos); if (keyInfoEntries.length > 1) { throw new Error("Multiple storage key requests not implemented"); @@ -83,15 +104,10 @@ async function getSecretStorageKey({ keys: keyInfos }) { /* isStaticModal= */ false, /* options= */ { onBeforeClose: async (reason) => { - if (reason !== "backgroundClick") { - return true; + if (reason === "backgroundClick") { + return confirmToDismiss(ssssItemName); } - const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); - const [sure] = await Modal.createDialog(QuestionDialog, { - title: _t("Cancel entering passphrase?"), - description: _t("If you cancel now, you won't complete your secret storage operation!"), - }).finished; - return sure; + return true; }, }, ); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6fb4b86aac..2e21f08447 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -60,8 +60,12 @@ "Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.", "The server does not support the room version specified.": "The server does not support the room version specified.", "Failure to create room": "Failure to create room", + "If you cancel now, you won't complete verifying the other user.": "If you cancel now, you won't complete verifying the other user.", + "If you cancel now, you won't complete verifying your other session.": "If you cancel now, you won't complete verifying your other session.", + "If you cancel now, you won't complete your secret storage operation.": "If you cancel now, you won't complete your secret storage operation.", "Cancel entering passphrase?": "Cancel entering passphrase?", - "If you cancel now, you won't complete your secret storage operation!": "If you cancel now, you won't complete your secret storage operation!", + "Enter passphrase": "Enter passphrase", + "Cancel": "Cancel", "Setting up keys": "Setting up keys", "Send anyway": "Send anyway", "Send": "Send", @@ -452,7 +456,6 @@ "Verify this device by confirming the following number appears on its screen.": "Verify this device by confirming the following number appears on its 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.", "Unable to find a supported verification method.": "Unable to find a supported verification method.", - "Cancel": "Cancel", "Waiting for %(displayName)s to verify…": "Waiting for %(displayName)s to verify…", "They match": "They match", "They don't match": "They don't match", @@ -2022,7 +2025,6 @@ "Export room keys": "Export room keys", "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.", "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.", - "Enter passphrase": "Enter passphrase", "Confirm passphrase": "Confirm passphrase", "Export": "Export", "Import room keys": "Import room keys", From 1105c14fdd41dec71a8a531ece2c76c01ab7552b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanislav=20Luke=C5=A1?= Date: Thu, 6 Feb 2020 13:53:52 +0000 Subject: [PATCH 031/268] Translated using Weblate (Czech) Currently translated at 98.0% (2059 of 2101 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/cs/ --- src/i18n/strings/cs.json | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json index 5941fdedb4..97ca508e04 100644 --- a/src/i18n/strings/cs.json +++ b/src/i18n/strings/cs.json @@ -2040,5 +2040,44 @@ "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Následující uživatelé asi neexistují nebo jsou neplatní a nelze je pozvat: %(csvNames)s", "Recent Conversations": "Nedávné konverzace", "Suggestions": "Návrhy", - "Recently Direct Messaged": "Nedávno kontaktovaní" + "Recently Direct Messaged": "Nedávno kontaktovaní", + "If you can't find someone, ask them for their username, share your username (%(userId)s) or profile link.": "Pokud někoho nemůžete nalézt, zeptejte se na username, pošlete jim svůj (%(userId)s) a nebo pošlete odkaz na svůj profil.", + "Go": "Ok", + "If you can't find someone, ask them for their username (e.g. @user:server.com) or share this room.": "Pokud někoho nemůžete nalézt, zeptejte se na username (například @user:server.com) a nebo pošlete odkaz na tuto místnost.", + "You added a new session '%(displayName)s', which is requesting encryption keys.": "Přidali jste novou relaci '%(displayName)s', která požaduje šifrovací klíče.", + "Your unverified session '%(displayName)s' is requesting encryption keys.": "Vaše neověřená relace '%(displayName)s' požaduje šifrovací klíče.", + "Loading session info...": "Načítám informace o relaci...", + "New session": "Nová relace", + "Use this session to verify your new one, granting it access to encrypted messages:": "Použijte tuto relaci abyste ověřili novou a dali jí přístup ke svým šifrovaným zprávám:", + "If you didn’t sign in to this session, your account may be compromised.": "Pokud jste se do této nové relace nepřihlásili, váš účet může být kompromitován.", + "This wasn't me": "Nebyl/a jsem to já", + "This will allow you to return to your account after signing out, and sign in on other sessions.": "Umožní vám to se přihlásit do dalších relací a vrátit se ke svému účtu poté co se odhlásíte.", + "You are currently blacklisting unverified sessions; to send messages to these sessions you must verify them.": "Máte zakázané posílání zpráv neověřeným relacím; abyste mohli zprávu odeslat, musíte je ověřit.", + "We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Doporučujeme si projít ověřovací proces pro každou relaci abyste ověřili, že patří tomu, komu očekáváte. Můžete ale poslat zprávu i bez ověření, pokud chcete.", + "Room contains unknown sessions": "V místnosti jsou neověřené relace", + "\"%(RoomName)s\" contains sessions that you haven't seen before.": "V místnosti \"%(RoomName)s\" jsou relace, které jste ještě nikdy neviděli.", + "Unknown sessions": "Neznámá relace", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your passphrase.": "Zadejte svoje heslo a získejte přístup k bezpečnému úložišti historie zpráv a k identitě pro cross-signing pro snadné ověřování vašich relací.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.": "Zadejte svůj obnovovací klíč a získejte přístup k bezpečnému úložišti historie zpráv a k identitě pro cross-signing pro snadné ověřování vašich relací.", + "Recovery key mismatch": "Obnovovací klíč neodpovídá", + "Incorrect recovery passphrase": "Nesprávné heslo pro obnovení", + "Backup restored": "Záloha byla nahrána", + "Enter recovery passphrase": "Zadejte heslo pro obnovení zálohy", + "Enter recovery key": "Zadejte obnovovací klíč", + "Confirm your identity by entering your account password below.": "Potvrďte svou identitu zadáním hesla ke svému účtu.", + "Message not sent due to unknown sessions being present": "Zpráva nebyla odeslána, protože jsou v místnosti neznámé relace", + "Show sessions, send anyway or cancel.": "Zobrazit relace, i tak odeslat, a nebo zrušit.", + "Verify this session to grant it access to encrypted messages.": "Ověřte relaci aby získala přístup k šifrovaným zprávám.", + "Start": "Začít", + "Session verified": "Relace je ověřena", + "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Vaše nová relace je teď ověřená. Má přístup k šifrovaným zprávám a ostatní uživatelé jí budou věřit.", + "Your new session is now verified. Other users will see it as trusted.": "Vaše nová relace je teď ověřená. Ostatní uživatelé jí budou věřit.", + "Done": "Hotovo", + "Without completing security on this session, it won’t have access to encrypted messages.": "Bez dokončení ověření nebude mít nová relace přístup k šifrovaným zprávám.", + "Go Back": "Zpět", + "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Změna hesla resetuje šifrovací klíče ve všech vašich přihlášených relacích a přijdete tak o přístup k historickým zprávám. Před změnou hesla si nastavte zálohu klíčů nebo si klíče pro místnosti exportujte.", + "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Všude jsme Vás odhlásili, takže nedostáváte žádné upozornění. Můžete je znovu povolit tím, že se na všech svych zařízeních znovu přihlásíte.", + "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Získejte znovu přístup k účtu a obnovte si šifrovací klíče uložené v této relaci. Bez nich nebudete schopni číst zabezpečené zprávy na některých zařízeních.", + "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Varování: Vaše osobní data (včetně šifrovacích klíčů) jsou tu pořád uložena. Smažte je, pokud chcete tuto relaci zahodit nebo se přihlašte pod jiný účet.", + "Sender session information": "Informace o relaci odesílatele" } From c916ef453490b718854989ca2a74ac476b61934a Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 6 Feb 2020 17:57:17 +0000 Subject: [PATCH 032/268] Only emit in RoomViewStore when state actually changes This adds a shallow state check to attempt to only emit a store update when something actually changes. Fixes https://github.com/vector-im/riot-web/issues/12256 --- src/stores/RoomViewStore.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 9bcc2815e6..64dfd56b2f 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -66,6 +66,20 @@ class RoomViewStore extends Store { } _setState(newState) { + // If values haven't changed, there's nothing to do. + // This only tries a shallow comparison, so unchanged objects will slip + // through, but that's probably okay for now. + let stateChanged = false; + for (const key of Object.keys(newState)) { + if (this._state[key] !== newState[key]) { + stateChanged = true; + break; + } + } + if (!stateChanged) { + return; + } + this._state = Object.assign(this._state, newState); this.__emitChange(); } From f620cc05e24d843a322c1d1443a2e1ea105a2036 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 6 Feb 2020 20:01:09 +0000 Subject: [PATCH 033/268] Translated using Weblate (Hungarian) Currently translated at 99.7% (2097 of 2103 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index b8d14774d6..d3a77a6bcc 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2090,5 +2090,35 @@ "We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Javasoljuk, hogy minden munkamenetet ellenőrizz, hogy a tényleges tulajdonosához tartoznak vagy újraküldheted az üzenetet ha akarod anélkül, hogy ellenőriznéd őket.", "Room contains unknown sessions": "A szoba ismeretlen munkameneteket tartalmaz", "\"%(RoomName)s\" contains sessions that you haven't seen before.": "\"%(RoomName)s\" még nem látott munkameneteket tartalmaz.", - "Unknown sessions": "Ismeretlen munkamenetek" + "Unknown sessions": "Ismeretlen munkamenetek", + "Cancel entering passphrase?": "Megszakítod a jelmondat bevitelét?", + "If you cancel now, you won't complete your secret storage operation!": "Ha most megszakítod, akkor nem fejezed be a biztonságos tárolóval kapcsolatos műveletet!", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your passphrase.": "A jelmondat megadásával hozzáférhetsz a biztonságos üzeneteidhez és az eszközök közötti hitelesítéshez használt személyazonosságodhoz, hogy más munkameneteket hitelesíthess.", + "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.": "A visszaállítási kulcs megadásával hozzáférhetsz a biztonságos üzeneteidhez és az eszközök közötti hitelesítéshez használt személyazonosságodhoz, hogy más munkameneteket hitelesíthess.", + "Recovery key mismatch": "A visszaállítási kulcs nem megfelelő", + "Incorrect recovery passphrase": "A visszaállítási jelmondat helytelen", + "Backup restored": "Mentés visszaállítva", + "Enter recovery passphrase": "Visszaállítási jelmondat megadása", + "Enter recovery key": "Visszaállítási kulcs megadása", + "Confirm your identity by entering your account password below.": "A fiók jelszó megadásával erősítsd meg a személyazonosságodat.", + "Message not sent due to unknown sessions being present": "Ismeretlen munkamenet miatt az üzenet nem került elküldésre", + "Show sessions, send anyway or cancel.": "Munkamenetek megmutatása, küldés mindenképpen vagy küldés megszakítása.", + "Your new session is now verified. Other users will see it as trusted.": "Az új munkameneted ellenőrizve. Mások megbízhatónak fogják látni.", + "Without completing security on this session, it won’t have access to encrypted messages.": "Amíg a biztonság nincs beállítva a munkameneten nem fér hozzá a titkosított üzenetekhez.", + "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "A jelszó változtatás minden munkamenet végpontok közötti titkosító kulcsait alaphelyzetbe állítja, ezáltal a titkosított üzenetek olvashatatlanok lesznek, hacsak először nem mented ki a szobák kulcsait és töltöd vissza jelszóváltoztatás után. A jövőben ezt egyszerűsítjük majd.", + "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Kijelentkeztettünk minden eszközödből és nem kapsz értesítéseket sem. Az értesítések újra engedélyezéséhez jelentkezz be újra az eszközökön.", + "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Szerezd vissza a hozzáférést a fiókodhoz és állítsd vissza az elmentett titkosítási kulcsokat ebben a munkamenetben. Ezek nélkül egyetlen munkamenetben sem tudod elolvasni a titkosított üzeneteidet.", + "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Figyelmeztetés: A személyes adataid (beleértve a titkosító kulcsokat is) továbbra is az eszközön vannak tárolva. Ha az eszközt nem használod tovább vagy másik fiókba szeretnél bejelentkezni, töröld őket.", + "Sender session information": "Küldő munkamenet információ", + "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Fejleszd ezt a munkamenetet, hogy más munkamenetet tudj vele hitelesíteni amivel hozzáférnek a titkosított üzenetekhez és megbízhatónak lesznek jelölve más felhasználók számára.", + "Set up encryption on this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Állítsd be a titkosítást ezen a munkameneten, hogy más munkamenetet tudj vele hitelesíteni amivel hozzáférnek a titkosított üzenetekhez és megbízhatónak lesznek jelölve más felhasználók számára.", + "Back up my encryption keys, securing them with the same passphrase": "Mentsd el a titkosítási kulcsaimat és védd őket ugyanazzal a jelmondattal", + "Keep a copy of it somewhere secure, like a password manager or even a safe.": "A másolatot tartsd biztonságos helyen, mint pl. egy jelszókezelő (vagy széf).", + "Your recovery key": "Visszaállítási kulcsod", + "Copy": "Másol", + "You can now verify your other devices, and other users to keep your chats safe.": "Már ellenőrizheted a többi eszközödet és más felhasználókat, hogy a beszélgetéseidet biztonságban tudhasd.", + "Make a copy of your recovery key": "Készíts másolatot a visszaállítási kulcsodról", + "You're done!": "Kész!", + "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "A Biztonságos Üzenet Visszaállítás beállítása nélkül kijelentkezés után vagy másik munkamenetet használva nem tudod visszaállítani a titkosított üzeneteidet.", + "Create key backup": "Kulcs mentés készítése" } From 2bafc1ebc895eff36da70932b034363c7d039bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20C?= Date: Fri, 7 Feb 2020 08:01:44 +0000 Subject: [PATCH 034/268] Translated using Weblate (French) Currently translated at 100.0% (2103 of 2103 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index cc79b5c9fc..e1bf47569d 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -2126,5 +2126,9 @@ "If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "Si vous l’avez fait accidentellement, vous pouvez configurer les messages sécurisés sur cette session ce qui re-chiffrera l’historique des messages de cette session avec une nouvelle méthode de récupération.", "How fast should messages be downloaded.": "À quelle fréquence les messages doivent être téléchargés.", "of ": "sur ", - "Message downloading sleep time(ms)": "Temps d’attente de téléchargement des messages (ms)" + "Message downloading sleep time(ms)": "Temps d’attente de téléchargement des messages (ms)", + "Cancel entering passphrase?": "Annuler la saisie de la phrase de passe ?", + "If you cancel now, you won't complete your secret storage operation!": "Si vous annulez maintenant, vous ne terminerez pas votre opération du coffre secret !", + "Indexed rooms:": "Salons indexés :", + "%(crawlingRooms)s out of %(totalRooms)s": "%(crawlingRooms)s sur %(totalRooms)s" } From 6d0aab2a2d62d67c0d843a48478f8b1fb69e8572 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 7 Feb 2020 08:55:03 +0000 Subject: [PATCH 035/268] Translated using Weblate (French) Currently translated at 100.0% (2103 of 2103 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/fr/ --- src/i18n/strings/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index e1bf47569d..940f850df1 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -1153,7 +1153,7 @@ "Waiting for partner to confirm...": "Nous attendons que le partenaire confirme…", "Incoming Verification Request": "Demande de vérification entrante", "Go back": "Revenir en arrière", - "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "Pour éviter la duplication d'issues, veuillez voir les issues existantsd'abord (et ajouter un +1) ou créer un nouvel issue si vous ne le trouvez pas.", + "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "Pour éviter la duplication de problèmes, veuillez voir les problèmes existants d'abord (et ajouter un +1) ou créer un nouveau problème si vous ne le trouvez pas.", "Report bugs & give feedback": "Rapporter des anomalies & Donner son avis", "Backup could not be decrypted with this key: please verify that you entered the correct recovery key.": "La sauvegarde n'a pas pu être déchiffrée avec cette clé : veuillez vérifier que vous avez saisi la bonne clé de récupération.", "Update status": "Mettre à jour le statut", From 9a0bc15548f9d0eea82e95477462cf11d1116e6d Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 6 Feb 2020 21:13:47 +0000 Subject: [PATCH 036/268] Translated using Weblate (Hungarian) Currently translated at 100.0% (2103 of 2103 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/hu/ --- src/i18n/strings/hu.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index d3a77a6bcc..14ba143c10 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -2120,5 +2120,11 @@ "Make a copy of your recovery key": "Készíts másolatot a visszaállítási kulcsodról", "You're done!": "Kész!", "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "A Biztonságos Üzenet Visszaállítás beállítása nélkül kijelentkezés után vagy másik munkamenetet használva nem tudod visszaállítani a titkosított üzeneteidet.", - "Create key backup": "Kulcs mentés készítése" + "Create key backup": "Kulcs mentés készítése", + "This session is encrypting history using the new recovery method.": "Ez a munkamenet az új visszaállítási metódussal titkosítja a régi üzeneteket.", + "This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "A munkamenet észrevette, hogy a visszaállítási jelmondat és a kulcs a Biztonságos Üzenetekhez törölve lett.", + "If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "Ha véletlenül tetted, beállíthatod a Biztonságos Üzeneteket ezen a munkameneten ami újra titkosítja a régi üzeneteket az visszaállítási eljárással.", + "Indexed rooms:": "Indexált szobák:", + "%(crawlingRooms)s out of %(totalRooms)s": "%(crawlingRooms)s / %(totalRooms)s", + "Message downloading sleep time(ms)": "Üzenet letöltés alvási idő (ms)" } From fa13bb96893d242efff8250b13d083cea954ce31 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Jan 2020 18:50:44 +0100 Subject: [PATCH 037/268] make the verif toast work with to_device request that do .request/.ready --- .../views/toasts/VerificationRequestToast.js | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/components/views/toasts/VerificationRequestToast.js b/src/components/views/toasts/VerificationRequestToast.js index 5125e20261..0c5d29ebe6 100644 --- a/src/components/views/toasts/VerificationRequestToast.js +++ b/src/components/views/toasts/VerificationRequestToast.js @@ -58,10 +58,7 @@ export default class VerificationRequestToast extends React.PureComponent { _checkRequestIsPending = () => { const {request} = this.props; - const isPendingInRoomRequest = request.channel.roomId && - !(request.ready || request.started || request.done || request.cancelled || request.observeOnly); - const isPendingDeviceRequest = request.channel.deviceId && request.started; - if (!isPendingInRoomRequest && !isPendingDeviceRequest) { + if (request.done || request.cancelled || request.observeOnly) { ToastStore.sharedInstance().dismissToast(this.props.toastKey); } }; @@ -79,6 +76,7 @@ export default class VerificationRequestToast extends React.PureComponent { ToastStore.sharedInstance().dismissToast(this.props.toastKey); const {request} = this.props; // no room id for to_device requests + const cli = MatrixClientPeg.get(); try { if (request.channel.roomId) { dis.dispatch({ @@ -86,23 +84,29 @@ export default class VerificationRequestToast extends React.PureComponent { room_id: request.channel.roomId, should_peek: false, }); - await request.accept(); - const cli = MatrixClientPeg.get(); + } else { dis.dispatch({ - action: "set_right_panel_phase", - phase: RIGHT_PANEL_PHASES.EncryptionPanel, - refireParams: { - verificationRequest: request, - member: cli.getUser(request.otherUserId), - }, + action: 'view_room', + room_id: cli.getRooms()[0].roomId, + should_peek: false, }); - } else if (request.channel.deviceId && request.verifier) { - // show to_device verifications in dialog still - const IncomingSasDialog = sdk.getComponent("views.dialogs.IncomingSasDialog"); - Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, { - verifier: request.verifier, - }, null, /* priority = */ false, /* static = */ true); } + await request.accept(); + dis.dispatch({ + action: "set_right_panel_phase", + phase: RIGHT_PANEL_PHASES.EncryptionPanel, + refireParams: { + verificationRequest: request, + member: cli.getUser(request.otherUserId), + }, + }); + // } else if (request.channel.deviceId && request.verifier) { + // // show to_device verifications in dialog still + // const IncomingSasDialog = sdk.getComponent("views.dialogs.IncomingSasDialog"); + // Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, { + // verifier: request.verifier, + // }, null, /* priority = */ false, /* static = */ true); + // } } catch (err) { console.error(err.message); } From 049a6d2064605c521e53fe91f19b3e86e4bd3976 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Sun, 2 Feb 2020 10:25:05 +0100 Subject: [PATCH 038/268] hide toast when request is accepted if this is a .request > .ready request, dismissing when in .ready is what we want, as that is how you accept the request if this is a .start request, we shouldn't dismiss so only add .ready to the phases to hide the toast, not .started --- src/components/views/toasts/VerificationRequestToast.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/toasts/VerificationRequestToast.js b/src/components/views/toasts/VerificationRequestToast.js index 0c5d29ebe6..a5a26f7ddb 100644 --- a/src/components/views/toasts/VerificationRequestToast.js +++ b/src/components/views/toasts/VerificationRequestToast.js @@ -58,7 +58,7 @@ export default class VerificationRequestToast extends React.PureComponent { _checkRequestIsPending = () => { const {request} = this.props; - if (request.done || request.cancelled || request.observeOnly) { + if (request.ready || request.done || request.cancelled || request.observeOnly) { ToastStore.sharedInstance().dismissToast(this.props.toastKey); } }; From 413a149b4713feded25cc23f912200871c456188 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Sun, 2 Feb 2020 10:47:15 +0100 Subject: [PATCH 039/268] disable "Accept"/"Decline" buttons on verif tile after clicking to avoid sending double events --- src/components/views/messages/MKeyVerificationRequest.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/messages/MKeyVerificationRequest.js b/src/components/views/messages/MKeyVerificationRequest.js index ab02b2e5ad..9a48858bc7 100644 --- a/src/components/views/messages/MKeyVerificationRequest.js +++ b/src/components/views/messages/MKeyVerificationRequest.js @@ -27,6 +27,7 @@ import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases"; export default class MKeyVerificationRequest extends React.Component { constructor(props) { super(props); + this.state = {}; } componentDidMount() { @@ -58,6 +59,7 @@ export default class MKeyVerificationRequest extends React.Component { }; _onAcceptClicked = async () => { + this.setState({acceptOrCancelClicked: true}); const request = this.props.mxEvent.verificationRequest; if (request) { try { @@ -70,6 +72,7 @@ export default class MKeyVerificationRequest extends React.Component { }; _onRejectClicked = async () => { + this.setState({acceptOrCancelClicked: true}); const request = this.props.mxEvent.verificationRequest; if (request) { try { @@ -135,9 +138,10 @@ export default class MKeyVerificationRequest extends React.Component { subtitle = (
{ userLabelForEventRoom(request.requestingUserId, mxEvent.getRoomId())}
); if (request.requested && !request.observeOnly) { + const disabled = this.state.acceptOrCancelClicked; stateNode = (
- - + +
); } } else { // request sent by us From 577121e88d43513f66b8803257b186ca23d44f90 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Sun, 2 Feb 2020 10:48:02 +0100 Subject: [PATCH 040/268] disable "verify by emoji" after clicking it --- src/components/views/right_panel/VerificationPanel.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/right_panel/VerificationPanel.js b/src/components/views/right_panel/VerificationPanel.js index 3527747a66..f925508be6 100644 --- a/src/components/views/right_panel/VerificationPanel.js +++ b/src/components/views/right_panel/VerificationPanel.js @@ -62,8 +62,9 @@ export default class VerificationPanel extends React.PureComponent { if (pending) { button = ; } else { + const disabled = this.state.emojiButtonClicked; button = ( - + {_t("Verify by emoji")} ); @@ -196,6 +197,7 @@ export default class VerificationPanel extends React.PureComponent { } _startSAS = async () => { + this.setState({emojiButtonClicked: true}); const verifier = this.props.request.beginKeyVerification(verificationMethods.SAS); try { await verifier.verify(); From 8fdae73e030546decf346d0f23a9c956faa456e2 Mon Sep 17 00:00:00 2001 From: Zoe Date: Fri, 7 Feb 2020 14:55:01 +0000 Subject: [PATCH 041/268] Button to reset cross-signing and SSSS keys --- src/CrossSigningManager.js | 11 ++-- .../CreateSecretStorageDialog.js | 10 ++- .../ConfirmDestroyCrossSigningDialog.js | 63 +++++++++++++++++++ .../views/settings/CrossSigningPanel.js | 24 ++++++- src/i18n/strings/en_EN.json | 4 ++ 5 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index a560c956f1..08ec459f26 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -116,17 +116,20 @@ export const crossSigningCallbacks = { * @param {Function} [func] An operation to perform once secret storage has been * bootstrapped. Optional. */ -export async function accessSecretStorage(func = async () => { }) { +export async function accessSecretStorage(func = async () => { }, force = false) { const cli = MatrixClientPeg.get(); secretStorageBeingAccessed = true; - try { - if (!await cli.hasSecretStorageKey()) { + if (!await cli.hasSecretStorageKey() || force) { + console.warn(!force ? "!hasSecretStorageKey()" : "force"); // This dialog calls bootstrap itself after guiding the user through // passphrase creation. const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '', import("./async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"), - null, null, /* priority = */ false, /* static = */ true, + { + force, + }, + null, /* priority = */ false, /* static = */ true, ); const [confirmed] = await finished; if (!confirmed) { diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 679b3907d1..c3574c0094 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -55,10 +55,12 @@ export default class CreateSecretStorageDialog extends React.PureComponent { static propTypes = { hasCancel: PropTypes.bool, accountPassword: PropTypes.string, + force: PropTypes.bool, }; static defaultProps = { hasCancel: true, + force: false, }; constructor(props) { @@ -107,7 +109,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent { MatrixClientPeg.get().isCryptoEnabled() && await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo) ); - const phase = backupInfo ? PHASE_MIGRATE : PHASE_PASSPHRASE; + const { force } = this.props; + const phase = (backupInfo && !force) ? PHASE_MIGRATE : PHASE_PASSPHRASE; this.setState({ phase, @@ -219,12 +222,15 @@ export default class CreateSecretStorageDialog extends React.PureComponent { const cli = MatrixClientPeg.get(); + const { force } = this.props; + try { await cli.bootstrapSecretStorage({ + setupNewSecretStorage: force, authUploadDeviceSigningKeys: this._doBootstrapUIAuth, createSecretStorageKey: async () => this._keyInfo, keyBackupInfo: this.state.backupInfo, - setupNewKeyBackup: !this.state.backupInfo && this.state.useKeyBackup, + setupNewKeyBackup: force || !this.state.backupInfo && this.state.useKeyBackup, }); this.setState({ phase: PHASE_DONE, diff --git a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js new file mode 100644 index 0000000000..942249e07d --- /dev/null +++ b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js @@ -0,0 +1,63 @@ +/* +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 {_t} from "../../../languageHandler"; +import * as sdk from "../../../index"; + +export default class ConfirmDestroyCrossSigningDialog extends React.Component { + static propTypes = { + onFinished: PropTypes.func.isRequired, + }; + + _onConfirm = () => { + this.props.onFinished(true); + }; + + _onDecline = () => { + this.props.onFinished(false); + }; + + render() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + + return ( + +
+

+ {_t( + "Deleting cross-signing keys is permanent. " + + "Anyone you have verified with will see security alerts. " + + "You almost certainly don't want to do this, unless " + + "you've lost every device you can cross-sign from." + )} +

+
+ +
+ ); + } +} diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js index f99968c44f..35f617b83b 100644 --- a/src/components/views/settings/CrossSigningPanel.js +++ b/src/components/views/settings/CrossSigningPanel.js @@ -20,6 +20,7 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; import { accessSecretStorage } from '../../../CrossSigningManager'; +import Modal from '../../../Modal'; export default class CrossSigningPanel extends React.PureComponent { constructor(props) { @@ -87,10 +88,10 @@ export default class CrossSigningPanel extends React.PureComponent { * cross-signing keys as needed. * 3. All keys are loaded and there's nothing to do. */ - _bootstrapSecureSecretStorage = async () => { + _bootstrapSecureSecretStorage = async (force=false) => { this.setState({ error: null }); try { - await accessSecretStorage(); + await accessSecretStorage(() => undefined, force); } catch (e) { this.setState({ error: e }); console.error("Error bootstrapping secret storage", e); @@ -99,6 +100,19 @@ export default class CrossSigningPanel extends React.PureComponent { this._getUpdatedStatus(); } + onDestroyStorage = (act) => { + if (!act) return; + console.log("Destroy secret storage:", act); + this._bootstrapSecureSecretStorage(true); + } + + _destroySecureSecretStorage = () => { + const ConfirmDestoryCrossSigningDialog = sdk.getComponent("dialogs.ConfirmDestroyCrossSigningDialog"); + Modal.createDialog(ConfirmDestoryCrossSigningDialog, { + onFinished: this.onDestroyStorage + }); + } + render() { const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); const { @@ -142,6 +156,12 @@ export default class CrossSigningPanel extends React.PureComponent { {_t("Bootstrap cross-signing and secret storage")}
; + } else { + bootstrapButton =
+ + {_t("Torpedo cross-signing")} + +
; } return ( diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index d125d10cfb..edb0da8780 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -553,6 +553,7 @@ "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.", "Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.", "Bootstrap cross-signing and secret storage": "Bootstrap cross-signing and secret storage", + "Torpedo cross-signing": "Torpedo cross-signing", "Cross-signing public keys:": "Cross-signing public keys:", "in memory": "in memory", "not found": "not found", @@ -1430,6 +1431,9 @@ "Changelog": "Changelog", "You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)", "Removing…": "Removing…", + "Destroy cross-signing keys?": "Destroy cross-signing keys?", + "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.": "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.", + "Clear cross-signing keys": "Clear cross-signing keys", "Confirm Removal": "Confirm Removal", "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.", "Clear all data in this session?": "Clear all data in this session?", From 1a5bed5a105f1db0bd219e52983fb03ff65ad704 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 31 Jan 2020 17:16:27 +0100 Subject: [PATCH 042/268] open a to_device request in a modal instead of the right panel 1st room --- .../views/toasts/VerificationRequestToast.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/views/toasts/VerificationRequestToast.js b/src/components/views/toasts/VerificationRequestToast.js index a5a26f7ddb..92402c3f98 100644 --- a/src/components/views/toasts/VerificationRequestToast.js +++ b/src/components/views/toasts/VerificationRequestToast.js @@ -78,28 +78,28 @@ export default class VerificationRequestToast extends React.PureComponent { // no room id for to_device requests const cli = MatrixClientPeg.get(); try { + await request.accept(); if (request.channel.roomId) { dis.dispatch({ action: 'view_room', room_id: request.channel.roomId, should_peek: false, }); - } else { dis.dispatch({ - action: 'view_room', - room_id: cli.getRooms()[0].roomId, - should_peek: false, + action: "set_right_panel_phase", + phase: RIGHT_PANEL_PHASES.EncryptionPanel, + refireParams: { + verificationRequest: request, + member: cli.getUser(request.otherUserId), + }, }); - } - await request.accept(); - dis.dispatch({ - action: "set_right_panel_phase", - phase: RIGHT_PANEL_PHASES.EncryptionPanel, - refireParams: { + } else { + const VerificationRequestDialog = sdk.getComponent("views.dialogs.VerificationRequestDialog"); + Modal.createTrackedDialog('Incoming Verification', '', VerificationRequestDialog, { verificationRequest: request, - member: cli.getUser(request.otherUserId), - }, - }); + }, null, /* priority = */ false, /* static = */ true); + } + // } else if (request.channel.deviceId && request.verifier) { // // show to_device verifications in dialog still // const IncomingSasDialog = sdk.getComponent("views.dialogs.IncomingSasDialog"); From bdeb9cccc42a23ae8143a092a62dfffa4654d6ee Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Feb 2020 15:34:45 +0000 Subject: [PATCH 043/268] Rename estimatedTargetDevice to targetDevice --- src/components/views/elements/crypto/VerificationQRCode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/elements/crypto/VerificationQRCode.js b/src/components/views/elements/crypto/VerificationQRCode.js index f9fea2dc78..61177cb833 100644 --- a/src/components/views/elements/crypto/VerificationQRCode.js +++ b/src/components/views/elements/crypto/VerificationQRCode.js @@ -47,7 +47,7 @@ export default class VerificationQRCode extends React.PureComponent { const myUserId = cli.getUserId(); const otherUserId = verificationRequest.otherUserId; const myDeviceId = cli.getDeviceId(); - const otherDevice = verificationRequest.estimatedTargetDevice; + const otherDevice = verificationRequest.targetDevice; const otherDeviceId = otherDevice ? otherDevice.deviceId : null; const qrProps = { From f6abd369cafc49a1b9d8f3d33a4407bf2ec45cd3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 7 Feb 2020 15:36:57 +0000 Subject: [PATCH 044/268] Fix comments --- src/components/views/elements/crypto/VerificationQRCode.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/crypto/VerificationQRCode.js b/src/components/views/elements/crypto/VerificationQRCode.js index 61177cb833..1c0fdcbf44 100644 --- a/src/components/views/elements/crypto/VerificationQRCode.js +++ b/src/components/views/elements/crypto/VerificationQRCode.js @@ -34,7 +34,7 @@ export default class VerificationQRCode extends React.PureComponent { // User verification use case only secret: PropTypes.string, otherUserKey: PropTypes.string, // Base64 key being verified - otherUserDeviceKey: PropTypes.string, // Base64 key of the other user's device (optional) + otherUserDeviceKey: PropTypes.string, // Base64 key of the other user's device (or what we think it is; optional) requestEventId: PropTypes.string, // for DM verification only }; @@ -68,10 +68,10 @@ export default class VerificationQRCode extends React.PureComponent { // Populate the keys we need depending on which direction and users are involved in the verification. if (myUserId === otherUserId) { if (!otherDeviceId) { - // New -> Existing session QR code + // Existing scanning New session's QR code qrProps.otherUserDeviceKey = null; } else { - // Existing -> New session QR code + // New scanning Existing session's QR code const myDevices = (await cli.getStoredDevicesForUser(myUserId)) || []; const device = myDevices.find(d => d.deviceId === otherDeviceId); if (device) qrProps.otherUserDeviceKey = device.getFingerprint(); From ce39d1de7076b8deb0deeadedbef1519ff8918b6 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 7 Feb 2020 13:25:07 +0000 Subject: [PATCH 045/268] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2105 of 2105 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/zh_Hant/ --- src/i18n/strings/zh_Hant.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 8cf4f7706e..2570746fc7 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -2128,5 +2128,9 @@ "Message downloading sleep time(ms)": "訊息下載休眠時間(毫秒)", "of ": "的 ", "Indexed rooms:": "已索引的聊天室:", - "%(crawlingRooms)s out of %(totalRooms)s": "%(totalRooms)s 中的 %(crawlingRooms)s" + "%(crawlingRooms)s out of %(totalRooms)s": "%(totalRooms)s 中的 %(crawlingRooms)s", + "If you cancel now, you won't complete verifying the other user.": "如果您現在取消,您將無法完成驗證其他使用者。", + "If you cancel now, you won't complete verifying your other session.": "如果您現在取消,您將無法完成驗證您其他的工作階段。", + "If you cancel now, you won't complete your secret storage operation.": "如果您現在取消,您將無法完成驗證您的秘密儲存空間動作。", + "Cancel entering passphrase?": "取消輸入通關密語?" } From 066faa18f19995742a36e78c4cede380867f0863 Mon Sep 17 00:00:00 2001 From: random Date: Fri, 7 Feb 2020 10:31:36 +0000 Subject: [PATCH 046/268] Translated using Weblate (Italian) Currently translated at 100.0% (2105 of 2105 strings) Translation: Riot Web/matrix-react-sdk Translate-URL: https://translate.riot.im/projects/riot-web/matrix-react-sdk/it/ --- src/i18n/strings/it.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json index dd6b697fb7..e3be1a1aae 100644 --- a/src/i18n/strings/it.json +++ b/src/i18n/strings/it.json @@ -2123,5 +2123,12 @@ "Downloading mesages for %(currentRoom)s.": "Scaricamento messaggi per %(currentRoom)s.", "Riot is securely caching encrypted messages locally for them to appear in search results:": "Riot sta tenendo in cache localmente i messaggi cifrati in modo sicuro affinché appaiano nei risultati di ricerca:", "of ": "di ", - "Message downloading sleep time(ms)": "Tempo di attesa scaricamento messaggi (ms)" + "Message downloading sleep time(ms)": "Tempo di attesa scaricamento messaggi (ms)", + "If you cancel now, you won't complete verifying the other user.": "Se adesso annulli, non completerai la verifica dell'altro utente.", + "If you cancel now, you won't complete verifying your other session.": "Se adesso annulli, non completerai la verifica dell'altra tua sessione.", + "If you cancel now, you won't complete your secret storage operation.": "Se adesso annulli, non completerai l'operazione dell'archivio segreto.", + "Cancel entering passphrase?": "Annullare l'inserimento della password?", + "Mod": "Moderatore", + "Indexed rooms:": "Stanze indicizzate:", + "%(crawlingRooms)s out of %(totalRooms)s": "%(crawlingRooms)s di %(totalRooms)s" } From b08c5d84107b0e60b89f932c830b4767d0bc60d7 Mon Sep 17 00:00:00 2001 From: Zoe Date: Fri, 7 Feb 2020 15:46:31 +0000 Subject: [PATCH 047/268] lint --- src/CrossSigningManager.js | 1 + .../views/dialogs/ConfirmDestroyCrossSigningDialog.js | 2 +- src/components/views/settings/CrossSigningPanel.js | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index 08ec459f26..3381f3e93b 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -115,6 +115,7 @@ export const crossSigningCallbacks = { * * @param {Function} [func] An operation to perform once secret storage has been * bootstrapped. Optional. + * @param {bool} [force] Reset secret storage even if it's already set up */ export async function accessSecretStorage(func = async () => { }, force = false) { const cli = MatrixClientPeg.get(); diff --git a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js index 942249e07d..3242afd5f1 100644 --- a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js +++ b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js @@ -46,7 +46,7 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component { "Deleting cross-signing keys is permanent. " + "Anyone you have verified with will see security alerts. " + "You almost certainly don't want to do this, unless " + - "you've lost every device you can cross-sign from." + "you've lost every device you can cross-sign from.", )}

diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js index 35f617b83b..77cae79324 100644 --- a/src/components/views/settings/CrossSigningPanel.js +++ b/src/components/views/settings/CrossSigningPanel.js @@ -87,6 +87,7 @@ export default class CrossSigningPanel extends React.PureComponent { * 2. Access existing secret storage by requesting passphrase and accessing * cross-signing keys as needed. * 3. All keys are loaded and there's nothing to do. + * @param {bool} [force] Bootstrap again even if keys already present */ _bootstrapSecureSecretStorage = async (force=false) => { this.setState({ error: null }); @@ -109,7 +110,7 @@ export default class CrossSigningPanel extends React.PureComponent { _destroySecureSecretStorage = () => { const ConfirmDestoryCrossSigningDialog = sdk.getComponent("dialogs.ConfirmDestroyCrossSigningDialog"); Modal.createDialog(ConfirmDestoryCrossSigningDialog, { - onFinished: this.onDestroyStorage + onFinished: this.onDestroyStorage, }); } From a260d7a1471d15b8af31dea56f220d457e5dfd1d Mon Sep 17 00:00:00 2001 From: Zoe Date: Fri, 7 Feb 2020 15:53:43 +0000 Subject: [PATCH 048/268] manual lint --- src/CrossSigningManager.js | 1 - .../views/dialogs/ConfirmDestroyCrossSigningDialog.js | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index 3381f3e93b..45e0a336d5 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -122,7 +122,6 @@ export async function accessSecretStorage(func = async () => { }, force = false) secretStorageBeingAccessed = true; try { if (!await cli.hasSecretStorageKey() || force) { - console.warn(!force ? "!hasSecretStorageKey()" : "force"); // This dialog calls bootstrap itself after guiding the user through // passphrase creation. const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '', diff --git a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js index 3242afd5f1..9e1980e98d 100644 --- a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js +++ b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js @@ -37,9 +37,11 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component { const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); return ( - +

{_t( From e016cbeffff7c2a30e9b6169372c726f6eb7e8b3 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 31 Jan 2020 17:03:10 +0100 Subject: [PATCH 049/268] support header image in QuestionDialog --- src/components/views/dialogs/QuestionDialog.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js index b165bf79e2..3eec497b44 100644 --- a/src/components/views/dialogs/QuestionDialog.js +++ b/src/components/views/dialogs/QuestionDialog.js @@ -31,6 +31,7 @@ export default createReactClass({ danger: PropTypes.bool, focus: PropTypes.bool, onFinished: PropTypes.func.isRequired, + headerImage: PropTypes.string, }, getDefaultProps: function() { @@ -63,6 +64,7 @@ export default createReactClass({

From 5c89b41177b832e1d7e7bed28d404c8f00b6bec8 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 31 Jan 2020 17:03:36 +0100 Subject: [PATCH 050/268] make device verification go over right panel (after showing dialog) dialog should be more or less as in the design --- src/components/views/right_panel/UserInfo.js | 68 ++++++++++++++++++-- src/i18n/strings/en_EN.json | 6 +- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js index cd8952fd72..fc1f5bfcc9 100644 --- a/src/components/views/right_panel/UserInfo.js +++ b/src/components/views/right_panel/UserInfo.js @@ -42,6 +42,8 @@ import {textualPowerLevel} from '../../../Roles'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases"; import EncryptionPanel from "./EncryptionPanel"; +import {verificationMethods} from 'matrix-js-sdk/src/crypto'; +import {SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; const _disambiguateDevices = (devices) => { const names = Object.create(null); @@ -135,12 +137,66 @@ function useIsEncrypted(cli, room) { return isEncrypted; } -function verifyDevice(userId, device) { - const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); - Modal.createTrackedDialog('Device Verify Dialog', '', DeviceVerifyDialog, { - userId: userId, - device: device, - }, null, /* priority = */ false, /* static = */ true); +async function verifyDevice(userId, device) { + const cli = MatrixClientPeg.get(); + const member = cli.getUser(userId); + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createTrackedDialog("Verification failed", "insecure", QuestionDialog, { + headerImage: require("../../../../res/img/e2e/warning.svg"), + title: _t("Not Trusted"), + description:
+

{_t("%(name)s (%(userId)s) signed in to a new session without verifying it:", {name: member.displayName, userId})}

+

{device.getDisplayName()} ({device.deviceId})

+

{_t("Ask this user to verify their session, or manually verify it below.")}

+
, + onFinished: async (doneClicked) => { + const manuallyVerifyClicked = !doneClicked; + if (!manuallyVerifyClicked) { + return; + } + const cli = MatrixClientPeg.get(); + const verificationRequest = await cli.requestVerification( + userId, + [ + verificationMethods.SAS, + SHOW_QR_CODE_METHOD, + SCAN_QR_CODE_METHOD, + verificationMethods.RECIPROCATE_QR_CODE, + ], + [device.deviceId], + ); + dis.dispatch({ + action: "set_right_panel_phase", + phase: RIGHT_PANEL_PHASES.EncryptionPanel, + refireParams: {member, verificationRequest}, + }); + }, + primaryButton: _t("Done"), + cancelButton: _t("Manually Verify"), + }); + + // const cli = MatrixClientPeg.get(); + // const verificationRequest = await cli.requestVerification( + // userId, + // [ + // verificationMethods.SAS, + // SHOW_QR_CODE_METHOD, + // SCAN_QR_CODE_METHOD, + // verificationMethods.RECIPROCATE_QR_CODE, + // ], + // [device.deviceId], + // ); + // dis.dispatch({ + // action: "set_right_panel_phase", + // phase: RIGHT_PANEL_PHASES.EncryptionPanel, + // refireParams: {member, verificationRequest}, + // }); + + // const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog'); + // Modal.createTrackedDialog('Device Verify Dialog', '', DeviceVerifyDialog, { + // userId: userId, + // device: device, + // }, null, /* priority = */ false, /* static = */ true); } function verifyUser(user) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 83c15fc385..78a56bbffc 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1166,6 +1166,11 @@ "Yours, or the other users’ session": "Yours, or the other users’ session", "Members": "Members", "Files": "Files", + "Not Trusted": "Not Trusted", + "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) signed in to a new session without verifying it:", + "Ask this user to verify their session, or manually verify it below.": "Ask this user to verify their session, or manually verify it below.", + "Done": "Done", + "Manually Verify": "Manually Verify", "Trusted": "Trusted", "Not trusted": "Not trusted", "%(count)s verified sessions|other": "%(count)s verified sessions", @@ -1928,7 +1933,6 @@ "Session verified": "Session verified", "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.", "Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.", - "Done": "Done", "Without completing security on this session, it won’t have access to encrypted messages.": "Without completing security on this session, it won’t have access to encrypted messages.", "Go Back": "Go Back", "Failed to send email": "Failed to send email", From 40b8db84e32a8d66a448fac620f3c4962fe4f229 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 7 Feb 2020 22:07:29 +0000 Subject: [PATCH 051/268] Get rid of dependence on usercontent.riot.im --- src/components/views/messages/MFileBody.js | 99 ++-------------------- 1 file changed, 6 insertions(+), 93 deletions(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index 737c229afe..aee7d903aa 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -26,7 +26,7 @@ import {decryptFile} from '../../../utils/DecryptFile'; import Tinter from '../../../Tinter'; import request from 'browser-request'; import Modal from '../../../Modal'; -import SdkConfig from "../../../SdkConfig"; +import AccessibleButton from "../elements/AccessibleButton"; // A cached tinted copy of require("../../../../res/img/download.svg") @@ -94,84 +94,6 @@ Tinter.registerTintable(updateTintedDownloadImage); // The downside of using a second domain is that it complicates hosting, // the downside of using a sandboxed iframe is that the browers are overly // restrictive in what you are allowed to do with the generated URL. -// -// For now given how unusable the blobs generated in sandboxed iframes are we -// default to using a renderer hosted on "usercontent.riot.im". This is -// overridable so that people running their own version of the client can -// choose a different renderer. -// -// To that end the current version of the blob generation is the following -// html: -// -// -// -// This waits to receive a message event sent using the window.postMessage API. -// When it receives the event it evals a javascript function in data.code and -// runs the function passing the event as an argument. This version adds -// support for a query parameter controlling the origin from which messages -// will be processed as an extra layer of security (note that the default URL -// is still 'v1' since it is backwards compatible). -// -// In particular it means that the rendering function can be written as a -// ordinary javascript function which then is turned into a string using -// toString(). -// -const DEFAULT_CROSS_ORIGIN_RENDERER = "https://usercontent.riot.im/v1.html"; - -/** - * Render the attachment inside the iframe. - * We can't use imported libraries here so this has to be vanilla JS. - */ -function remoteRender(event) { - const data = event.data; - - const img = document.createElement("img"); - img.id = "img"; - img.src = data.imgSrc; - - const a = document.createElement("a"); - a.id = "a"; - a.rel = data.rel; - a.target = data.target; - a.download = data.download; - a.style = data.style; - a.style.fontFamily = "Arial, Helvetica, Sans-Serif"; - a.href = window.URL.createObjectURL(data.blob); - a.appendChild(img); - a.appendChild(document.createTextNode(data.textContent)); - - const body = document.body; - // Don't display scrollbars if the link takes more than one line - // to display. - body.style = "margin: 0px; overflow: hidden"; - body.appendChild(a); -} - -/** - * Update the tint inside the iframe. - * We can't use imported libraries here so this has to be vanilla JS. - */ -function remoteSetTint(event) { - const data = event.data; - - const img = document.getElementById("img"); - img.src = data.imgSrc; - img.style = data.imgStyle; - - const a = document.getElementById("a"); - a.style = data.style; -} - /** * Get the current CSS style for a DOMElement. @@ -283,7 +205,6 @@ export default createReactClass({ // will be inside the iframe so we wont be able to update // it directly. this._iframe.current.contentWindow.postMessage({ - code: remoteSetTint.toString(), imgSrc: tintedDownloadImageURL, style: computedStyle(this._dummyLink.current), }, "*"); @@ -306,7 +227,7 @@ export default createReactClass({ // Wait for the user to click on the link before downloading // and decrypting the attachment. let decrypting = false; - const decrypt = () => { + const decrypt = (e) => { if (decrypting) { return false; } @@ -323,16 +244,15 @@ export default createReactClass({ }); }).finally(() => { decrypting = false; - return; }); }; return ( ); @@ -341,7 +261,6 @@ export default createReactClass({ // When the iframe loads we tell it to render a download link const onIframeLoad = (ev) => { ev.target.contentWindow.postMessage({ - code: remoteRender.toString(), imgSrc: tintedDownloadImageURL, style: computedStyle(this._dummyLink.current), blob: this.state.decryptedBlob, @@ -355,13 +274,7 @@ export default createReactClass({ }, "*"); }; - // If the attachment is encryped then put the link inside an iframe. - let renderer_url = DEFAULT_CROSS_ORIGIN_RENDERER; - const appConfig = SdkConfig.get(); - if (appConfig && appConfig.cross_origin_renderer_url) { - renderer_url = appConfig.cross_origin_renderer_url; - } - renderer_url += "?origin=" + encodeURIComponent(window.location.origin); + // If the attachment is encrypted then put the link inside an iframe. return (
@@ -373,7 +286,7 @@ export default createReactClass({ */ }
-