Commit Graph

60762 Commits

Author SHA1 Message Date
Baptiste Wojtkowski a71ffe1263
Update release notes for 25.11.07 release
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-08-06 15:04:23 +00:00
Baptiste Wojtkowski d340401088
Increment version for 25.11.07 release 2026-08-06 14:56:15 +00:00
David Cook 25edf5f980
Bug 42847: [24.11] Fix unit test 2026-08-06 14:48:04 +00:00
Baptiste Wojtkowski 388d8c2ba7
Bug 42485: (RMaint follow-up) Tidy ES file 2026-07-30 09:26:17 +00:00
Martin Renvoize 3320978bba
Bug 42471: (follow-up) prevent XSS in suggestion status
The custom/authorized-value status branch concatenated row.status
directly into a class="..." attribute string. escape_str() only
escapes &, <, > (not quotes), so a status code containing a double
quote could still break out of the attribute.

Build the status <span> via DOM APIs instead, the same way the
reason field was fixed: fixed statuses get a hardcoded class, and
the free-form status code goes into a data-status attribute via
dataset, which the DOM escapes safely regardless of content.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:54:46 +00:00
David Cook a5202afdf1
Bug 42471: (follow-up) prevent XSS in suggestion reason
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:54:45 +00:00
Jonathan Druart 9d9ee5ba75
Bug 42471: Prevent XSS in suggestion.tt
escape_str all the things

Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:54:38 +00:00
Martin Renvoize eac00c5118
Bug 30233: (follow-up) Fix POD formatting codes in _apply_substitution
The angle-bracket delimiter notation in the POD prose (e.g.
PATTERN<DELIM>) caused the POD parser to treat the trailing letter of
each word as an unknown formatting code (N<>, T<>). Replace with
C<s/PATTERN/REPLACEMENT/FLAGS> and a parenthetical note that any
non-space delimiter is accepted.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 08:26:59 +00:00
Martin Renvoize 910aa5d705
Bug 30233: (follow-up) Add tests for _apply_substitution and combined modifiers
- t/C4/ClassSplitRoutine/RegEx.t (new): exercises _apply_substitution via
  the public split_callnumber interface — basic substitution, alternate
  delimiters, \n/$n backrefs, /gi combined flag, /e rejection, and malformed
  or uncompilable rules (including the new logger warn path).
- t/Koha/Regex/Replacement.t: extend the subst() helper to handle the ig/gi
  combined modifier and add a subtest that confirms case-insensitive global
  replacement and backref case preservation.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 08:26:58 +00:00
Martin Renvoize 8b3ff675c1
Bug 30233: (follow-up) Log a warning when _apply_substitution discards a bad pattern
When eval { qr/$pattern/ } fails (e.g. the admin-configured s/// contains
an invalid regex), _apply_substitution previously returned silently with no
indication of why the rule was skipped. Add a Koha::Logger warn so the
failure appears in the log and is diagnosable without a debugger.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 08:26:57 +00:00
David Cook 70eb221030
Bug 30233: (follow-up) fix some errors reported by QA tools
Note: While the methodology in Koha::Regex::Replacement may seem
bespoke, it's similar to how Python's re.sub(pattern, repl, string)
regex substitution works.

Unit tests:
prove -v t/Koha/Regex/Replacement.t \
    t/SimpleMARC.t \
    t/db_dependent/MarcModificationTemplates.t \
    t/Labels_split_Regex.t

Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 08:26:56 +00:00
Sanjar Tulkinov Anvar o'g'li 4c7b2972e2
Bug 30233: Stop running call number split regexes as code
C4::ClassSplitRoutine::RegEx::split_callnumber ran the admin-configured rule
through eval "\$cn_item =~ $regex", executing arbitrary Perl. Parse the
rule as s<DELIM>PATTERN<DELIM>REPLACEMENT<DELIM>FLAGS, reject the /e flag,
compile the pattern with qr// and expand the replacement as data via
Koha::Regex::Replacement::expand_template, so the rule is applied without
eval.

Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 08:26:55 +00:00
Sanjar Tulkinov Anvar o'g'li ada5871991
Bug 30233: Stop running MARC modification replacements as code
Koha::SimpleMARC::_modify_values and Koha::Items::apply_regex wrapped the
user replacement in a string and ran it through s///ee, so an interpolation
block such as \@{[ system(...) ]} executed arbitrary Perl. Expand the
replacement as data via Koha::Regex::Replacement::expand_template under a
single /e instead, which keeps capture-group replacements working but never
runs the input as code.

Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 08:26:51 +00:00
Sanjar Tulkinov Anvar o'g'li a4017301c8
Bug 30233: Add Koha::Regex::Replacement to expand replacements as data
Add a small single-pass helper, Koha::Regex::Replacement::expand_template,
that expands a user-supplied regex replacement string as data: numbered
backreferences ($1..$n, ${n}, the legacy \1..\9 form), named captures
($+{name}, ${name}) and the \n \r \t escapes. Every other character is
copied through literally, so \@{...}/${...} interpolation blocks end up as
text rather than being run. This is used to replace the s///ee double-eval.

The routine is fully qualified at the call sites rather than exported, and
case folding is left out to keep it small.

Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 08:22:32 +00:00
Martin Renvoize da3a09f5ea
Bug 42746: (QA follow-up) Sanitize agefield and substitution field at the sink too
The original fix only whitelisted agefield, condition_field, and
substitution_field at the point they're saved in
tools/automatic_item_modification_by_age.pl, leaving the actual
consumer of the stored syspref, C4::Items::ToggleNewStatus, trusting
agefield and substitution field unchecked. agefield is spliced
directly into raw SQL (TO_DAYS($agefield)) and so can't be
parameterized like an ordinary value; substitution field reaches a
dynamic method call ($item->$field($value)). Any future or
alternate writer of the automatic_item_modification_by_age_configuration
syspref would have reopened both holes without touching the form at
all.

This adds the same allow-list validation directly in ToggleNewStatus
(falling back to the safe default agefield, or skipping the
substitution/condition, exactly as before for missing values), shares
the age-field allow-list between the two files via a new
GetAutomaticItemModificationAgeFields() in C4::Items so it can't drift
between them, and logs rejected values via Koha::Logger instead of
silently discarding them so tampering leaves an audit trail.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:29 +00:00
Jonathan Druart 3b53d6711d
Bug 42746: Sanitize condition and substitution fields
Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>

Amended-by: Jonathan Druart:
Replace , with ;

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:28 +00:00
Jonathan Druart 5cf846f9f8
Bug 42746: Sanitize age_field
Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>
2026-07-30 08:22:27 +00:00
Martin Renvoize 5b825da072
Bug 42747: (QA follow-up) Parameterize query, dedupe, and log rejections
The original fix only whitelisted image_name at the point it's saved
in edit-layout.pl, leaving the actual injection sink in create-pdf.pl
unparameterized. This adds defense-in-depth by fixing the query itself,
avoids a redundant duplicate call to get_all_image_names() (already
fetched earlier in the script as $image_names), and logs rejected
image_name values instead of silently discarding them so tampering
attempts leave an audit trail.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:26 +00:00
Jonathan Druart dc4403aae0
Bug 42747: Prevent SQL injection via image_name in edit-layout
Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:25 +00:00
Jonathan Druart c5968932fc
Bug 42866: Prevent SQL injection in Koha::AddtionalContents->search_for_display
Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
2026-07-30 08:22:25 +00:00
Jonathan Druart cb22264499
Bug 42749: Prevent SQL injection from GetInvoices (order_by)
Signed-off-by: Sanjar Tulkinov Anvar o'g'li <sanjarbiy11@gmail.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:24 +00:00
Martin Renvoize c6afa10d07
Bug 42847: (QA follow-up) Clear session state on all login_core exit paths
login_core only cleared leftover session state on the failed-auth
branch. The earlier 'SIP access not authorized' return (unknown
terminal id) left any account/ils/institution/policy/credentials from
a prior connection on a reused prefork worker in place.

Move the reset to the top of login_core so every non-success exit path
leaves clean state, and only a successful api_auth re-establishes the
session. This keeps the no-authenticated-state-until-auth invariant in
a single place rather than duplicating the key list per branch.

Also extend the unit test to cover the unknown-terminal path on a
reused worker.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:23 +00:00
Kyle M Hall 6aaa9d2264
Bug 42847: Prevent previously authenticated user
After a SIP terminal logs in successfully, a later connection handled by the
same worker could bypass authentication entirely. login_core() stores the account
in the session before calling api_auth(), and left it in place when authentication
failed. The check in raw_transport() that is meant to drop unauthenticated connections
only looks at $self->{account}->{id}, which is now populated straight from the SIP config,
so the connection is treated as logged in.

Test Plan:
1) Create a SIP user with the username and password "term1"
2) Restart the SIP server
3) Apply the first patch
4) prove t/db_dependent/SIP/MsgType.t
5) Note the new test fails
6) Telnet to the SIP server port ( 6001 for ktd )
5) Send a successful login: 9300CNterm1|COterm1
6) Note you get a 941 back
7) Disconnect, then telnet to localhost 6001 again
8) Send a bad login: 9300CNterm1|COterm2
9) Note you get a 940 back, but the connection stays open
10) Send a patron information request, using a real patron cardnumber:
    6300120260615    110310          AOCPL|AA23529001000463
11) Note you get a 64 patron information response with the patron's data back,
    even though the login failed!
12) Apply the second patch
13) prove t/db_dependent/SIP/MsgType.t
14) Note the subtest now passes!
15) Restart all the things!
16) Repeat steps 4 to 10
17) Note the the patron info request returns no patron data and the connection is dropped!

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:22 +00:00
Kyle M Hall cbb897f4d8
Bug 42847: Add unit tests
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
2026-07-30 08:22:21 +00:00
Laura_Escamilla 2dff8abf7f
Bug 43019: Prevent access to pages belonging to another library (staff side)
To test:
1. Create two patron accounts:
    * One patron whose home library matches the library assigned to the page.
    * One patron whose home library is different from the library assigned to the page.
2. Create a new page with the following settings:
    * Display location = OPAC
    * Library = a specific library
    * Publication date = Today
    * Title and Content = minimally necessary content
3. Save the page.
4. Right-click the OPAC link and copy the link address.
5. Open the link in an incognito or private browser window without signing in.
    * Confirm that the library-specific page is not displayed.
    * Confirm that a 404 page is shown.
6. In the incognito window, sign in using the patron account whose home library matches the page library.
7. Open the copied OPAC link again.
    * Confirm that the page is displayed.
8. Sign out and sign in using the patron account whose home library does not match the page library.
9. Open the copied OPAC link again.
    * Confirm that the page is not displayed.
    * Confirm that a 404 page is shown.
10. Edit the page and change Library to All libraries.
11. Open the OPAC link in an incognito or private browser window without signing in.
    * Confirm that the page is displayed.
12. While signed in as each patron account, open the OPAC link again.
    * Confirm that the page is displayed for patrons from both libraries.
13. Create or edit a page with the following settings:
    * Display location = Staff interface
    * Library = a specific library
    * Publication date = Today
    * Title and Content = minimally necessary content
14. Sign in to the staff interface using a staff account whose library matches the page library.
15. Open the page from the staff interface.
    * Confirm that the page is displayed.
16. Sign out and sign in using a staff account whose library does not match the page library.
17. Open the staff page link directly.
    * Confirm that the page is not displayed.
    * Confirm that a 404 page is shown.
18. Edit the staff page and change Library to All libraries.
19. Open the page while signed in with staff accounts from both libraries.
    * Confirm that the page is displayed for both accounts.
20. Repeat the OPAC and staff interface checks using Display location = Staff interface and OPAC.
    * Confirm that the page is displayed in both interfaces for users from the matching library.
    * Confirm that users from a different library receive a 404 page.
    * Confirm that pages assigned to All libraries are available in both interfaces.

Signed-off-by: David Cook <dcook@prosentient.com.au>
2026-07-30 08:22:20 +00:00
David Cook 16df1a33b2
Bug 43019: Fix branch comparison
This change fixes the branch comparison between the Page
and the user. Previously, it was doing a numeric "!=" and now it
does the string comparison "ne". Also, if no environmental variable
is set for the default branch, it defaults to an empty string
for anonymous (ie non-authenticated) users.

Test plan:
0. Apply the patch
1. restart_all
2. Log into the staff interface
3. Go to Tools
4. Click on "Pages"
5. Create a Page for All Libraries for the OPAC
6. Copy the "OPAC" link in the "Page URL" table cell and open it
in a private window or a separate browser
7. Note that the page appears
8. Now change the "Page" to a specific library
9. Revisit the URL in the private window
10. Note that it now gives a 404 error
11. Log into the OPAC with a user whose library matches the libary
of the Page
12. Note that now you can view the URL again
13. Change the library of the user or the Page
14. Note that you cannot see the Page now

Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
2026-07-30 08:22:19 +00:00
Laura_Escamilla 36e813c06a
Bug 42919: Retain suggestion form values when duplicate warning is shown
To test:

