Repository navigation
Log in to FOLIO with expiring tokens and support the SCELC member tenant - #10
Merged
Merged
Conversation
FOLIO no longer accepts long-lived API tokens, so the token from /authn/login stopped working. Boffo now logs in with /authn/login-with-expiry, stores the access token, refresh token, and both expiration times in user properties (never the password), and renews the access token with /authn/refresh when it is about to expire or FOLIO returns 401, retrying the request once. All FOLIO GETs go through folioFetch(), so renewal also works partway through long call-number searches. Caltech's FOLIO is moving to the SCELC member tenant cs00000003m013. When a user has no stored refresh token, which is true of every existing user, Boffo copies the default URL and tenant from the script properties over the user's stored values before showing the credentials dialog. The script property boffo_folio_tenant_id must be updated in the Apps Script project. "Clear FOLIO token" deletes all of the token data. PRIVACY.md, the usage docs, README.md, the credentials form, and CHANGES.md describe the new behavior. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename CHANGES.md to CHANGELOG.md and follow Keep a Changelog 1.1.0: add the standard header, rewrite each version heading as "[X.Y.Z] - YYYY-MM-DD" using the tagged release dates, and add comparison links at the bottom. Released entries are unchanged; the Unreleased section groups its entries under Added, Changed, and Fixed. Update the release steps in the Makefile and releaseNotes in codemeta.json to point to the new file name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Caltech’s FOLIO no longer accepts long-lived API tokens, so Boffo’s lookups fail today, and Caltech Library’s FOLIO moves to the SCELC consortial member tenant
cs00000003m013(the API URLs don’t change). This pull request updates Boffo for both.Login and token renewal (
Code.js)saveFolioInfo()logs in withPOST /authn/login-with-expiry. It takes the access token from anx-okapi-tokenheader or thefolioAccessTokencookie, and the refresh token from thefolioRefreshTokencookie. Header names are matched case-insensitively, andSet-Cookiemay be a string or an array.boffo_folio_api_token,boffo_folio_api_token_expires,boffo_folio_refresh_token, andboffo_folio_refresh_token_expires). It never stores the password.folioFetch(). It renews the access token withPOST /authn/refreshwhen less than 60 seconds remain, and on a 401 it renews and retries once. Lookup functions no longer pass a token around, so renewal works partway through long call-number searches and when the call-number dialog stays open for a long time.Tenant
boffo_folio_urlandboffo_folio_tenant_idfrom the script properties over that user’s stored values before showing the credentials dialog. Every existing user starts without a refresh token, so each one gets the new tenant once. After logging in, values the user typed are kept.onInstall()doesn’t run.Docs
PRIVACY.md,docs/usage.md,README.md, and the text incredentials-form.htmldescribe the stored tokens.CHANGES.mdis renamed toCHANGELOG.mdand follows Keep a Changelog 1.1.0, with dated version headings and comparison links. TheMakefileandcodemeta.jsonpoint to the new name.Consortium notes
Boffo calls:
POST /authn/login-with-expiryandPOST /authn/refreshGET /instance-statuses?limit=0GET /inventory/itemsGET /locationsIt never queries instance records directly. Items and holdings belong to the member tenant, so lookups should work. During testing, confirm that the Title and Contributor names columns are filled in for an item on a shared instance, and that the location picker lists Caltech’s locations.
Before release
boffo_folio_tenant_idtocs00000003m013.Merging this doesn’t change the published add-on, which stays pinned to its Apps Script version until a new version is created and selected in the Marketplace SDK settings.
Test plan
Not yet tested against real FOLIO. The token helpers were checked offline in Node with fake Apps Script services (login, cookie parsing, renewal before expiry, retry after a 401, a rejected refresh, the old-tenant migration, and Clear FOLIO token).
For steps 2 and 3, run small functions from the Apps Script editor as yourself to change your user properties, for example:
t1()and then start a large call-number range search. The execution log should show one renewal partway through. Also leave the call-number dialog open for more than 10 minutes before submitting.boffo_folio_refresh_token_expiresto a past time; the next command should show the credentials dialog. Separately, set the refresh token to junk and runt1(); Boffo should clear the tokens and ask you to log in again.boffo_folio_tenant_idtofs00001057andboffo_folio_api_tokento any string, and delete the refresh-token properties. A lookup should open the dialog withcs00000003m013filled in.If renewal fails in step 2, check first that Apps Script sends the
Cookieheader on the/authn/refreshrequest.🤖 Generated with Claude Code