From 2c7dfb540143da570afe167e55f862e3ba47a0f7 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Tue, 28 Feb 2023 10:39:35 +0100 Subject: [PATCH] Factor out basic email check (#10244) --- src/components/views/dialogs/InviteDialog.tsx | 4 +-- src/email.ts | 4 +++ .../views/dialogs/InviteDialog-test.tsx | 16 ++++++++++ test/email-test.ts | 32 +++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 test/email-test.ts diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 3084440619..2d1c967472 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -657,7 +657,7 @@ export default class InviteDialog extends React.PureComponent 0 && Email.looksValid(term) && SettingsStore.getValue(UIFeature.IdentityServer)) { + if (Email.looksValid(term) && SettingsStore.getValue(UIFeature.IdentityServer)) { // Start off by suggesting the plain email while we try and resolve it // to a real account. this.setState({ @@ -796,7 +796,7 @@ export default class InviteDialog extends React.PureComponent 0 && Email.looksValid(address)) { + if (Email.looksValid(address)) { toAdd.push(new ThreepidMember(address)); continue; } diff --git a/src/email.ts b/src/email.ts index 24022064a2..7a9d4769bc 100644 --- a/src/email.ts +++ b/src/email.ts @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2023 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. @@ -22,5 +23,8 @@ const EMAIL_ADDRESS_REGEX = new RegExp( ); export function looksValid(email: string): boolean { + // short circuit regex with this basic check + if (email.indexOf("@") < 1) return false; + return EMAIL_ADDRESS_REGEX.test(email); } diff --git a/test/components/views/dialogs/InviteDialog-test.tsx b/test/components/views/dialogs/InviteDialog-test.tsx index 9c0dcda498..b117211fbb 100644 --- a/test/components/views/dialogs/InviteDialog-test.tsx +++ b/test/components/views/dialogs/InviteDialog-test.tsx @@ -16,6 +16,7 @@ limitations under the License. import React from "react"; import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; import { RoomType } from "matrix-js-sdk/src/@types/event"; import { Room } from "matrix-js-sdk/src/matrix"; @@ -187,4 +188,19 @@ describe("InviteDialog", () => { await screen.findByText("foobar@email.com"); await screen.findByText("Invite by email"); }); + + it("should add pasted values", async () => { + mockClient.getIdentityServerUrl.mockReturnValue("https://identity-server"); + mockClient.lookupThreePid.mockResolvedValue({}); + + render(); + + const input = screen.getByTestId("invite-dialog-input"); + input.focus(); + await userEvent.paste(`${bobId} ${aliceEmail}`); + + await screen.findByText(bobId); + await screen.findByText(aliceEmail); + expect(input).toHaveValue(""); + }); }); diff --git a/test/email-test.ts b/test/email-test.ts new file mode 100644 index 0000000000..c1822d7eaf --- /dev/null +++ b/test/email-test.ts @@ -0,0 +1,32 @@ +/* +Copyright 2023 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 { looksValid } from "../src/email"; + +describe("looksValid", () => { + it.each([ + ["", false], + ["alice", false], + ["@", false], + ["@alice:example.com", false], + ["@b.org", false], + ["alice@example", false], + ["a@b.org", true], + ["alice@example.com", true], + ])("for »%s« should return %s", (value: string, expected: boolean) => { + expect(looksValid(value)).toBe(expected); + }); +});