chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { emailMatchesPattern } from "../app/utils/emailPattern.js";
|
||||
|
||||
// emailMatchesPattern backs the ADMIN_EMAILS and WHITELISTED_EMAILS gates.
|
||||
// Property under test: a pattern matches the whole address, never a substring.
|
||||
describe("emailMatchesPattern", () => {
|
||||
it("matches an address that equals the operator pattern exactly", () => {
|
||||
expect(emailMatchesPattern("admin@company.com", "admin@company.com")).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a leading-@ domain shorthand against addresses at that domain", () => {
|
||||
expect(emailMatchesPattern("@company.com", "alice@company.com")).toBe(true);
|
||||
expect(emailMatchesPattern("@company.com", "bob@company.com")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects a look-alike address that merely contains the pattern", () => {
|
||||
// A look-alike address embeds the pattern as a substring; an unanchored
|
||||
// match would wrongly accept it.
|
||||
expect(emailMatchesPattern("admin@company.com", "evil@admin@company.com.attacker.com")).toBe(
|
||||
false
|
||||
);
|
||||
expect(emailMatchesPattern("@company.com", "evil@company.com.attacker.com")).toBe(false);
|
||||
expect(emailMatchesPattern("@company.com", "alice@sub.company.com")).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects a trailing-garbage address (pattern is only a prefix)", () => {
|
||||
expect(emailMatchesPattern("admin@company.com", "admin@company.computer-evil.com")).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects a leading-garbage address (pattern is only a suffix)", () => {
|
||||
expect(emailMatchesPattern("admin@company.com", "not-admin@company.com")).toBe(false);
|
||||
});
|
||||
|
||||
it("preserves top-level alternation as whole-string alternatives", () => {
|
||||
// Guards against anchoring without the non-capturing group, which would
|
||||
// turn `^a|b$` into anchored-a OR anchored-b and break multi-address configs.
|
||||
const pattern = "alice@x.com|bob@x.com";
|
||||
expect(emailMatchesPattern(pattern, "alice@x.com")).toBe(true);
|
||||
expect(emailMatchesPattern(pattern, "bob@x.com")).toBe(true);
|
||||
expect(emailMatchesPattern(pattern, "eve@x.com")).toBe(false);
|
||||
// ...and alternation must not become a substring match either.
|
||||
expect(emailMatchesPattern(pattern, "eve+alice@x.com.evil.com")).toBe(false);
|
||||
});
|
||||
|
||||
it("expands domain shorthand inside simple top-level alternation", () => {
|
||||
const pattern = "alice@x.com|@company.com";
|
||||
expect(emailMatchesPattern(pattern, "alice@x.com")).toBe(true);
|
||||
expect(emailMatchesPattern(pattern, "carol@company.com")).toBe(true);
|
||||
expect(emailMatchesPattern(pattern, "carol@company.com.evil.com")).toBe(false);
|
||||
});
|
||||
|
||||
it("accepts patterns that already carry their own anchors", () => {
|
||||
// Operators who already wrote a fully-anchored pattern keep working:
|
||||
// ^(?:^...$)$ accepts exactly the same strings.
|
||||
expect(emailMatchesPattern("^ops@company\\.com$", "ops@company.com")).toBe(true);
|
||||
expect(emailMatchesPattern("^ops@company\\.com$", "ops@company.com.evil.com")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user