1. Make a suggestion that will trigger a duplicate warning, in KTD I like "Clothes, clothes, clothes, music, music, music, boys, boys, boys".
2. Fill out some other details, like notes and public notes.
3. The warning says "Click on "Confirm your suggestion" to ignore this message."
4. Notice none of the details are still there.
5. Apply the patch
6. Repeat steps 1-3. Notice that the details remain now after you get the warning message.
7. Submit the form to ensure all details are saved correctly.
8. Sign off and have a lovely day. :D

Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-30 07:50:17 +00:00
Laura_Escamilla a6d43aad1c
Bug 42234: Add text to checkout history cover image table header
1. Enable at least one cover image service, such as GoogleJackets or
   OPACAmazonCoverImages.
2. Log in to the OPAC as a patron with checkout history.
3. Go to your account > Checkout history.
4. Inspect the checkout history table header.
5. Confirm the cover image column header contains "Cover image".
6. Confirm the table still displays correctly.
7. Confirm sorting/export behavior is unchanged for that column.
8. Sign off and have a wonderful day! :D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 946ce25c52)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 16:02:24 +00:00
Martin Renvoize 88765a86ab
Bug 42485: (QA follow-up) Add explicit JSON::PP import and test coverage
Add explicit `use JSON::PP ()` to Elasticsearch.pm and the test file
to make the dependency on JSON::PP::false visible rather than relying
on YAML::XS loading it as a side effect.

Extend the get_elasticsearch_mappings() test subtest to assert that
date_detection and numeric_detection are disabled at the mapping root.

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 40b9e8abd5)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 16:00:51 +00:00
Tomás Cohen Arazi 7ab4ec84bd
Bug 42485: Disable date and numeric detection on ES mappings
When ElasticsearchMARCFormat is set to ARRAY, the marc_data_array
field uses dynamic:true mapping. Elasticsearch auto-detects field
types based on the first document indexed. If a MARC subfield value
looks like a date (e.g. 2024-01-15 in 952$e), ES locks that
subfield to type date. Subsequent records with non-date values in
the same subfield fail to index with a document_parsing_exception.

This patch sets date_detection and numeric_detection to false at
the mapping root level, so ES treats all dynamically mapped fields
as text instead of guessing types.

Test plan:
1. $ ktd --search-engine es8 --name test-es --proxy up -d
   $ ktd --name test-es --wait-ready 180
   $ ktd --name test-es --shell
2. k$ koha-mysql kohadev -e "UPDATE systempreferences
     SET value='ARRAY'
     WHERE variable='ElasticsearchMARCFormat';"
   k$ echo 'flush_all' | nc -q1 memcached 11211
   k$ koha-mysql kohadev -e "DELETE FROM biblio_metadata;
     DELETE FROM items; DELETE FROM biblioitems;
     DELETE FROM biblio;"
   k$ rebuild_elasticsearch.pl -d -r --biblios
3. Add a record with date-like 952$e and index it:
   k$ koha-shell kohadev -p -c 'perl -MC4::Biblio
     -MMARC::Record -MMARC::Field -MKoha::Item -e "
     my \$r = MARC::Record->new();
     \$r->append_fields(
       MARC::Field->new(q{245},q{1},q{0},a=>q{Record one}),
       MARC::Field->new(q{942},q{ },q{ },c=>q{BK}));
     my (\$bn) = C4::Biblio::AddBiblio(\$r, q{});
     Koha::Item->new({biblionumber=>\$bn,
       biblioitemnumber=>\$bn, homebranch=>q{CPL},
       holdingbranch=>q{CPL}, itype=>q{BK},
       booksellerid=>q{2024-01-15}})->store;
     print qq{Added biblio \$bn\n};"'
   k$ rebuild_elasticsearch.pl --biblios -bn <biblionumber>
4. Check the mapping for 952$e:
   k$ curl -s es:9200/koha_kohadev_biblios/_mapping/field/\
     marc_data_array.fields.952.subfields.e
