forked from ChelseaKR/exitdrill
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcivicrm_browser_access_denial.mjs
More file actions
131 lines (125 loc) · 4.16 KB
/
Copy pathcivicrm_browser_access_denial.mjs
File metadata and controls
131 lines (125 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { chromium } from "playwright-core";
function fail() {
throw new Error("closed browser access-denial probe failed");
}
function requireCredential(name) {
const value = process.env[name];
if (typeof value !== "string" || value.length < 8 || value.length > 256) fail();
return value;
}
function requireContactId() {
const value = process.env.EXITDRILL_PROTECTED_CONTACT_ID;
if (!/^[1-9][0-9]{0,9}$/.test(value ?? "")) fail();
return value;
}
const username = requireCredential("EXITDRILL_BROWSER_USERNAME");
const password = requireCredential("EXITDRILL_BROWSER_PASSWORD");
const contactId = requireContactId();
let browser;
let currentStep = "browser_launch";
try {
browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
acceptDownloads: false,
baseURL: "http://application",
extraHTTPHeaders: {
Authorization: `Basic ${Buffer.from(`${username}:${password}`, "utf8").toString("base64")}`,
},
serviceWorkers: "block",
viewport: { width: 1440, height: 1000 },
});
let unexpectedNetwork = false;
let failedRequestCount = 0;
let pageErrorCount = 0;
const pageErrors = [];
await context.route("**/*", async (route) => {
const url = new URL(route.request().url());
if (
(url.protocol === "http:" && url.hostname === "application" && url.port === "") ||
url.protocol === "data:" ||
url.protocol === "about:"
) {
await route.continue();
} else {
unexpectedNetwork = true;
await route.abort("blockedbyclient");
}
});
const page = await context.newPage();
page.on("dialog", (dialog) => dialog.dismiss());
page.on("download", (download) => download.cancel());
page.on("pageerror", (error) => {
pageErrorCount += 1;
if (pageErrors.length < 3) pageErrors.push({ name: error.name, message: error.message });
});
page.on("requestfailed", () => {
failedRequestCount += 1;
});
currentStep = "protected_contact_navigation";
const response = await page.goto(`/civicrm/contact/view?reset=1&cid=${contactId}`, {
timeout: 30_000,
waitUntil: "load",
});
if (!response) fail();
const redirectChain = [];
let request = response.request();
while (request) {
const redirectResponse = await request.response();
redirectChain.unshift({
pathname: new URL(request.url()).pathname,
status: redirectResponse?.status() ?? 0,
});
request = request.redirectedFrom();
}
const bodyText = (await page.locator("body").innerText()).replace(/\s+/g, " ").trim();
if (
unexpectedNetwork ||
failedRequestCount !== 0 ||
pageErrorCount !== 1 ||
JSON.stringify(pageErrors) !==
JSON.stringify([
{ name: "TypeError", message: "$(...).notify is not a function" },
]) ||
JSON.stringify(redirectChain) !==
JSON.stringify([
{ pathname: "/civicrm/contact/view", status: 302 },
{ pathname: "/civicrm", status: 200 },
]) ||
response.status() !== 200 ||
new URL(page.url()).pathname !== "/civicrm" ||
(await page.locator(".crm-contact-page").count()) !== 0 ||
bodyText.includes("Synthetic Person Alpha")
) {
fail();
}
process.stdout.write(
`${JSON.stringify({
authenticated_identity: "deny",
browser_engine: "chromium",
data_mode: "synthetic_only",
denial_signal: "redirect_and_protected_content_absence",
known_runtime_errors: [
{ error_key: "jquery_notify_unavailable", occurrence_count: 1 },
],
redirect_chain: [
{ route: "civicrm/contact/view", status: 302 },
{ route: "civicrm", status: 200 },
],
retained_artifacts: [],
schema_version: "exitdrill/civicrm-browser-access-denial-observation/v0.1",
steps: [
"protected_contact_requested",
"protected_contact_redirected",
"protected_contact_content_absent",
],
target_profile:
"directus-11.17.4-civic-case-to-civicrm-standalone-6.16.2/v0.1",
})}\n`,
);
await context.close();
} catch {
process.stderr.write(`CiviCRM browser access-denial probe failed closed at ${currentStep}\n`);
process.exitCode = 1;
} finally {
await browser?.close().catch(() => undefined);
}