You've already forked element-web
mirror of
https://github.com/element-hq/element-web.git
synced 2025-08-06 16:22:46 +03:00
Add config option to force verification (#29)
* Add config option to force verification If this is set, users will not have the option to skip verification on login (they will still be able to reload and continue unverified, currently). Default off. * Test for complete security dialog * I hadn't set up prettier
This commit is contained in:
@@ -52,6 +52,8 @@ export interface IConfigOptions {
|
|||||||
auth_footer_links?: { text: string; url: string }[];
|
auth_footer_links?: { text: string; url: string }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
force_verification?: boolean; // if true, users must verify new logins
|
||||||
|
|
||||||
map_style_url?: string; // for location-shared maps
|
map_style_url?: string; // for location-shared maps
|
||||||
|
|
||||||
embedded_pages?: {
|
embedded_pages?: {
|
||||||
|
@@ -14,6 +14,7 @@ import SetupEncryptionBody from "./SetupEncryptionBody";
|
|||||||
import AccessibleButton from "../../views/elements/AccessibleButton";
|
import AccessibleButton from "../../views/elements/AccessibleButton";
|
||||||
import CompleteSecurityBody from "../../views/auth/CompleteSecurityBody";
|
import CompleteSecurityBody from "../../views/auth/CompleteSecurityBody";
|
||||||
import AuthPage from "../../views/auth/AuthPage";
|
import AuthPage from "../../views/auth/AuthPage";
|
||||||
|
import SdkConfig from "../../../SdkConfig";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
onFinished: () => void;
|
onFinished: () => void;
|
||||||
@@ -82,8 +83,10 @@ export default class CompleteSecurity extends React.Component<IProps, IState> {
|
|||||||
throw new Error(`Unknown phase ${phase}`);
|
throw new Error(`Unknown phase ${phase}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const forceVerification = SdkConfig.get("force_verification") ?? false;
|
||||||
|
|
||||||
let skipButton;
|
let skipButton;
|
||||||
if (phase === Phase.Intro || phase === Phase.ConfirmReset) {
|
if (!forceVerification && (phase === Phase.Intro || phase === Phase.ConfirmReset)) {
|
||||||
skipButton = (
|
skipButton = (
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
onClick={this.onSkipClick}
|
onClick={this.onSkipClick}
|
||||||
|
79
test/components/structures/auth/CompleteSecurity-test.tsx
Normal file
79
test/components/structures/auth/CompleteSecurity-test.tsx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2024 New Vector Ltd.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
|
Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import { mocked } from "jest-mock";
|
||||||
|
import EventEmitter from "events";
|
||||||
|
|
||||||
|
import CompleteSecurity from "../../../../src/components/structures/auth/CompleteSecurity";
|
||||||
|
import { stubClient } from "../../../test-utils";
|
||||||
|
import { Phase, SetupEncryptionStore } from "../../../../src/stores/SetupEncryptionStore";
|
||||||
|
import SdkConfig from "../../../../src/SdkConfig";
|
||||||
|
|
||||||
|
class MockSetupEncryptionStore extends EventEmitter {
|
||||||
|
public phase: Phase = Phase.Intro;
|
||||||
|
public lostKeys(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public start: () => void = jest.fn();
|
||||||
|
public stop: () => void = jest.fn();
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("CompleteSecurity", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const client = stubClient();
|
||||||
|
const deviceIdToDevice = new Map();
|
||||||
|
deviceIdToDevice.set("DEVICE_ID", {
|
||||||
|
deviceId: "DEVICE_ID",
|
||||||
|
userId: "USER_ID",
|
||||||
|
});
|
||||||
|
const userIdToDevices = new Map();
|
||||||
|
userIdToDevices.set("USER_ID", deviceIdToDevice);
|
||||||
|
mocked(client.getCrypto()!.getUserDeviceInfo).mockResolvedValue(userIdToDevices);
|
||||||
|
|
||||||
|
const mockSetupEncryptionStore = new MockSetupEncryptionStore();
|
||||||
|
jest.spyOn(SetupEncryptionStore, "sharedInstance").mockReturnValue(
|
||||||
|
mockSetupEncryptionStore as SetupEncryptionStore,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Renders with a cancel button by default", () => {
|
||||||
|
render(<CompleteSecurity onFinished={() => {}} />);
|
||||||
|
|
||||||
|
expect(screen.getByRole("button", { name: "Skip verification for now" })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Renders with a cancel button if forceVerification false", () => {
|
||||||
|
jest.spyOn(SdkConfig, "get").mockImplementation((key: string) => {
|
||||||
|
if (key === "forceVerification") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<CompleteSecurity onFinished={() => {}} />);
|
||||||
|
|
||||||
|
expect(screen.getByRole("button", { name: "Skip verification for now" })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Renders without a cancel button if forceVerification true", () => {
|
||||||
|
jest.spyOn(SdkConfig, "get").mockImplementation((key: string) => {
|
||||||
|
if (key === "force_verification") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<CompleteSecurity onFinished={() => {}} />);
|
||||||
|
|
||||||
|
expect(screen.queryByRole("button", { name: "Skip verification for now" })).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
@@ -108,6 +108,7 @@ export function createTestClient(): MatrixClient {
|
|||||||
|
|
||||||
secretStorage: {
|
secretStorage: {
|
||||||
get: jest.fn(),
|
get: jest.fn(),
|
||||||
|
isStored: jest.fn().mockReturnValue(false),
|
||||||
},
|
},
|
||||||
|
|
||||||
store: {
|
store: {
|
||||||
@@ -128,6 +129,7 @@ export function createTestClient(): MatrixClient {
|
|||||||
getDeviceVerificationStatus: jest.fn(),
|
getDeviceVerificationStatus: jest.fn(),
|
||||||
resetKeyBackup: jest.fn(),
|
resetKeyBackup: jest.fn(),
|
||||||
isEncryptionEnabledInRoom: jest.fn(),
|
isEncryptionEnabledInRoom: jest.fn(),
|
||||||
|
getVerificationRequestsToDeviceInProgress: jest.fn().mockReturnValue([]),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getPushActionsForEvent: jest.fn(),
|
getPushActionsForEvent: jest.fn(),
|
||||||
|
Reference in New Issue
Block a user