=> FAIL: type is "date" (should be "text")
5. Add a record with non-date 952$e and index it:
   k$ koha-shell kohadev -p -c 'perl -MC4::Biblio
     -MMARC::Record -MMARC::Field -MKoha::Item -e "
     my \$r = MARC::Record->new();
     \$r->append_fields(
       MARC::Field->new(q{245},q{1},q{0},a=>q{Record two}),
       MARC::Field->new(q{942},q{ },q{ },c=>q{BK}));
     my (\$bn) = C4::Biblio::AddBiblio(\$r, q{});
     Koha::Item->new({biblionumber=>\$bn,
       biblioitemnumber=>\$bn, homebranch=>q{CPL},
       holdingbranch=>q{CPL}, itype=>q{BK},
       booksellerid=>q{My Vendor Name}})->store;
     print qq{Added biblio \$bn\n};"'
   k$ rebuild_elasticsearch.pl --biblios -bn <biblionumber> -v -v -v
=> FAIL: document_parsing_exception - failed to parse date field
   [My Vendor Name]
6. Apply this patch, repeat from step 2
7. Repeat step 4:
=> SUCCESS: type is "text"
8. Repeat step 5:
=> SUCCESS: No indexing errors
9. Sign off :-D

Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 78850b4a15)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 16:00:50 +00:00
Jonathan Druart 044237c121
Bug 41992: Do not restore pagination offset
When "Save configuration state on page change" is enabled, the page
number is kept in localStorage and restored.

To prevent that we can set the attribute "start" of the state to 0.

Test plan:
Go on a page with several pages, go to another page than the first one
Go the another view and get back
Without this patch the last visited page was preserved when returning to the previous view
With this patch applied the view now defaults to the first page

Note that this does not affect shareable links.

Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 91f2e47f49)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 15:57:07 +00:00
Owen Leonard 8ac4968e41
Bug 42229: (follow-up) Restore card number <label> when necessary
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit efff7c7046)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 15:12:55 +00:00
Owen Leonard 21dd4a6e44
Bug 42229: (follow-up) Markup correction
The "Street type" fields had double "name" attributes.

Signed-off-by: Owen Leonard <oleonard@myacpl.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit b9bff3256a)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 15:12:54 +00:00
Laura_Escamilla 1f8ec51be7
Bug 42229: Avoid using form labels for static values in opac-memberentry.tt
The OPAC personal details page uses <label> elements in some places
where no visible form control is present. In these cases, the content
is display-only and the label is not associated with an interactive
field.

Replace those labels with non-form markup for static values while
preserving existing labels for actual form controls.

Test plan:
1. Log in to the OPAC and go to the "Personal details" page
2. Inspect display-only values such as Username and Expiration date
3. Confirm <label> elements are used for content that is not part of a
   form control
4. Apply the patch
5. Log in to the OPAC and go to the "Personal details" page
6. Confirm display-only values such as Username and Expiration date no
   longer use <label> elements
7. Confirm other static display-only values updated by the patch also no
   longer use <label> elements
8. Confirm actual form controls, such as text inputs and selects, still
   have proper associated labels
9. Run an accessibility checker and confirm the related label misuse
   issues are resolved
10. Sign off and have a great day!

Signed-off-by: Owen Leonard <oleonard@myacpl.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit c416062ef0)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 15:12:49 +00:00
Laura_Escamilla b503890b49
Bug 42232: Add missing legend to action fieldset in OPAC
To test:
1. Log on to the OPAC and go to "Messaging" page.
2. The fieldset that contains the Save/Cancel button is missing a legend.
3. Apply the patch and refresh the "Messaging" page.
4. Notice that the fieldset now contains an accessible legend.
5. Sign off and have a great day!

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit a8e7087ce8)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:57:52 +00:00
Laura_Escamilla 9f31ed6cf2
Bug 42233: Add accessible text to empty purchase suggestions table header
The first header cell in the OPAC purchase suggestions table contains
only an icon, leaving the <th> without accessible text. This causes
the column header to be announced unclearly by assistive technology
and can be flagged by accessibility testing as an empty table header.

Add visually hidden text to the header so the column has a meaningful
accessible name while preserving the current visual display.

Test plan:
1. Log in to the OPAC
2. Make a purchase suggestion
3. In the suggestions table, the first <th> contains no text
4. Apply the patch
5. Repeat steps 1-2
6. Inspect the suggestions table header
7. Confirm the first <th> now contains visually hidden text describing
   the checkbox selection column
