BooksStack's OIDC Client requests the 'profile' and 'email' scope values
in order to have access to the 'name', 'email', and other claims. It
looks for these claims in the ID Token that is returned along with the
Access Token.
However, the OIDC-core specification section 5.4 [1] only requires that
the Provider include those claims in the ID Token *if* an Access Token is
not also issued. If an Access Token is issued, the Provider can leave out
those claims from the ID Token, and the Client is supposed to obtain them
by submitting the Access Token to the UserInfo Endpoint.
So I suppose it's just good luck that the OIDC Providers that BookStack
has been tested with just so happen to also stick those claims in the ID
Token even though they don't have to. But others (in particular:
https://login.infomaniak.com) don't do so, and require fetching the
UserInfo Endpoint.)
A workaround is currently possible by having the user write a theme with a
ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE hook that fetches the UserInfo
Endpoint. This workaround isn't great, for a few reasons:
1. Asking the user to implement core parts of the OIDC protocol is silly.
2. The user either needs to re-fetch the .well-known/openid-configuration
file to discover the endpoint (adding yet another round-trip to each
login) or hard-code the endpoint, which is fragile.
3. The hook doesn't receive the HTTP client configuration.
So, have BookStack's OidcService fetch the UserInfo Endpoint and inject
those claims into the ID Token, if a UserInfo Endpoint is defined.
Two points about this:
- Injecting them into the ID Token's claims is the most obvious approach
given the current code structure; though I'm not sure it is the best
approach, perhaps it should instead fetch the user info in
processAuthorizationResponse() and pass that as an argument to
processAccessTokenCallback() which would then need a bit of
restructuring. But this made sense because it's also how the
ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE hook works.
- OIDC *requires* that a UserInfo Endpoint exists, so why bother with
that "if a UserInfo Endpoint is defined" bit? Simply out of an
abundance of caution that there's an existing BookStack user that is
relying on it not fetching the UserInfo Endpoint in order to work with
a non-compliant OIDC Provider.
[1]: https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
- Cast send_invite value in cases where it might not have been a boolean,
which occurs on non-JSON requests.
- Added test to cover.
- Updated API docs to mention and shown boolean usage.
Cleaned up and updated page picker a bit, allowing longer names to show,
clicking through to item without triggering popup, and updated to use
hidden attributes instead of styles.
Added phpunit tests to cover supporting entity-selector-templates
endpoint.
Swapped back handling to instead be pre-determined instead of being
based upon session/referrer which would cause inconsistent results when
referrer data was not available (redirect to app-loaded images/files).
To support, this adds a mechansism to provide a URL through request
data.
Also cleaned up some imports in code while making changes.
Closes#4656.
This changes the point-of-logout to be within the initial part of the
SAML logout flow, as per 5.3.2 of the SAML spec, processing step 2.
This also improves the logout redirect handling to use the global
redirect suggestion so that auto-login handling is properly taken into
account.
Added tests to cover.
Manual testing performed against keycloak.
For #4713
- Disabled by default due to strict rejection by auth systems.
- Fixed issue when autoloading logout URL, but not provided in
autodiscovery response.
- Added proper handling for if the logout URL contains a query string
already.
- Added extra tests to cover.
- Forced config endpoint to be used, if set as a string, instead of
autodiscovery endpoint.
Managed to do this in an API-compatible way although resuling output may
differ due to new dom handling in general, although user content is used
inline to remain as comptable as possible.
- Added mulit-level depth parsing.
- Updating usage of HTML doc in page content to be efficient.
- Removed now redundant PageContentTest cases.
- Made some include system fixes based upon testing.
Expanded tests with many more cases, and added fixes for failed
scenarios.
Updated logic to specifically handling parent <p> tags, and now assume
compatibility with parent block types elswhere to allow use in a
variety of scenarios (td, details, blockquote etc...).
Implements block promoting to body (including position choosing based
upon likely tag position within parent) and block splitting where we're
only a single depth down from the body child.
- Merged book and chapter name items to a single page path list item
which has links to parent page/chapter.
- Added permission filtering to page path elements.
- Added page path to also be on comment notifications.
- Updated testing to cover.
- Added new Message Line objects to support.
Done during review of #4629
Previously we'd prevent caching of authed responses for security
(prevent back cache or proxy caching) but caching could still be an
issue in non-auth scenarios due to CSRF (eg. returning to login screen after
session expiry).
For #4600
- Updated existing tests now affected by my-account changes.
- Updated some existing tests to more accuractly check the scenario.
- Updated some code styling in SocialController.
- Fixed redirects for social account flows to fit my-account.
- Added test for social account attaching.
- Added test for api token redirect handling.
- Updated to go through HomeController with the builder as a helper
class.
- Extracted some reapeated items into variables in manifest.
- Updated background color to match those used by BookStack.
- Removed reference of icon.ico since its not intended to be used.
- Added tests to cover functionality.
Review of #4430
Uploads over the post max size Would previously error without a
clean user facing message. This catches that error to provide a
user friendly message, compatible with our common error handling.
Tested on image manager handling.
Added test to cover.
- Fixed missing page content for direct page children
- Fixed lack of book description.
- Fixed inconsistent spacing between items.
- Fixed lack of spacing between HTML items when HTML on same line.
For #4557
- Moved "common" template partials, that are only used in layouts, to
layouts/parts folder.
- Simplified HTML structure of header template.
- Extracted logo and links from header template to simplify.
- Added header-links-start template for easier extension/customization
without needing to override full list of links.
- Added test to cover usage of this.
For #4564
Added due to now not being able to perform an exact search where
contains a trailing backslash.
Now all backslashes in exact terms are consided escape chars
and require escaping themselves.
Potential breaking change due to search syntax handling change.
Related to #4535.
Also prevented use of empty exact matches.
Prevents issues when attempting to use exact search terms in inputs for
just search terms, and use of single " chars within search terms since
these would get auto-promoted to exacts.
For #4535
During review of #4560.
- Simplified command to share as much log as possible across different
run options.
- Extracted out user handling to share with MFA command.
- Added specific handling for disabled avatar fetching.
- Added mention of avatar endpoint, to make it clear where these avatars
are coming from (Protect against user expectation of LDAP avatar sync).
- Simplified a range of the testing.
- Tweaked wording and code formatting.
- Reduced app settings down to what's required.
- Used new view-shared $locale object instead of using globals via
config.
- Aligned language used to default on "locale" instead of mixing
locale/language.
For #4501
- Moves guest user caching from User class to app container for
simplicity.
- Updates test to use simpler $this->users->guest() method for
consistency.
- Streamlined helpers to avoid function overlap for simplicity.
- Extracted user profile dropdown while doing changes.
- Updating formatting.
- Tweaked truncation to roughly match elipsis char to width used.
- Updated testing to use existing helpers, and ran check as admin user
to avoid name conflicts.
This adds specific handling for functions.php error loading to re-throw
errors wrapped in a more descriptive message, to make it clear the error
is due to an issue in their functions.php file.
Decided to throw and stop, rather than ignore & continue, to be on the
safe side in the event auth-level (or other security level) customizations
have been made via functions.php.
Adds test to cover.
Closes#4504
- Adds filtering to the watched items list in notification preferences
so that deleted (recycle bin) items are removed via query.
- Adds relations and logic to properly remove watches upon user and
entity delete events, to old watches in database do not linger.
- Adds testing to cover the above.
Did not add migration for existing data, since patch will be close to
introduction, and lingering DB entries don't open a security concern,
just some potential confusion in specific potential scenarios.
Probably not work extra migration risk, although could add in future if
concerns/issues are found.
Related to #4499
- Passed decode flags to provide consistent behaviour across PHP
versions during testing.
- Added env option to prevent local option taking action in PHPunit
tests.
- Covered webhook SSR allow list useage via test.
- Updated allow list handling to use trailing slash, or hash, or end of
line as late anchor for better handling for hosts (prevent .co.uk
passing for .co domain host)
Prevention of action on certain routes for guest user when public access
is enabled. Could not see a way this could be a security issue, beyond a
mild nuisance that'd only be visible if public users can edit, which
would present larger potential nuisance anyway.
Review of #4313
- Made constructor changes while reviewing some classes.
- Updated API examples for consistency.
- Tweaked formatting for some array changes.
- Simplified added tests.
- Tweaked chapter/page repo priority handling to be simpler.
Performed manual API endpoint testing of page/chapter create/update.
Added test and changed logic to properly check the view permissions for
the notification receiver before sending.
Required change to permissions applicator to allow the user to be
manually determined, and a service provider update to provide the class
as a singleton without a specific user, so it checks the current logged
in user on demand.
- Ensured watch options passed in all meta template usage to fix failing
scenarios where watch options did not exist.
- Fixed testing issue caused by guest user permission caching.
- Added general user preferences view and updated link in profile menu
to suit.
- Made notification permission required for notification preferences
view, added test to cover.
Reverted work in 847a57a49a.
Left test in but updated to new expectation.
Left migration in but removed content to prevent new pre-v23.06
upgraders loosing shelf create permission status.
Added note to permission to describe use-case.
For #4375
Due to queue serialization.
Added a test to check a couple of delete events.
Added ApiTokenFactory to support.
Also made a couple of typing/doc updates while there.
Related to #4373
Was causing confusion.
Added test to cover.
Also added migration to remove existing create entries to pre-emptively
avoid issues in future if 'create' is used again.
After full review of current MAIL_ENCRYPTION usage in laravel and
smyfony mailer, this updates the options in BookStack to be simplified
and specific in usage:
- Removed mail.mailers.smtp.encryption option since it did not actually
affect anything in the current state of dependancies.
- Updated MAIL_ENCRYPTION so values of tls OR ssl will force-enable tls
via 'scheme' option with laravel passes to the SMTP transfport, which
Smyfony uses as an indicator to force TLS.
When MAIL_ENCRYPTION is not used, STARTTLS will still be attempted by
symfony mailer.
Updated .env files to refer to BookStack docs (which was updated for
this) and to reflect correct default port.
Related to #4342