Bug 42772: Cypress.env => cy.env

Warning: The allowCypressEnv configuration option is enabled. This allows any browser code to read values from Cypress.env(). This is insecure and will be removed in a future major version.

1. Replace Cypress.env() calls with cy.env() (for sensitive values) or Cypress.expose() (for public configuration)
2. Set allowCypressEnv: false in your Cypress configuration to disable Cypress.env()

Learn more: https://on.cypress.io/cypress-env-migration

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Jonathan Druart 2026-06-08 14:51:01 +02:00 committed by Pedro Amorim
parent 7b307694fa
commit f89e68c220
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
4 changed files with 178 additions and 156 deletions

View File

@ -12,11 +12,14 @@ export default defineConfig({
setupNodeEvents(on, config) {
return require("./t/cypress/plugins/index.js")(on, config);
},
allowCypressEnv: false,
baseUrl: process.env.KOHA_INTRANET_URL || "http://localhost:8081",
specPattern: "t/cypress/integration/**/*.*",
supportFile: "t/cypress/support/e2e.js",
env: {
opacBaseUrl: process.env.KOHA_OPAC_URL || "http://localhost:8080",
kohaUsername: process.env.KOHA_USER || "koha",
kohaPassword: process.env.KOHA_PASS || "koha",
apiUsername: process.env.KOHA_USER || "koha",
apiPassword: process.env.KOHA_PASS || "koha",
},

View File

@ -55,18 +55,20 @@ describe("Patron self-renewal", () => {
});
it("should verify that the patron wants to renew their account", function () {
cy.visitOpac("/cgi-bin/koha/opac-user.pl");
cy.intercept(
"GET",
Cypress.env("opacBaseUrl") +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "0",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
},
}
).as("renewalConfig");
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) => {
cy.intercept(
"GET",
opacBaseUrl +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "0",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
},
}
).as("renewalConfig");
});
cy.get("#patronSelfRenewal", { timeout: 10000 });
cy.get("#self_renewal_available a").click();
cy.wait("@renewalConfig");
@ -76,33 +78,36 @@ describe("Patron self-renewal", () => {
});
it("should renew a patron's account", function () {
cy.visitOpac("/cgi-bin/koha/opac-user.pl");
cy.intercept(
"GET",
Cypress.env("opacBaseUrl") +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "0",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
},
}
).as("renewalConfig");
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) => {
cy.intercept(
"GET",
opacBaseUrl +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "0",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
},
}
).as("renewalConfig");
});
cy.get("#patronSelfRenewal", { timeout: 10000 });
cy.get("#self_renewal_available a").click();
cy.wait("@renewalConfig");
cy.intercept(
"POST",
Cypress.env("opacBaseUrl") +
"/api/v1/public/patrons/*/self_renewal",
{
statusCode: 201,
body: {
expiry_date: "2099-01-01",
confirmation_sent: true,
},
}
).as("submitRenewal");
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) => {
cy.intercept(
"POST",
opacBaseUrl + "/api/v1/public/patrons/*/self_renewal",
{
statusCode: 201,
body: {
expiry_date: "2099-01-01",
confirmation_sent: true,
},
}
).as("submitRenewal");
});
cy.get("#patronSelfRenewal .verification_actions")
.contains("Yes")
.click();
@ -113,34 +118,39 @@ describe("Patron self-renewal", () => {
});
it("should display an information message step", function () {
cy.visitOpac("/cgi-bin/koha/opac-user.pl");
cy.intercept(
"GET",
Cypress.env("opacBaseUrl") +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "0",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
self_renewal_information_messages: ["This should be shown"],
},
}
).as("renewalConfig");
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) => {
cy.intercept(
"GET",
opacBaseUrl +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "0",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
self_renewal_information_messages: [
"This should be shown",
],
},
}
).as("renewalConfig");
});
cy.get("#patronSelfRenewal", { timeout: 10000 });
cy.get("#self_renewal_available a").click();
cy.wait("@renewalConfig");
cy.intercept(
"POST",
Cypress.env("opacBaseUrl") +
"/api/v1/public/patrons/*/self_renewal",
{
statusCode: 201,
body: {
expiry_date: "2099-01-01",
confirmation_sent: true,
},
}
).as("submitRenewal");
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) => {
cy.intercept(
"POST",
opacBaseUrl + "/api/v1/public/patrons/*/self_renewal",
{
statusCode: 201,
body: {
expiry_date: "2099-01-01",
confirmation_sent: true,
},
}
).as("submitRenewal");
});
cy.get("#patronSelfRenewal .verification_question").contains(
"This should be shown"
);
@ -158,18 +168,20 @@ describe("Patron self-renewal", () => {
});
it("should confirm patron details if required", function () {
cy.visitOpac("/cgi-bin/koha/opac-user.pl");
cy.intercept(
"GET",
Cypress.env("opacBaseUrl") +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "1",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
},
}
).as("renewalConfig");
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) => {
cy.intercept(
"GET",
opacBaseUrl +
"/api/v1/public/patrons/*/self_renewal?_per_page=-1",
{
self_renewal_settings: {
opac_patron_details: "1",
self_renewal_failure_message:
"Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.",
},
}
).as("renewalConfig");
});
cy.get("#patronSelfRenewal", { timeout: 10000 });
cy.get("#self_renewal_available a").click();
cy.wait("@renewalConfig");
@ -183,18 +195,19 @@ describe("Patron self-renewal", () => {
cy.get("#update-account div.alert.alert-info").contains(
"Please verify your details to proceed with your self-renewal"
);
cy.intercept(
"POST",
Cypress.env("opacBaseUrl") +
"/api/v1/public/patrons/*/self_renewal",
{
statusCode: 201,
body: {
expiry_date: "2099-01-01",
confirmation_sent: true,
},
}
).as("submitRenewal");
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) => {
cy.intercept(
"POST",
opacBaseUrl + "/api/v1/public/patrons/*/self_renewal",
{
statusCode: 201,
body: {
expiry_date: "2099-01-01",
confirmation_sent: true,
},
}
).as("submitRenewal");
});
cy.get("#update-account fieldset.action input[type='submit']")
.contains("Submit renewal request")
.click();

View File

@ -3,46 +3,58 @@ describe("SCO", () => {
// cy.request() — no browser navigation, so no cross-origin issues.
function setSyspref(variable: string, value: string) {
// Step 1: GET the login page to get an anonymous session + its CSRF token
cy.request("/cgi-bin/koha/mainpage.pl?logout.x=1").then(loginPage => {
const csrfForLogin = (loginPage.body as string).match(
/<meta name="csrf-token" content="([^"]+)"/
)?.[1];
if (!csrfForLogin)
throw new Error("CSRF token not found on login page");
cy.env(["apiUsername", "apiPassword"]).then(
({ apiUsername, apiPassword }) => {
cy.request("/cgi-bin/koha/mainpage.pl?logout.x=1").then(
loginPage => {
const csrfForLogin = (loginPage.body as string).match(
/<meta name="csrf-token" content="([^"]+)"/
)?.[1];
if (!csrfForLogin)
throw new Error(
"CSRF token not found on login page"
);
// Step 2: POST credentials — Koha authenticates and redirects to the
// logged-in mainpage whose body contains the new session's CSRF token
cy.request({
method: "POST",
url: "/cgi-bin/koha/mainpage.pl",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: [
`login_userid=${encodeURIComponent(Cypress.env("apiUsername"))}`,
`login_password=${encodeURIComponent(Cypress.env("apiPassword"))}`,
`csrf_token=${encodeURIComponent(csrfForLogin)}`,
`login_op=cud-login`,
].join("&"),
}).then(mainPage => {
const csrfForSvc = (mainPage.body as string).match(
/<meta name="csrf-token" content="([^"]+)"/
)?.[1];
if (!csrfForSvc)
throw new Error("CSRF token not found on main page");
// Step 2: POST credentials — Koha authenticates and redirects to the
// logged-in mainpage whose body contains the new session's CSRF token
cy.request({
method: "POST",
url: "/cgi-bin/koha/mainpage.pl",
headers: {
"Content-Type":
"application/x-www-form-urlencoded",
},
body: [
`login_userid=${encodeURIComponent(apiUsername)}`,
`login_password=${encodeURIComponent(apiPassword)}`,
`csrf_token=${encodeURIComponent(csrfForLogin)}`,
`login_op=cud-login`,
].join("&"),
}).then(mainPage => {
const csrfForSvc = (mainPage.body as string).match(
/<meta name="csrf-token" content="([^"]+)"/
)?.[1];
if (!csrfForSvc)
throw new Error(
"CSRF token not found on main page"
);
// Step 3: POST to svc endpoint — session cookie sent automatically
cy.request({
method: "POST",
url: "/cgi-bin/koha/svc/config/systempreferences",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"CSRF-TOKEN": csrfForSvc,
},
body: `pref_${encodeURIComponent(variable)}=${encodeURIComponent(value)}`,
});
});
});
// Step 3: POST to svc endpoint — session cookie sent automatically
cy.request({
method: "POST",
url: "/cgi-bin/koha/svc/config/systempreferences",
headers: {
"Content-Type":
"application/x-www-form-urlencoded",
"CSRF-TOKEN": csrfForSvc,
},
body: `pref_${encodeURIComponent(variable)}=${encodeURIComponent(value)}`,
});
});
}
);
}
);
}
beforeEach(() => {

View File

@ -75,46 +75,40 @@ Cypress.on("uncaught:exception", err => {
}
});
function get_fallback_login_value(param) {
var env_var = param == "username" ? "KOHA_USER" : "KOHA_PASS";
return typeof Cypress.env(env_var) === "undefined"
? "koha"
: Cypress.env(env_var);
}
Cypress.Commands.add("visitOpac", path => {
cy.visit(Cypress.env("opacBaseUrl") + path);
cy.env(["opacBaseUrl"]).then(({ opacBaseUrl }) =>
cy.visit(opacBaseUrl + path)
);
});
Cypress.Commands.add("login", (username, password) => {
var user =
typeof username === "undefined"
? get_fallback_login_value("username")
: username;
var pass =
typeof password === "undefined"
? get_fallback_login_value("password")
: password;
cy.visit("/cgi-bin/koha/mainpage.pl?logout.x=1");
cy.get("#userid").type(user);
cy.get("#password").type(pass);
cy.get("#submit-button").click();
cy.env(["kohaUsername", "kohaPassword"]).then(
({ kohaUsername, kohaPassword }) => {
var user =
typeof username === "undefined" ? kohaUsername : username;
var pass =
typeof password === "undefined" ? kohaPassword : password;
cy.visit("/cgi-bin/koha/mainpage.pl?logout.x=1");
cy.get("#userid").type(user);
cy.get("#password").type(pass);
cy.get("#submit-button").click();
}
);
});
Cypress.Commands.add("loginOpac", (username, password) => {
var user =
typeof username === "undefined"
? get_fallback_login_value("username")
: username;
var pass =
typeof password === "undefined"
? get_fallback_login_value("password")
: password;
cy.visitOpac("/cgi-bin/koha/opac-main.pl?logout.x=1");
cy.get("#userid").type(user);
cy.get("#password").type(pass);
cy.get("#auth .action").contains("Log in").click();
cy.env(["kohaUsername", "kohaPassword"]).then(
({ kohaUsername, kohaPassword }) => {
var user =
typeof username === "undefined" ? kohaUsername : username;
var pass =
typeof password === "undefined" ? kohaPassword : password;
cy.visitOpac("/cgi-bin/koha/opac-main.pl?logout.x=1");
cy.get("#userid").type(user);
cy.get("#password").type(pass);
cy.get("#auth .action").contains("Log in").click();
}
);
});
Cypress.Commands.add("left_menu_active_item_is", label => {