8. Confirm the info icon still appears and its tooltip still works
9. Run an accessibility checker or inspect the DOM and confirm the
   empty table header issue is resolved

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit e07b92e48a)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:57:16 +00:00
Nick Clemens d9a707455a
Bug 42245: Prevent preselecting sort values for guarantor search
av-build-dropbox.inc takes a 'default' param

When building the patron we are setting this to the value of sort1, then sort2
This seems to remain cached, and when we build the guarantor search the sort2 value is used as the default
This patch ensures we pass a blank default to the modal

To recreate:
1 - Define 2 values for 'BSort1' in Administration -> Authorised values
2 - Define 2 values for 'BSort2' in Administration -> Authorised values
3 - Find a borrower who is eligible to have a guarantor
4 - Edit patron and assign values to sort 1 and 2 for this borrower and save
5 - Edit patron again and click 'Add guarantor'
6 - Note that sort 2 is populated
7 - Apply patch
8 - Reload borrower
9 - Confirm sort1 and 2 are empty

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 183d1cf211)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:55:59 +00:00
Laura_Escamilla d6d83bf73d
Bug 42299: Add accessible label to star rating select in OPAC
To test:
1. Set  OpacStarRatings so it shows on the OPAC detail page
2. Notice star ratings has no associated label element
3. Apply the patch and refresh the OPAC detail page you were viewing.
4. Notice that the star ratings now have an accessible label.
5. Sign off and have a great day. :D

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit fda196565d)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:53:44 +00:00
Johanna Räisä eb9aff3c81
Bug 42395: Fix missing translations on load_patron_holds_table
This patch adds missing translations for the load_patron_holds_table function.

Sponsored-by: Koha-Suomi Oy
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 07325de908)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:52:38 +00:00
Emmi Takkinen c18d62e71d
Bug 41829: Set correct id to copied Tag editor button
When one copies MARC field, Tag editor button on fields
containing value builder plugin have same id as original
MARC field. This patch sets correct id to these buttons.

To reproduce:
1. Find MARC framework which has value builder plugin
   attached to one of its fields.
2. Navigate to Cataloging -> New record.
3. Navigate to MARC field with plugin attached to it.
4. Inspect fields Tag editor button with browsers developer
   tools.
   -> Check the id of Tag editor button.
5. Copy the field and check id of copied Tag editor button.
   -> Notice that it has the same id as in original field.
6. Apply this patch.
7. Referesh the page, navigate back to field and copy it.
8. Inspect Tag editors id.
   -> Id should now be same as in other copied fields.

Sponsored-by: Koha-Suomi Oy
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit c28b9b86ca)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:45:21 +00:00
Jonathan Druart 1203c94195
Bug 42781: Do not modify window.name
https://developer.mozilla.org/en-US/docs/Web/API/Window/name

Test plan:
0. Do not apply this patch (you can apply the first one)
1. Go to /cgi-bin/koha/members/members-home.pl
2. Open the console
3. type "window.name", it's ""
4. Run a patron search, "d"
5. window.name is now "Duffy, Joann name"
6. Apply this patch, try again
7. window.name is still an empty string

Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit bba0146b3d)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:44:30 +00:00
Magnus Enger 76857ac5e2
Bug 42781: Declare 'name' before using it in patron-format.js
The code in koha-tmpl/intranet-tmpl/prog/js/patron-format.js uses
a variable called 'name' without declaring it first. The declaration
was removed in bug 32176. No deterioration of functionality has been
discovered in connection with this, but the declaration should be
restored.

To test:
- Apply the patch.
- HidePatronName = Show
- Look at the staff detail view for a record that has at least one
  item on loan.
- Verify the name of the patron is displayed as expected.

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 7b02715f4f)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:44:29 +00:00
Jan Kissig f581158da2
Bug 42844: Fix broken subscription search when using additional fields as seach criteria
This fixes an error when searching for a subscription with an additional field when no result is found by changing the call of SearchSubscriptions to expect an array instead of an hash ref.
Serials.pm, when using filter_by_additional_fields may return an empty array, but the calling function only checked for an hash ref which lead to an error when no result was found.

Testplan:
a) create an additional field for subscriptions: More -> Serials -> Manage subscription fields
   f.e. use an AV CCODE as additional field
   make sure "searchable" is checked
   No subscription should use this additional field by now.
