Check for cross-signing homeserver support
This checks the homeserver to ensure it supports cross-signing (via the versions feature flag) before attempting bootstrapping or offering user verification. Fixes https://github.com/vector-im/riot-web/issues/11863
This commit is contained in:
parent
f80582a51d
commit
a71a234622
6 changed files with 92 additions and 42 deletions
|
@ -42,6 +42,7 @@ import {textualPowerLevel} from '../../../Roles';
|
|||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
|
||||
import EncryptionPanel from "./EncryptionPanel";
|
||||
import { useAsyncMemo } from '../../../hooks/useAsyncMemo';
|
||||
|
||||
const _disambiguateDevices = (devices) => {
|
||||
const names = Object.create(null);
|
||||
|
@ -916,6 +917,12 @@ const useIsSynapseAdmin = (cli) => {
|
|||
return isAdmin;
|
||||
};
|
||||
|
||||
const useHomeserverSupportsCrossSigning = (cli) => {
|
||||
return useAsyncMemo(async () => {
|
||||
return cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing");
|
||||
}, [cli], false);
|
||||
};
|
||||
|
||||
function useRoomPermissions(cli, room, user) {
|
||||
const [roomPermissions, setRoomPermissions] = useState({
|
||||
// modifyLevelMax is the max PL we can set this user to, typically min(their PL, our PL) && canSetPL
|
||||
|
@ -1315,19 +1322,23 @@ const BasicUserInfo = ({room, member, groupId, devices, isRoomEncrypted}) => {
|
|||
text = _t("Messages in this room are end-to-end encrypted.");
|
||||
}
|
||||
|
||||
const userTrust = cli.checkUserTrust(member.userId);
|
||||
const userVerified = SettingsStore.isFeatureEnabled("feature_cross_signing") ?
|
||||
userTrust.isCrossSigningVerified() :
|
||||
userTrust.isVerified();
|
||||
const isMe = member.userId === cli.getUserId();
|
||||
|
||||
let verifyButton;
|
||||
if (isRoomEncrypted && !userVerified && !isMe) {
|
||||
verifyButton = (
|
||||
<AccessibleButton className="mx_UserInfo_field" onClick={() => verifyUser(member)}>
|
||||
{_t("Verify")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
const homeserverSupportsCrossSigning = useHomeserverSupportsCrossSigning(cli);
|
||||
if (
|
||||
SettingsStore.isFeatureEnabled("feature_cross_signing") &&
|
||||
homeserverSupportsCrossSigning
|
||||
) {
|
||||
const userTrust = cli.checkUserTrust(member.userId);
|
||||
const userVerified = userTrust.isCrossSigningVerified();
|
||||
const isMe = member.userId === cli.getUserId();
|
||||
|
||||
if (isRoomEncrypted && !userVerified && !isMe) {
|
||||
verifyButton = (
|
||||
<AccessibleButton className="mx_UserInfo_field" onClick={() => verifyUser(member)}>
|
||||
{_t("Verify")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let devicesSection;
|
||||
|
|
|
@ -72,11 +72,14 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
const crossSigningPublicKeysOnDevice = crossSigning.getId();
|
||||
const crossSigningPrivateKeysInStorage = await crossSigning.isStoredInSecretStorage(secretStorage);
|
||||
const secretStorageKeyInAccount = await secretStorage.hasKey();
|
||||
const homeserverSupportsCrossSigning =
|
||||
await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing");
|
||||
|
||||
this.setState({
|
||||
crossSigningPublicKeysOnDevice,
|
||||
crossSigningPrivateKeysInStorage,
|
||||
secretStorageKeyInAccount,
|
||||
homeserverSupportsCrossSigning,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -120,6 +123,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
crossSigningPublicKeysOnDevice,
|
||||
crossSigningPrivateKeysInStorage,
|
||||
secretStorageKeyInAccount,
|
||||
homeserverSupportsCrossSigning,
|
||||
} = this.state;
|
||||
|
||||
let errorSection;
|
||||
|
@ -127,13 +131,19 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
errorSection = <div className="error">{error.toString()}</div>;
|
||||
}
|
||||
|
||||
const enabled = (
|
||||
// Whether the various keys exist on your account (but not necessarily
|
||||
// on this device).
|
||||
const enabledForAccount = (
|
||||
crossSigningPrivateKeysInStorage &&
|
||||
secretStorageKeyInAccount
|
||||
);
|
||||
|
||||
let summarisedStatus;
|
||||
if (enabled && crossSigningPublicKeysOnDevice) {
|
||||
if (!homeserverSupportsCrossSigning) {
|
||||
summarisedStatus = <p>{_t(
|
||||
"Your homeserver does not support cross-signing.",
|
||||
)}</p>;
|
||||
} else if (enabledForAccount && crossSigningPublicKeysOnDevice) {
|
||||
summarisedStatus = <p>✅ {_t(
|
||||
"Cross-signing and secret storage are enabled.",
|
||||
)}</p>;
|
||||
|
@ -149,18 +159,18 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
}
|
||||
|
||||
let bootstrapButton;
|
||||
if (!enabled) {
|
||||
bootstrapButton = <div className="mx_CrossSigningPanel_buttonRow">
|
||||
<AccessibleButton kind="primary" onClick={this._bootstrapSecureSecretStorage}>
|
||||
{_t("Bootstrap cross-signing and secret storage")}
|
||||
</AccessibleButton>
|
||||
</div>;
|
||||
} else {
|
||||
bootstrapButton = <div className="mx_CrossSigningPanel_buttonRow">
|
||||
if (enabledForAccount) {
|
||||
bootstrapButton = (
|
||||
<AccessibleButton kind="danger" onClick={this._destroySecureSecretStorage}>
|
||||
{_t("Reset cross-signing and secret storage")}
|
||||
</AccessibleButton>
|
||||
</div>;
|
||||
);
|
||||
} else if (!enabledForAccount && homeserverSupportsCrossSigning) {
|
||||
bootstrapButton = (
|
||||
<AccessibleButton kind="primary" onClick={this._bootstrapSecureSecretStorage}>
|
||||
{_t("Bootstrap cross-signing and secret storage")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -181,10 +191,16 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
<td>{_t("Secret storage public key:")}</td>
|
||||
<td>{secretStorageKeyInAccount ? _t("in account data") : _t("not found")}</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<tr>
|
||||
<td>{_t("Homeserver feature support:")}</td>
|
||||
<td>{homeserverSupportsCrossSigning ? _t("exists") : _t("not found")}</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</details>
|
||||
{errorSection}
|
||||
{bootstrapButton}
|
||||
<div className="mx_CrossSigningPanel_buttonRow">
|
||||
{bootstrapButton}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,6 @@ export default class KeyBackupPanel extends React.PureComponent {
|
|||
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
|
||||
import('../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog'),
|
||||
{
|
||||
secureSecretStorage: SettingsStore.isFeatureEnabled("feature_cross_signing"),
|
||||
onFinished: () => {
|
||||
this._loadBackupStatus();
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue