Sponsored-by: ByWater Solutions
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This adds a command-line utility script that allows administrators to reset
a patron's two-factor authentication settings when they lose access to their
authenticator device.
The script uses the new Koha::Patron methods and provides:
* Parameter validation (mutually exclusive userid/cardnumber/patron_id)
* User-friendly error messages and feedback
* Verification that patron has 2FA enabled before attempting reset
To test:
1. Enable TwoFactorAuthentication system preference
2. Set up 2FA for a test patron
3. Run:
$ ktd --shell
k$ perl misc/admin/reset_2fa.pl --userid <userid>
=> SUCCESS: Script resets 2FA and shows confirmation message
4. Verify patron can log in with password only
5. Test error cases:
- No parameters: shows usage message
- Multiple parameters: shows mutual exclusivity error
- Non-existent user: shows user not found error
- User without 2FA: shows informational message
=> SUCCESS: All scenarios work as expected
6. Sign off :-D
Sponsored-by: ByWater Solutions
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This adds two new methods to Koha::Patron for managing two-factor authentication:
* has_2fa_enabled() - Returns 1 if patron has 2FA enabled, 0 otherwise
* reset_2fa() - Clears secret and sets auth_method to 'password'
The reset_2fa method includes audit logging when BorrowersLog is enabled
and returns the patron object for method chaining.
To test:
1. Apply patch
2. Run:
$ ktd --shell
k$ prove t/db_dependent/Koha/Patron.t
=> SUCCESS: Tests pass!
3. Sign off :-D
Sponsored-by: ByWater Solutions
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
We needed better idempotency around checking for fields before
attempting to use them during migration and then dropping them.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
In the unit test system we reset the database version to 21.11 after
having upgraded a long way past that. The 231200022 update appears not
to be fully idempotent, so we fail running through the upgrade.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
In the unit test system we reset the database version to 21.11 after
having upgraded a long way past that. The 221200041 update appears not
to be fully idempotent, so we fail running through the upgrade.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
We can use the isValid's dayjs function instead of our own parsing
functions.
Test plan:
Confirm that you cannot enter an invalid date when using a date picker widget.
Works as expected.
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
I just added an exception in the script. Sorry for the inconvenience.
Test Plan:
1- Enable the following system preference: OpacStarRatings (results,
details, and patron).
2- Apply the patch.
3- Go to the Opac.
4- Search a record.
5- Inspect the HTML code before the stars and notice that there is "Star
rating" in a span tag with the class "sr-only". Inspect the stars,
there should be a span tag for each star. After the stars, notice
that there is the average rating in a span with the "sr-only" class.
6- Click on a record and do the same as the 5: go to the star rating,
inspect the HTML code, and notice that there is a span tag for each
star.
7- Now, log into an account.
8- Search a record.
9- It should be the same information as in the step 5.
10- Click on a record to view the details. Now, you can change the
rating. Inspect the stars, each should have the number of stars in
the span tag with a "sr-only" class, which are in the link tags.
11- For this part, you need to have a record checked out (if you don't
have a record checked out, go to the staff interface and do it.
Choose your patron and enter the barcode of the record).
12- Go to your account. In the "Checked Out" section, you should see the
same as in the 10 step: the number of stars and be able to change
your rating or make a new one.
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>
Test plan:
Enable the following system preferences: CookieConsent, EnableOpacSearchHistory, and OpacLangSelectorMode (both top and footer).
-Apply the patch.
-Go to the Koha OPAC.
-Check the vertical dividers in the navigation.
-If they are present with a coherent design, the test is successful.
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
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>
With the move to the latest ES versions we got rid of 'data' type - we need to use '_doc'
To test:
1 - Delete a record from the DB directly
DELETE FROM biblio WHERE biblionumber=45;
2 - perl misc/maintenance/compare_es_to_db.pl
3 - Try the curl command - it doesn't work
4 - Apply this patch
5 - perl misc/maintenance/compare_es_to_db.pl
6 - Try the curl command - it now fetches the record
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds --biblios and --authorities options to the script to allow
checking only a single index
To test:
0 - Apply patch
1 - perl misc/maintenance/compare_es_to_db.pl
2 - biblios and authorities are checked
3 - perl misc/maintenance/compare_es_to_db.pl -b
4 - Only biblios are checked
5 - perl misc/maintenance/compare_es_to_db.pl -a
6 - Only authorities are checked
7 - perl misc/maintenance/compare_es_to_db.pl -a -b
8 - Both indexes are checked
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds table configuration options to the serial claims table,
including the option to set a default sort column.
The patch also moves the table column filter row to the top, which I
think is more standard in the staff interface.
To test, apply the patch and restart services.
- You'll need to have subscription issues which are missing, claimed, or
late.
- Go to Serials -> Claims, and select a vendor.
- In the table of missing issues, confirm that all DataTable controls
work correctly: Column visibility, export, and configuration options.
- Confirm that you can use Administration -> Table settings -> Serials
-> Claims to hide columns by default or set the default order.
- Confirm that the column header filter forms work correctly.
Sponsored-by: Athens County Public Libraries
Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
As the title says, we are missing such endpoints and this patch adds
them.
To test:
1. Apply this patches
2. Run:
$ ktd --shell
k$ yarn api:bundle
k$ prove t/db_dependent/api/v1/patrons_accounts.t
=> SUCCESS: The spec builds!
=> SUCCESS: The tests pass!
3. Verify all the codepaths are covered by tests
4. Sign off :-D
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
To test:
0. APPLY PATCH and resart_all
1. Make sure you have items with itemcallnumber's in your DB
2. Visit http://localhost:8081/cgi-bin/koha/cataloguing/plugin_launcher.pl?q=1&plugin_name=cn_browser.pl and make a search
3. You should see a column for Shelving location now
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>
This patch adjusts the style of the Select2 field in the sidebar. It
should have 100% width and the selections should word-wrap.
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: David Flater <flaterdavid@gmail.com>
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>
To test:
0. APPLY PATCH and restart_all
1. Place some holds with different shelving locations and collection
codes.
2. Build the holds queue
3. Go to Circulation > Holds queue
4. Notice that shelfing location and collection code are now multi
select2 dropdowns
5. Try searching for various combos of shelfing locations and collection
codes.
6. Make sure the results are correct.
7. After making selections and running the search make sure your
selections are retained in the search form in the left nav bar
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>
Development wise it is much simpler to do this check in perl when
opening the editor than getting this logic into the template with
javascript. Furthermore, older data may be corrupted, but we trust
the current plugins to not insert such fields anymore.
Test plan:
Run t/db_dependent/Koha/Biblio/Metadata/Extractor/MARC/MARC21.t
Open an existing record in the basic editor. Shorten 008 without plugin.
Save and open the record again. Do you get the alert?
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
The routine to create the message can return nothing if there is no content,
we should handle this case and not attempt to send.
To test:
1 - Test plan from last patch
2 - Apply this patch
3 - POST to patron API again
4 - Success!
Signed-off-by: Claire Hernandez <claire.hernandez@biblibre.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Currently we assume BadParameter has been thrown with a parameter that is a valid patron field.
It may only include a message, or it may have come from outside the patron object, we should
handle all cases.
To test:
1 - Wrap "WELCOME" notice content in conditional:
[% IF borrower.categorycode != 'SELFREG' %]
...
[% END %]
2 - Enable preference AutoEmailNewUser
3 - Attempt to self register a patron via API with body:
{"surname":"PATRON","firstname":"PROBLEM","library_id":"CPL","category_id":"SELFREG","email":"eample@example.org"}
4 - Response error: "Given does not exist"
5 - Apply this patch, restart all
6 - Repeat 3
7 - Response error: "Exception 'Koha::Exceptions::BadParameter' thrown 'Parameter message_id cannot be empty if passed.'\n"
8 - It's uglier, but actually helpful
Signed-off-by: Claire Hernandez <claire.hernandez@biblibre.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch completes the deprecation cycle started in bug 36343 by
removing the backward compatibility code and deprecation warnings for
the old after_biblio_action hook signature.
Changes made:
1. Removed the duplicate biblio and biblio_id parameters from
_after_biblio_action_hooks in C4::Biblio that were marked for
deprecation in 24.11.00
2. Updated the test plugin to use only the new payload-based signature,
ensuring all parameters are accessed via $params->{payload}
The after_biblio_action hook now consistently uses the modern signature
with a payload parameter, matching the pattern used by other plugin hooks
like before_biblio_action, after_item_action, and after_hold_action.
Test plan:
1. Run: prove t/db_dependent/Koha/Plugins/Biblio_and_Items_plugin_hooks.t
2. Run: prove t/db_dependent/Koha/Plugins/
3. Run: prove t/db_dependent/Biblio.t
4. All tests should pass
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
We pushed bug 40587 since this bug Passed QA. It introduces a new test
using the older construct, so this patch updates that test to add the
new construct by building a File::Transport.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch updates the EDI accounts management page to display
the new file transport system instead of the old inline transport
configuration fields.
Changes:
- Replaced multiple transport-related columns (Transport, Remote host,
Username, Password, Upload/Download ports and directories) with a
single "File transport" column
- The file transport column displays the transport name with its
connection test status in brackets
- Status indicators match the file_transports page:
* "Tests passing" (green with checkmark icon) for successful tests
* "Errors detected" (red with x icon) for failed tests
* "Never used" (italic) for untested transports
- Updated the Perl controller to decode the JSON status field from
the file_transports table and pass it to the template
- Uses get_inflated_columns to convert DBIx::Class results to plain
hashrefs for template consumption
The display now correctly reflects the architectural change where
transport configuration is managed separately in the file_transports
table rather than duplicated in each EDI account.
Note: At a future date we should replace the raw DBIx::Class methods
with Koha::Object based classes. I propose Koha::EDI::Account(s).
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Fix several API inconsistencies in the FTP transport class:
1. Message format: Use standardized `message => $operation` format
instead of hardcoded strings like "Upload succeeded"
2. Operation tracking: Add $operation variable to all methods for
consistent error reporting and logging
3. Error handling: Update _abort_operation() to accept operation
parameter and provide more detailed error payloads
4. Success payloads: Replace empty `detail => ''` payloads with
meaningful operation-specific information (host, port, file paths,
directory info, file counts)
All transport classes now have consistent APIs for:
- Standardized message formats
- Consistent operation tracking
- Uniform error handling
- Informative success payloads
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
The EDI test was still creating vendor_edi_accounts with transport='FILE'
which no longer works after the migration to the file_transports system.
Updated all test account creation to:
- Create file_transports records with transport='local'
- Link EDI accounts via file_transport_id instead of direct transport field
- Set appropriate download/upload directories for local testing
All EDI tests now pass with the new transport architecture.
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch completely refactors the EDI transport handling to use the
modern file_transports system instead of legacy direct connections.
Changes:
- Remove legacy FTP/SFTP connection code
- Update constructor to load file_transport from vendor_edi_accounts
- Update download_messages/upload_messages to use modern transport methods
- Use new rename_file() method for EDI file processing workflow
- Remove dependencies on Net::FTP and Net::SFTP::Foreign
- Maintain all EDI-specific functionality (file filtering, ingestion)
Cleanup:
- Remove obsolete methods: file_download, sftp_download, ftp_download,
sftp_upload, ftp_upload, file_upload, _abort_download
- Update POD documentation to reflect new architecture
- 184 lines of legacy code removed
Removed imports:
- use DateTime; - Not used, dt_from_string() used instead
- use English qw{ -no_match_vars }; - No English variables used
- use File::Copy qw( copy move ); - File operations now handled by
Koha::File::Transport internally
The transport system now provides:
- Unified connection handling across all transport types
- Enhanced error reporting and status tracking
- Encrypted credential storage
- Connection testing capabilities
- Support for local directories (testing/development)
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Fix API inconsistency where different transport types returned different
formats from list_files():
- SFTP: returned array of hashrefs with detailed file information
- FTP: returned simple array of filenames
- Local: returned simple array of filenames
Now all transports return an array reference of hashrefs with consistent
structure containing filename, longname, and additional metadata.
This eliminates the need for workarounds like the ref($file) eq 'HASH'
check in EDI code and provides a more robust, consistent API.
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds proper connection cleanup functionality to the file
transport system, addressing a gap identified during EDI migration.
Changes:
- Add disconnect() method to base Transport class interface
- Implement SFTP disconnect using connection->disconnect()
- Implement FTP disconnect using connection->quit()
- Add DESTROY methods to ensure connections are cleaned up on object destruction
- Local transport includes no-op disconnect for API consistency
This ensures that FTP/SFTP connections are properly closed, preventing
connection leaks and potential resource exhaustion issues.
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch enhances the file transport system with file renaming
capabilities and adds a Local transport class for development/testing.
Changes:
- Add rename_file() method to base Transport class and SFTP/FTP subclasses
- Create Koha::File::Transport::Local for local directory operations
- Add 'local' transport type to polymorphic mapping
- Update transport instantiation to handle Local transport
- Add Local transport tests to verify polymorphic behavior
- Enhanced connect() method for Local transport validates directories
The rename_file functionality is needed for EDI file processing workflow
where files are renamed after download to mark them as processed.
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch updates the EDI accounts administration interface to use
the new file_transports system instead of direct transport configuration.
Changes:
- Replace transport configuration fields with transport selection dropdown
- Add file_transports data to template for selection options
- Remove password decryption since credentials are now managed by transports
- Simplify form handling to only manage EDI-specific fields
- Add helpful link to file transport administration
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds database migration to move EDI transport configurations
from vendor_edi_accounts to the new file_transports system introduced
in Bug 39190.
Changes:
- Add file_transport_id column to vendor_edi_accounts with foreign key
- Add 'local' transport type to file_transports enum
- Remove old transport fields from vendor_edi_accounts in kohastructure
- Migration script converts existing EDI configurations to file transports
- Handles FILE -> local transport type conversion
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
We did some last minute renaming of things in bug 39190 but didn't catch
all the places. This patch updates the old 'sftp_servers' naming scheme
to 'file_transports' following the new pattern and restores edit and
delete functionality in the File transports management area.
Sponsored-by: ByWater Solutions
Signed-off-by: Hannah Dunne-Howrie <hdunne-howrie@westminster.gov.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
If we don't want the incremental run we should return early in ->new to
prevent the git clone.
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
If the file had a failure and still has, we should not list it twice.
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
git clone needs https://, but we need to remove it to build the push url
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Victor Grousset/tuxayo <victor@tuxayo.net>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>