b) go to More -> Serials
c1) if bug 40201 is pushed you can search for that additional field on serials-home
   -> An error stack trace will appear.
c2) otherwise perform an empty search on serials home to end on serials-search. In the search form on the left select that additional field as search criteria.
   -> An error stack trace will appear.
d) add a subscription using that additional field
  -> More -> Serials -> New subscription.
  On step two there is a section for Additional fields. Select f.e. CCODE Fiction
e) redo c1 or c2 using that additonal field value as search criteria.
f) Check that the search result shows your subscription.
g) apply patch and redo c1 or c2 for an additional field value that is not used (f.e. Non-fiction)
h) The search should work now, returning 0 results instead of an error
i) check that searching for a used additional field (f.e. Fiction) still works

Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit a26800691f)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:42:36 +00:00
Pedro Amorim 88ae89c5ea
Bug 42783: Fix ManageMarcImport_spec.ts
If import_batch_profiles is slow to respond, it'll trigger select.change() in stage-marc-import.tt and change the format to ISO2709 before the form is submitted, causing the error.

cypress run --spec t/cypress/integration/Tools/ManageMarcImport_spec.ts

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 838fa2f78b)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-29 14:41:41 +00:00
Owen Leonard 44b5d57da1
Bug 42518: Capitalization: Refund Payout Receipt
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit f4c0819644)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-08 14:29:32 +00:00
David Nind af58b42b19
Bug 42695: (follow-up) Format paragraph
Moves the explanation sentence into its own paragraph.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit d2df80f20d)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-08 14:28:26 +00:00
Owen Leonard 8cc8b88af9
Bug 42695: Minor language and markup corrections to reports error messages
This patch makes a vew minor corrections to guided_reports_start.tt.

To test apply the patch and go to Reports.

- Try to create an SQL report which uses UPDATE, e.g.
  UPDATE items SET barcode = 1 WHERE itemnumber = 1
- Confirm that the text of the error message reads well and is formatted
  well.

Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 6fa6228f73)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-08 14:24:58 +00:00
Pedro Amorim 13773ecf7f
Bug 42705: Fix SCO spec WebBasedSelfCheck setup
cy.login() in beforeEach broke the test in two ways: the intranet staff session cookie bled into the OPAC request (HTTP cookies have no port scope in
browsers), and navigating from intranet→OPAC mid-test hit a cross-origin block in Cypress. The afterEach suffered the same race condition - the syspref POST fired before the login redirect completed.

Replace with cy.request(), which makes HTTP calls at the runner level without touching the browser's current origin. cy.visitOpac() is then the first
browser navigation, so no cross-origin issue arises. A three-step flow satisfies Koha's CSRF middleware:
1) GET the login page to obtain a session and its token
2) POST credentials to authenticate
3) POST to the svc endpoint.

This fixes the #barcode and #patronlogin not found issues

The CSRF token also requires encodeURIComponent() — base64 uses +, which a
URL-encoded form body decodes as a space, silently corrupting the token and causing the login to fail.

This resolves the 403 Forbidden issue

Everything must pass:
$ cypress run --spec t/cypress/integration/OPAC/SCO_spec.ts

as well as npm run cypress open (cypress ui)

ktd selenium:
$ perl /kohadevbox/misc4dev/run_tests.pl --run-only t/cypress/integration/OPAC/SCO_spec.ts

squash

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
2026-07-08 14:07:37 +00:00
Pedro Amorim 8527fdf29f
Bug 42705: Add HttpClient_spec.ts
This fails without the fix patch in this set:
cypress run --spec t/cypress/integration/HttpClient_spec.ts

It passes with the fix

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 5baf1ce6e0)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-08 14:01:10 +00:00
Pedro Amorim 66fc0daf4a
Bug 42705: Make http-client.js handle svc endpoint error
The afterEach calls cy.login() then immediately posts to the syspref endpoint. On CI, the machine is slow enough that the POST fires before the login
redirect completes — no valid session yet — so the endpoint returns a C4::Service auth error in this format:

{ "type": "auth", "message": "expired" }

http-client.js only knew how to parse modern REST API errors (json.error or json.errors[]). Neither field exists here, so json.errors.map(...) crashed with a TypeError instead of surfacing the actual error message.

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 4e87782636)
Signed-off-by: Baptiste Wojtkowski <baptiste.wojtkowski@biblibre.com>
2026-07-08 14:00:51 +00:00