## FusionAuth.io Full Documentation # FusionAuth CLI import InlineField from 'src/components/InlineField.astro'; The FusionAuth command line interface (CLI) tool allows you to manipulate FusionAuth from the command line. The focus of the CLI is on allowing easy management of commonly modified customization code and markup, such as emails, themes or lambdas. It is not a full featured replacement for any of the [client libraries](/docs/sdks/), which wrap all of the API. ## Prerequisites The CLI tool requires node. It's tested with version 19 but should work with modern versions of node. ## Installation You can install this tool using `npm`. ``` npm i -g @fusionauth/cli ``` ## Functionality This tool allows you to easily retrieve and publish FusionAuth configurations from the command line. This includes: * emails * lambdas * themes The CLI is designed to work with complex version controlled configuration and includes support for localized content. ## Usage Currently, the CLI supports the following commands: - Emails - `fusionauth email:download` - Download a specific template or all email templates from a FusionAuth server. - `fusionauth email:duplicate` - Duplicate an email template locally. - `fusionauth email:html-to-text` - Convert HTML email templates to text, where the text template is missing. - `fusionauth email:upload` - Upload a specific template or all email templates to a FusionAuth server. - `fusionauth email:watch` - Watch the email template directory and upload changes to a FusionAuth server. - `fusionauth email:create` - Create a new email template locally. - Lambdas - `fusionauth lambda:create` - Upload a lambda to a FusionAuth server. - `fusionauth lambda:delete` - Delete a lambda from a FusionAuth server. - `fusionauth lambda:retrieve` - Download a lambda from a FusionAuth server. - Themes - `fusionauth theme:download` - Download a theme from a FusionAuth server. - `fusionauth theme:upload` - Upload a theme to a FusionAuth server. - `fusionauth theme:watch` - Watch a theme directory and upload changes to a FusionAuth server. ## Examples ``` fusionauth theme:download -k # modify your theme fusionauth theme:upload -k ``` To learn more about the commands, use the `--help` switch. ``` fusionauth --help ``` ## Updating To update to the most recent version, use `npm update`. ``` npm update -g @fusionauth/cli ``` ## Source Code The FusionAuth CLI is open source and we welcome pull requests. You can [view the source code](https://github.com/FusionAuth/fusionauth-node-cli) and [the npm package](https://www.npmjs.com/package/@fusionauth/cli). # Migrate from Inversoft Passport to FusionAuth import Aside from 'src/components/Aside.astro'; import Breadcrumb from 'src/components/Breadcrumb.astro'; ## Overview If you are currently an Inversoft Passport customer and looking to move to FusionAuth you have come to the right place. Here you'll find important information on API changes, database upgrade procedures, etc. We have attempted to build an exhaustive list of changes you will need to be aware of, but please do plan to test your migration and ask for assistance from the FusionAuth team during your migration. The following sections are provided for you to review prior to upgrading to FusionAuth. ## Naming Changes In addition to the obvious change of Passport to FusionAuth, as you read through the documentation and update your integration be aware of the following name changes. _Name changes_ | Old name | New Name | Description | |------------------------|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Passport | FusionAuth | Passport is now known as FusionAuth | | passport.properties | fusionauth.properties | The Passport configuration file is now named `fusionauth.properties`. | | Passport Backend | FusionAuth App | The Passport Backend which refers to the webservice that services APIs and provides the UI is now referred as FusionAuth or FusionAuth App. | | passport-backend | fusionauth-app | The passport-backend which was the name of the package or bundle which contained the Passport Backend service will now be called fusionauth-app. | | Passport Search | FusionAuth Search | The Passport Search which refers to the webservice that provides search capability to FusionAuth is now referred to FusionAuth Search. | | passport-search-engine | fusionauth-search | The `passport-search-engine` which was the name of the package or bundle which contained the Passport Search Engine service will now be called `fusionauth-search`. | | X-Passport-TenantId | X-FusionAuth-TenantId | The `X-Passport-TenantId` which was used if you had configured more than one tenant to scope an API request to a particular tenant should be changed to `X-FusionAuth-TenantId`. | ## License Changes Because FusionAuth is no longer licensed in a traditional way, no license is required and no license checks are performed during a User create or Registration process. In Passport it was possible to receive a `402` status code indicating the license was expired or had exceeded the allocated usage, this response code will no longer be returned. ## Breaking Changes Review the following breaking changes when moving from Passport to FusionAuth. A breaking change means that compatibility has been broken and if your integration will break if you do not review the following changes and update your integration accordingly. ### API Changes * When the Search Engine service is down or un-reachable a new status code of `503` will be returned. Previously this error condition would have returned a `500` status code. * If you were passing the Tenant Id in an HTTP header, this header `X-Passport-TenantId` should now be provided as `X-FusionAuth-TenantId`. * Application API * Free form data is now available on the Application object, see `application.data` * Audit Log API * `auditLog.data.attributes` moved to `auditLog.data` * `auditLog.data.newValue` moved to `auditLog.newValue` * `auditLog.data.oldValue` moved to `auditLog.oldValue` * `auditLog.data.reason` moved to `auditLog.reason` * Group API * `group.data.attributes` moved to `group.data` * Group Member API * `groupMember.data.attributes` moved to `groupMember.data` * SystemConfiguration API * `systemConfiguration.failedAuthenticationUserActionId` moved to `systemConfiguration.failedAuthenticationConfiguration.userActionId` * `systemConfiguration.forgotEmailTemplateId` moved to `systemConfiguration.emailConfiguration.forgotPasswordEmailTemplateId` * `systemConfiguration.setPasswordEmailTemplateId` moved to `systemConfiguration.emailConfiguration.setPasswordEmailTemplateId` * `systemConfiguration.verificationEmailTemplateId` moved to `systemConfiguration.emailConfiguration.verificationEmailTemplateId` * `systemConfiguration.verifyEmail` moved to `systemConfiguration.emailConfiguration.verifyEmail` * `systemConfiguration.verifyEmailWhenChanged` moved to `systemConfiguration.emailConfiguration.verifyEmailWhenChanged` * Tenant API * `tenant.data.attributes` moved to `tenant.data` * `tenant.forgotEmailTemplateId` moved to `tenant.data` * `tenant.setPasswordEmailTemplateId` moved to `tenant.emailConfiguration.forgotPasswordEmailTemplateId` * `tenant.verificationEmailTemplateId` moved to `tenant.emailConfiguration.verificationEmailTemplateId` * `tenant.verifyEmail` moved to `tenant.emailConfiguration.verifyEmail` * `tenant.verifyEmailWhenChanged` moved to `tenant.emailConfiguration.verifyEmailWhenChanged` * User API * `user.data.attributes` moved to `user.data` * `user.data.preferredLanguages` moved to `user.preferredLanguages` * Removed `childIds` and `parentId` * User Registration API * `userRegistration.data.attributes` moved to `userRegistration.data` * `userRegistration.data.timezone` moved to `userRegistration.timezone` * `userRegistration.data.preferredLanguages` moved to `userRegistration.preferredLanguages` ### Email Templates The Forgot Email and Setup Password templates no longer support the `verificationId` replacement parameter. The `verificationId` replacement parameter was provided for backwards compatibility with older versions of Passport and has been removed in FusionAuth. Review your Forgot Password and Setup Password email templates and if you are using the replacement value `${verificationId}` in either the HTML or Text version of the template, replace it with `${changePasswordId}`. See [Email Templates](/docs/customize/email-and-messages/email-templates) for additional information. ### Client Libraries If you were using a Passport Client library please upgrade to the FusionAuth version. See [Client Libraries](/docs/sdks/) ### Removed Features * Parent and Child relationships between users was removed in FusionAuth. This feature is planned to be re-introduced with better support for a family structure and a more flexible relationship model. If you currently utilize this feature please contact the FusionAuth team for assistance. ## Database Migration Due to the data model changes that were made in FusionAuth your database schema will need to be updated. Please be aware that you Passport database MUST be upgraded to the latest version prior to migrating to FusionAuth. The latest Passport version is `1.22.4`, the easiest way to upgrade your schema is to install the latest version of Passport and start up the service and allow Maintenance Mode to upgrade your database for you. Once this is complete you may then run the migration script. ### MySQL The following is the MySQL database migration. Please ensure you fully test this migration or contact the FusionAuth team for assistance. ```sql -- Passport to FusionAuth -- Update the version. UPDATE version SET version = '1.0.0'; CREATE TABLE instance ( id BINARY(16) NOT NULL, support_id BINARY(16) NULL ) ENGINE = innodb CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; -- Insert instance INSERT INTO instance(id) VALUES (random_bytes(16)); -- Rename the forgot password ALTER TABLE system_configuration CHANGE COLUMN forgot_email_templates_id forgot_password_email_templates_id BINARY(16) NULL; ALTER TABLE tenants CHANGE COLUMN forgot_email_templates_id forgot_password_email_templates_id BINARY(16) NULL; -- Delete the system_configuration columns (verify_email and verify_email_when_changed didn't make it through and need to be manually updated) UPDATE system_configuration SET data = JSON_INSERT(data, '$.data', CAST('{}' AS JSON)); UPDATE system_configuration SET data = JSON_INSERT(data, '$.emailConfiguration', CAST(email_configuration AS JSON)); UPDATE system_configuration SET data = JSON_INSERT(data, '$.emailConfiguration.verifyEmail', IF(verify_email = 1, TRUE, FALSE) IS TRUE); UPDATE system_configuration SET data = JSON_INSERT(data, '$.emailConfiguration.verifyEmailWhenChanged', IF(verify_email_when_changed = 1, TRUE, FALSE) IS TRUE); UPDATE system_configuration SET data = JSON_INSERT(data, '$.passwordValidationRules', CAST(password_validation_rules AS JSON)); ALTER TABLE system_configuration DROP COLUMN email_configuration, DROP COLUMN password_expiration_days, DROP COLUMN password_validation_rules, DROP COLUMN verify_email, DROP COLUMN verify_email_when_changed; -- Add timezone to registration ALTER TABLE user_registrations ADD COLUMN timezone VARCHAR(255) NULL; -- Delete parent/child relationships ALTER TABLE users DROP COLUMN parent_id, DROP COLUMN parental_consent_type; -- Clean up application (two cases because some old Applications might have a data column with the value '{}' only) UPDATE applications SET data = JSON_INSERT(data, '$.data', CAST('{}' AS JSON)); UPDATE applications SET data = JSON_INSERT(data, '$.cleanSpeakConfiguration', CAST(clean_speak_configuration AS JSON)); UPDATE applications SET data = JSON_INSERT(data, '$.oauthConfiguration', CAST(oauth_configuration AS JSON)); ALTER TABLE applications DROP COLUMN clean_speak_configuration, DROP COLUMN oauth_configuration; -- Fix the data column for audit_logs UPDATE audit_logs SET data = JSON_REMOVE(JSON_INSERT(data, '$.data', CAST(COALESCE(JSON_EXTRACT(data, '$.attributes'), '{}') AS JSON)), '$.attributes'); -- Fix the data column for groups UPDATE groups SET data = JSON_REMOVE(JSON_INSERT(data, '$.data', CAST(COALESCE(JSON_EXTRACT(data, '$.attributes'), '{}') AS JSON)), '$.attributes'); -- Fix the data column for group_members UPDATE group_members SET data = JSON_REMOVE(JSON_INSERT(data, '$.data', CAST(COALESCE(JSON_EXTRACT(data, '$.attributes'), '{}') AS JSON)), '$.attributes'); -- Fix the data column for users UPDATE users SET data = JSON_REMOVE(JSON_INSERT(data, '$.data', CAST(COALESCE(JSON_EXTRACT(data, '$.attributes'), '{}') AS JSON)), '$.attributes'); -- Fix the data column for user_registrations UPDATE user_registrations SET data = JSON_REMOVE(JSON_INSERT(data, '$.data', CAST(COALESCE(JSON_EXTRACT(data, '$.attributes'), '{}') AS JSON)), '$.attributes'); -- Fix the data column for tenants UPDATE tenants SET data = JSON_REMOVE(JSON_INSERT(data, '$.data', CAST(COALESCE(JSON_EXTRACT(data, '$.attributes'), '{}') AS JSON)), '$.attributes'); UPDATE tenants SET data = JSON_INSERT(data, '$.emailConfiguration.verifyEmail', COALESCE(JSON_EXTRACT(data, '$.verifyEmail'), FALSE)); UPDATE tenants SET data = JSON_INSERT(data, '$.emailConfiguration.verifyEmailWhenChanged', COALESCE(JSON_EXTRACT(data, '$.verifyEmailWhenChanged'), FALSE)); -- Fix the internal API key DELETE FROM authentication_keys WHERE id LIKE '__internal_%' AND meta_data LIKE '%"cacheReloader"%'; INSERT INTO authentication_keys(id, permissions, meta_data, tenants_id) VALUES (concat('__internal_', replace(to_base64(random_bytes(64)), '\n', '')), '{"endpoints": {"/api/cache/reload": ["POST"]}}', '{"attributes": {"internalCacheReloader": "true"}}', NULL); ``` ### PostgreSQL The following is the PostgreSQL database migration. Please ensure you fully test this migration or contact the FusionAuth team for assistance. ```sql \set ON_ERROR_STOP true -- Passport to FusionAuth -- Update the version. UPDATE version SET version = '1.0.0'; CREATE TABLE instance ( id UUID NOT NULL, support_id UUID NULL ); -- Insert instance INSERT INTO instance(id) VALUES (md5(random() :: TEXT || clock_timestamp() :: TEXT) :: UUID); -- Rename the forgot password ALTER TABLE system_configuration RENAME COLUMN forgot_email_templates_id TO forgot_password_email_templates_id; ALTER TABLE tenants RENAME COLUMN forgot_email_templates_id TO forgot_password_email_templates_id; -- Delete the system_configuration columns -- Delete the system_configuration columns (verify_email and verify_email_when_changed didn't make it through and need to be manually updated) UPDATE system_configuration SET data = JSONB_SET(data::JSONB, '{data}', '{}', TRUE); UPDATE system_configuration SET data = JSONB_SET(data::JSONB, '{emailConfiguration}', email_configuration::JSONB, TRUE); UPDATE system_configuration SET data = JSONB_SET(data::JSONB, '{emailConfiguration,verifyEmail}', TO_JSONB(verify_email), TRUE); UPDATE system_configuration SET data = JSONB_SET(data::JSONB, '{emailConfiguration,verifyEmailWhenChanged}', TO_JSONB(verify_email_when_changed), TRUE); UPDATE system_configuration SET data = JSONB_SET(data::JSONB, '{passwordValidationRules}', password_validation_rules::JSONB, TRUE); ALTER TABLE system_configuration DROP COLUMN email_configuration, DROP COLUMN password_expiration_days, DROP COLUMN password_validation_rules, DROP COLUMN verify_email, DROP COLUMN verify_email_when_changed; -- Add timezone to registration ALTER TABLE user_registrations ADD COLUMN timezone VARCHAR(255) NULL; -- Delete parent/child relationships ALTER TABLE users DROP COLUMN parent_id, DROP COLUMN parental_consent_type; -- Clean up application (two cases because some old Applications might have a data column with the value '{}' only) UPDATE applications SET data = JSONB_SET(data::JSONB, '{data}', '{}', TRUE); UPDATE applications SET data = JSONB_SET(data::JSONB, '{cleanSpeakConfiguration}', COALESCE(clean_speak_configuration, '{}')::JSONB, TRUE); UPDATE applications SET data = JSONB_SET(data::JSONB, '{oauthConfiguration}', COALESCE(oauth_configuration, '{}')::JSONB, TRUE); ALTER TABLE applications DROP COLUMN clean_speak_configuration, DROP COLUMN oauth_configuration; -- Fix the data column for audit_logs UPDATE audit_logs SET data = JSONB_SET(data::JSONB, '{data}', COALESCE(data::JSONB -> 'attributes', '{}')::JSONB, TRUE) - 'attributes'; -- Fix the data column for groups UPDATE groups SET data = JSONB_SET(data::JSONB, '{data}', COALESCE(data::JSONB -> 'attributes', '{}')::JSONB, TRUE) - 'attributes'; -- Fix the data column for group_members UPDATE group_members SET data = JSONB_SET(data::JSONB, '{data}', COALESCE(data::JSONB -> 'attributes', '{}')::JSONB, TRUE) - 'attributes'; -- Fix the data column for users UPDATE users SET data = JSONB_SET(data::JSONB, '{data}', COALESCE(data::JSONB -> 'attributes', '{}')::JSONB, TRUE) - 'attributes'; -- Fix the data column for user_registrations UPDATE user_registrations SET data = JSONB_SET(data::JSONB, '{data}', COALESCE(data::JSONB -> 'attributes', '{}')::JSONB, TRUE) - 'attributes'; -- Fix the data column for tenants UPDATE tenants SET data = JSONB_SET(data::JSONB, '{data}', COALESCE(data::JSONB -> 'data' -> 'attributes', '{}')::JSONB, TRUE) #- '{data,attributes}'; UPDATE tenants SET data = JSONB_SET(data::JSONB, '{emailConfiguration,verifyEmail}', COALESCE(data::JSONB -> 'verifyEmail', TO_JSONB(FALSE)), TRUE); UPDATE tenants SET data = JSONB_SET(data::JSONB, '{emailConfiguration,verifyEmailWhenChanged}', COALESCE(data::JSONB -> 'verifyEmailWhenChanged', TO_JSONB(FALSE)), TRUE); -- Fix the internal API key DELETE FROM authentication_keys WHERE id LIKE '__internal_%' AND meta_data LIKE '%"cacheReloader"%'; INSERT INTO authentication_keys(id, permissions, meta_data, tenants_id) VALUES ('__internal_' || replace( encode(md5(random()::TEXT || clock_timestamp()::TEXT)::BYTEA || md5(random()::TEXT || clock_timestamp()::TEXT)::BYTEA, 'base64'), E'\n', ''), '{"endpoints": {"/api/cache/reload": ["POST"]}}', '{"attributes": {"internalCacheReloader": "true"}}', NULL); ``` ## Migration Summary The following is a summary of the steps required to migration to FusionAuth and is provided as a guidelines to assist you in performing the migration steps in the correct order. 1. Review all documented changes in this guide 2. Make a backup of your database 3. Upgrade Passport to the latest version. 4. Install the latest version of FusionAuth 5. Review and migrate settings from `passport.properties` to `fusionauth.properties`. You may have other settings that require migration in addition to the following. - `database.url` - `database.username` - `database.password` - `passport-search-engine.memory` is now `fusionauth-search.memory` - `passport-backend.memory` is now `fusionauth-app.memory` 6. Run the SQL migration found above 7. Start FusionAuth and bring up the UI and complete maintenance mode, you will be prompted to do the following steps: - Upgrade the db schema - Create search index 8. Once logged into FusionAuth rebuild the Elasticsearch index - Navigate to System -> Reindex. 9. Review your configuration in FusionAuth for accuracy. # Getting Started import LoginBefore from 'src/diagrams/quickstarts/login-before.astro'; import LoginAfter from 'src/diagrams/quickstarts/login-after.astro'; import Aside from 'src/components/Aside.astro'; ## Introduction FusionAuth is a modern platform for Customer Identity and Access Management (CIAM). FusionAuth provides APIs and a responsive web user interface to support login, registration, localized email, multi-factor authentication, reporting and much more. If you're looking for employee login or a replacement for Active Directory - you may be in the wrong place. While FusionAuth can be used for nearly any application, we do not offer native desktop integration and replacing Active Directory is not on our roadmap. However, if you're looking for a solution to manage end users that can perform at scale, then keep reading. Here's a typical application login flow before FusionAuth. And here's the same application login flow when FusionAuth is introduced. ## Core Concepts Legacy identity technologies have complex hierarchy and cryptic terminology like realms, principals, subjects and distinguished names. In order to simplify something perceived to be complex, the best approach is to go back to the basics, to the atomic elements and throw everything else away. When we built FusionAuth we took the back to basics approach. We identified two atomic elements of identify, Users and Applications. Everyone has Users, and Users need to be authenticated to Applications. For this reason FusionAuth is built upon four core elements: * Users - someone that can log into things * Applications - things that Users log into * Registrations - the connection between a User and an Application they have access to * Tenants - A way to logically isolate Applications, Users and Registrations ### Users A user is uniquely identified in any particular tenant by an email address or username. [Learn more.](/docs/get-started/core-concepts/users) ### Applications A FusionAuth Application represents an authenticated resource such as a web application, mobile application or any other application that requires authenticated users. A FusionAuth Application is defined by a name and a set of Roles. [Learn more.](/docs/get-started/core-concepts/applications) ### Registrations A User can be registered to one or more FusionAuth Applications. A User Registration can define one to many Application Roles. [Learn more.](/docs/get-started/core-concepts/registrations) ### Tenants Tenants are way to separate Users, Applications and Registrations into separate containers. Inside a Tenant, you can define any number of Users, Applications and Registrations. Across Tenants, you can define duplicate Applications, Users and Registrations. For example, you might have two Tenants and inside both Tenants you might have an Application named `Web Based Payroll` and a User with the email address `john@piedpiper.com`. Each of these Users might have a Registration to the `Web Based Payroll` Application. And finally, each of these Users might have different passwords and data. [Learn more.](/docs/get-started/core-concepts/tenants) ## Getting Started First you will need to install and configure FusionAuth before starting your integration. Here are some links to get you started: ### Quick Start * [5-Minute Setup Guide](/docs/quickstarts/5-minute-setup-guide) * [Register a User and Login](/docs/lifecycle/register-users/register-user-login-api) * [Self-service Registration](/docs/lifecycle/register-users/basic-registration-forms) * [Common Configuration](/docs/get-started/run-in-the-cloud/common-configuration) ### Install Options * [FastPath Install](/docs/get-started/download-and-install/fast-path) * [Docker](/docs/get-started/download-and-install/docker) * [Package Installation](/docs/get-started/download-and-install/fusionauth-app) * [All Options](/docs/get-started/download-and-install) ### Create a User and call an API * [Register a User and Login](/docs/lifecycle/register-users/register-user-login-api) * [API Docs](/docs/apis/) # Lifecycle Overview There's a lifecycle for CIAM users: * Users must get into your identity store somehow. You can [migrate them to the new system](/docs/lifecycle/migrate-users) if they exist elsewhere, you can create them via APIs or federation, or they must [self-register](/docs/lifecycle/register-users). * After users are in the CIAM system, they need to [authenticate, log in or sign in](/docs/lifecycle/authenticate-users) (these all mean the same thing). This includes all manner of authentication methods: * passwordless options such as passkeys and magic links * Identity Providers such as Google or Facebook * SAML and OIDC federation * and more * User profile data also needs to be [managed over time](/docs/lifecycle/manage-users). Functionality for this part of the lifecycle includes forms used by customer service reps, self-service account/profile management, searching to extract user data in bulk, and verifying users. * Finally, users are sometimes deprovisioned. In FusionAuth this is done by locking user accounts by [deactivating or deleting users](/docs/apis/users#delete-a-user). The documentation in this section explain FusionAuth's functionality and how it can help with each of these parts of the lifecycle. # Authentication Types import AuthenticationTypes from 'src/content/docs/_shared/authentication-type-values.astro'; FusionAuth supports authentication in many different ways. These are the methods that are available. These authentication type values are available in [webhook payloads](/docs/extend/events-and-webhooks/events/user-login-success), [OAuth tokens](/docs/lifecycle/authenticate-users/oauth/tokens) and for use with a [login validation lambda](/docs/extend/code/lambdas/login-validation). # Configuration Reference import APIBlock from 'src/components/api/APIBlock.astro'; import APIField from 'src/components/api/APIField.astro'; import Aside from 'src/components/Aside.astro'; import InlineField from 'src/components/InlineField.astro'; import PropertyAdditionalJvmArgs from 'src/content/docs/reference/_property-additional-jvm-args.mdx'; import PropertyMemory from 'src/content/docs/reference/_property-memory.mdx'; import ConfigurationLimits from 'src/content/docs/get-started/core-concepts/_configuration-limits.mdx'; import ConfigurationOptions from 'src/components/docs/reference/ConfigurationOptions.astro'; ## Overview FusionAuth configuration is managed in a number of ways, depending on the item being configured. The majority of application level settings are managed in the UI or the APIs. Other items such as memory, ports, and other system configuration options are managed through a lookup process. This process uses environment variables, Java system properties, and the key value pairs in the `fusionauth.properties` file. ## Lookup Process The lookup process was introduced in version [`1.19.0`](/docs/release-notes/archive#version-1-19-0) and allows any configuration option to be specified in one of three ways: environment variables, Java system properties, or in the `fusionauth.properties` configuration file. Here is the process for looking up configuration options (NOTE: that the name of the configuration options are listed below): 1. Check if an environment variable is defined with the configuration option name 2. Check if an environment variable is defined with the configuration option name translated by upper-casing it and replacing periods and dashes with underscores 3. Check if there is a Java system property with the configuration option name 4. Check if the configuration option is defined in the `fusionauth.properties` configuration file To better illustrate how the lookup works, let's take one of the common configuration options for FusionAuth and walk through each step. We'll use `database.url` which defines the JDBC URL where the database is located. Here's how the lookup will work: 1. Check for an environment variable named `database.url` 2. Check for an environment variable named `DATABASE_URL` 3. Check for a Java System property defined like this: `-Ddatabase.url=foo` 4. Check if there is a line in `fusionauth.properties` like this: `database.url=foo` This lookup order is consistent for every configuration option listed below. ## Configuration File Assuming you installed in the default locations, the configuration file may be found in the following directory. If you have installed in an alternate location the path to this file will be different. ```plaintext title="Linux and macOS" /usr/local/fusionauth/config/fusionauth.properties ``` ```plaintext title="Windows" \fusionauth\config\fusionauth.properties ``` ## Options ## Limits # FusionAuth Release Notes - What's New in FusionAuth import Breadcrumb from 'src/components/Breadcrumb.astro'; import DatabaseMigrationWarning from 'src/components/docs/release-notes/DatabaseMigrationWarning.mdx'; import DeprecationWarning from 'src/components/docs/release-notes/DeprecationWarning.astro'; import GeneralMigrationWarning from 'src/components/docs/release-notes/GeneralMigrationWarning.astro'; import InlineField from 'src/components/InlineField.astro'; import InlineUIElement from 'src/components/InlineUIElement.astro'; import Issue from 'src/components/docs/release-notes/ReleaseNotesIssue.astro'; import RelatedToIssue from 'src/components/docs/release-notes/ReleaseNotesRelatedToIssue.astro'; import IssueResolvedVia from 'src/components/docs/release-notes/ReleaseNoteIssueResolvedVia.astro'; import ReleaseNotesSelector from 'src/components/docs/release-notes/ReleaseNotesSelector.astro'; import ReleaseNoteHeading from 'src/components/docs/release-notes/ReleaseNoteHeading.astro'; import ThemeUpdateWarning from 'src/components/docs/release-notes/ThemeUpdateWarning.astro'; import { YouTube } from '@astro-community/astro-embed-youtube'; {/* Hey, developer! Read this please! Also see some additional detail in the _README.md if it is still relevant. If you are adding a new release note, please read. 1. If you have a db migration, add the to the release note. 2. If you have a db migration, add the version to operate/deploy/upgrade.mdx in the `Out-of-Band Database Upgrades` section. 3. Add the following sections, removing any that are empty, but keeping this order: - Known Issues - Security - Changed - New - Fixed - Enhancements - Internal For fixed bugs, provide the following information to the reader 1. What it is and Why they care 2. What specific situation and configuration causes the issue that we've fixed 3. What symptom(s) they will observe if they have or may hit this condition */} Looking for release notes older than 1.44.0? Look in the [release notes archive](/docs/release-notes/archive). Looking to be [notified of new releases?](/docs/operate/roadmap/releases#release-notifications) This release provides a handful of improvements to the webhook event log. In versions `1.53.0` through `1.56.0`, very large webhook event log volumes could impact performance during log cleaning operations. If you are currently using a version of FusionAuth earlier than `1.53.0` and use webhooks, we recommend upgrading to version `1.57.0`. ### Changed * The process for deleting webhook event logs according to retention rules was formerly turned off by default, causing all webhook event log entries to be retained forever. This will now be enabled by default in new FusionAuth installations. Existing installations that are being upgraded will retain their former setting. ### Fixed * The client libraries were missing `PATCH` support for Entities. Support for this operation has been added. * Client libraries are missing full support for `PUT` and `PATCH` operations for entity types, forms, form fields, IP ACLs, webhooks, and families. This fix adds support for these. ### Enhancements * When prompted for how you heard about FusionAuth in the setup wizard, you may now supply "ChatGPT/LLMs/AI" as a standard response. * Two enhancements were added to the configuration for controlling webhook event logging behavior: * Webhook event logging can now be turned off, which is the default for new FusionAuth installations. Previously, you were only able to reduce the retention period to a very small window, however in this case the logging and log management would still occur. * Deleting webhook event logs according to a configured retention period is now enabled by default. Previously, it was disabled by default. * Webhook event log searching was improved by setting a default 1-hour search window when no duration parameters are provided. Webhook event logging can create a large number of log records, and the performance of unbounded searches scaled roughly linearly with the number of log records, leading to less performant searches as the data size increased. * The process that applies webhook event log retention rules is getting some performance improvements. This is a background process that generally does not impact performance but could consume a disproportionate amount of system resources when under heavy load. ### Security * Improved security around certain cross-origin requests ### Fixed * FusionAuth returns a 500 when supplying a malformed application Id in an IdP-initiated SAML login, making it hard to troubleshoot. The error should be handled more gracefully, and a more meaningful error message should be returned. * The Application / Multi-Factor / SMS Template tooltip is incorrectly referencing an email template instead of an SMS template. Update this to reference the correct template type. * The passwordless API returns a 500 error when a non-existent application Id is provided. This should return a correct response code and meaningful error. * When posting an invalid grant type to the `/oauth2/token` endpoint, the list of supported grant types in the error message is missing the `device` grant type * Users are being prompted to re-submit a form when first logging into a new deployment using Firefox. The request should proceed on the first attempt. * When creating an entity grant for a user using the API, some invalid payloads will yield a 500 error. A more meaningful error should be returned. * FusionAuth shows a notification for getting a free license even after a license has been installed. This notification should disappear after a FusionAuth instance has been licensed. * Executing a manual system reset in development mode with a valid kickstart file fails. This should work as expected. * Supplying a malformed license key to Reactor is producing a generic error. A specific error would be more helpful. * The Daily Active Users report is missing data from the most recent day. The report should include this data. * After setting an application-level email verification template, the tenant-level template is still being used. The application-level setting should be honored. * The standard first name field intended for use in user edit forms has an incorrect name in MySQL installations, which is preventing it from showing up in the user edit form * The webhook event log can return fewer records per page than requested with the _Results per page_ dropdown, even when more results are available. Ensure that the number of results equals the requested number. * A nondescript error is returned when trying to save system settings via the FusionAuth admin application. It is still possible to update system settings using the API. * The simple theme editor's right-hand panel isn't constraining its content properly, allowing content to spill over the bottom border ### Enhancements * FusionAuth now allows you to create non-retrievable API keys. If you select this option when creating a key, the key will only be visible during creation and not thereafter. Make a copy and keep it secure! * Improved the execution performance of lambdas * Allow the post-login bootstrapping of a FusionAuth SSO session using an access token. This can be useful if you've authenticated a user outside of an OAuth workflow, or if you've lost access to the SSO session cookie. ### Internal * Update dependencies. * Upgrade `ch.qos.logback:logback-core` `1.5.6` -> `1.5.16` * Upgrade `org.primeframework:prime-mvc` `4.27.0` -> `4.29.2` * Upgrade `org.graalvm.polyglot:polyglot` `22.3.3` -> `24.1.2` * Upgrade `org.graalvm.js:js` `22.3.3` -> `24.1.2` * Upgrade `com.inversoft:inversoft-cache` `0.6.0` -> `0.6.1` * Upgrade `com.inversoft:inversoft-api-authentication` `0.29.0` -> `0.30.0` * Removed duplicated storage of internal messages relating to SCIM group operations * Added instrumentation to help with the auto-generation of documentation ### Known Issues * You can't save the System Settings in the admin UI. ### Security * Correct validation for configured authorized redirect URLs when using wild card support has been enabled. * Add additional validation of an authorizing JWT when using the Issue JWT API (`/api/jwt/issue`). ### Changed * The length of the refresh token has increased from `54` to `64` characters. If for some reason you are expecting a specific length, you may need to account for this change. ### New * Allow for the sending of usage stats. Enabling usage stats allow FusionAuth to better understand how our users use our product. Usage data does not contain configuration, user data or any information that can be used to identity a company or individual. This information will help us know where we need to invest in new features and enhancements. If you are using FusionAuth Cloud, this feature will be enabled by default and cannot be disabled. ### Fixed * The confirmation page shown when users are completing verification and other workflows shows a FreeMarker error when some cookies are unavailable. This could happen when cookies are deleted by a user, removed by a proxy, or when running in an iframe. * When an OAuth workflow ends in redirecting with an error to a `redirect_uri` that contains query parameters, the resulting URL is being built incorrectly. * The SCIM ResourceTypes endpoint is returning resource type URLs with incorrect paths. The endpoint is returning a path prefix of `/api/scim/v2/` when it should be `/api/scim/resource/v2/`. * The OAuth scopes consent form has text that cannot be localized. Hosted pages should be fully localizable for users. * When viewing user data in the `Manage user` view, a boolean value is always shown as `-`, regardless of its actual value. * The JWT populate lambda is not executed when a user is logged in using the login API, but only when that user does not have a registration for the application named in the API call. This could lead to inconsistent behavior between a login using the hosted OAuth pages and a login using the login API. * The PHP client library is not handling libcurl errors gracefully, making it difficult to troubleshoot integration problems when using this library. See the [client library issue](https://github.com/FusionAuth/fusionauth-php-client/issues/28) for more details. * When downloading login records from System -> Login Records, the exported file format contains a place for zip code, however the zip code values are not being populated in the export. * The `POST /api/user/registration` call is documented as returning a `refreshTokenId`, but this value is not being returned on the response. * When editing a user's password in the FusionAuth admin UI after a new hashing scheme is set on the tenant, the password is not re-hashed using the new scheme. The re-hashing occurs as expected on a login or when the user changes their own password. ### Enhancements * The `rate limit` error message was added to the default theme messages to make it more obvious that it is customizable. The `[RateLimitedException]` message key was previously supported, but not easily discoverable. * Add an additional refresh token revocation policy to revoke a one-time use token on reuse. This policy helps protect against token theft by revoking the token if it were to be stolen and reused. * FusionAuth can now accept encrypted SAML assertions when acting as a SAML service provider. Support for encrypted assertions when FusionAuth is the SAML identity provider was added in version `1.47.0 `. * API keys can now be optionally set to expire at a given date/time. An expired key will not be deleted but will cause a `401` response to be returned when used. The expiration value can be edited to allow the expiration to be extended. * Additional parameters are now accepted on the hosted backend `/app/login` and `/app/registration` endpoints. This means you can pass things like `login_hint`, `idp_hint`, and analytics parameters that will be available on the respective OAuth hosted pages. * The First-time Setup wizard was improved with more descriptive and consistent text around using a Community plan license. * In the new Webhook Event Log there were numerous small UX and copy improvements. * Improved handling of a SAML `RelayState` in an IdP-initiated login. Previously, FusionAuth would only look for a valid ACS URL in the `RelayState`. Now, if the ACS URL can be resolved via other means, the `RelayState` value will be preserved and passed as a parameter in the final call to the ACS URL. * Added support for providing connect and read timeout values when making a `fetch` call from a lambda. * You can now configure a grace period for single-use refresh tokens, during which time the previous token will remain active. This is required for various use cases, including when clustered OAuth clients employ eventual consistency when synchronizing a refresh token, and some nodes of a client can find themselves with an out-of-date refresh token. ### Internal * Added tests to verify correct handing of wildcards in URLs in various places in the application. This change does not contain any functional changes. * Remove unused comments in a few theme templates. * Update dependencies. * Upgrade `org.primeframework:prime-mvc` `4.22.13` -> `4.27.0` * Better exception handling in extreme edge cases related to licensing of Breached Password Detection. ### Security * A vulnerability was discovered in the FusionAuth hosted pages. Under specific application configurations, and with insufficient authorization validation being performed on an access token, a malicious user could bypass required steps in post-authentication workflows, allowing unauthorized access to protected resources. This vulnerability was introduced in version `1.41.0`. It is recommended that you upgrade to version `1.54.0` at your earliest convenience. ### Fixed * The SCIM Groups API does not properly perform atomic updates to groups and members. This can lead to consistency issues when multiple SCIM update requests are simultaneously processed requiring membership changes. A fix for FusionAuth SSO session management with external identity providers requires a change to Google IdP usage. ### Fixed * In order to better protect 3rd party logins via SAML v2, OpenID Connect, and other 3rd party identity providers, a CSRF (cross site request forgery) token was added in version `1.47.0`. This token was not being used when all identity providers configured for the requested `client_id` were also configured to use managed domains, and the authorize request also contained the `idp_hint` request parameter. In this specific configuration, because the token was not being utilized, the login workflow would fail with the error `The request origin could not be verified. Unable to complete this login request.` * When using the hosted login pages, the end user is generally shown a checkbox named `Keep me signed in`, which indicates whether the user wishes to create an SSO session after logging in. When using an external identity provider along with an `idp_hint` or `login_hint` parameter, a user may be taken directly to the identity provider, bypassing the page with this checkbox. In this case, the user will not have the option of making a choice to establish or not establish an SSO session. This behavior has been improved in order to provide additional control on how the SSO session should be created. FusionAuth will now use the following order of operations in this non-interactive workflow to decide if the SSO session should be created. 1. The user's previous selection, if available. This past choice will have been stored in an HTTP only cookie. 2. The optionally supplied `rememberDevice` query parameter. In the event that the user has never seen the login page, the value of the `rememberDevice` query parameter will be the deciding factor. A value of `true` indicates that an SSO session should be created and a value of `false` indicates that an SSO session should not be created. If this parameter is omitted, the default behavior will be to create the SSO session. For more information on using the `idp_hint` and `login_hint` parameters, see the [Identity Providers Overview](/docs/lifecycle/authenticate-users/identity-providers/) documentation. * When using the login validation lambda with a 3rd party identity provider such as OpenID Connect, when the validation lambda causes the login to fail, the end user will not see the specific error returned by the lambda. Instead the user will see the following generic error (unless this message has been modified in a theme): > A validation error occurred during the login attempt. An event log was created for the administrator to review. The reason for this generic message is that in most cases if FusionAuth cannot complete a login request to a 3rd party we do not want to show the end user the technical reason. When a login validation lambda is the cause of the login failure, we do intend to the show the end user a more specific message. This issue has been corrected and if the login validation lambda was the cause of the failure, the event log is created when the identity provider has enabled debug. ### Security * Improvements to better defend against XSS (Cross-Site Scripting) attacks. ### Fixed * The `kickstart.success` event may not fire correctly after Kickstart completes due to a timing issue when creating the webhook in your Kickstart definition. * Navigating to the System -> About page in the FusionAuth admin UI may fail to render if you start up without an internet connection. * Navigating to the System -> Webhook Log in the FusionAuth admin UI may display a general error and fail to return search results if there are any events of type `user.login.failed` displayed. You may work around this issue by selecting a specific event type, or narrowing the scope of the results by using any of the additional search criteria found in the Advanced search controls. ### Fixed * A user may fail to enroll a new Passkey (WebAuthn credential) used for reauthentication during a login workflow. Previously configured Passkeys should continue to work as expected. This bug was introduced in version `1.53.0`. ### Known Issues * FusionAuth's hosted login pages no longer create an SSO session when signing in using an external IdP. * A user may fail to enroll a new Passkey (WebAuthn credential) used for reauthentication during a login workflow. Previously configured Passkeys should continue to work as expected. * Currently, FusionAuth's Webhook Event Log does not set a retention policy by default and may grow too large in volume which can result in an impact to performance when searching Webhook Event Logs. See issue for workaround. * Related to [GitHub Issue #3008](https://github.com/FusionAuth/fusionauth-issues/issues/3008) ### Changed * The Docker image for the `linux/arm/v7` architecture is not being published for this release. This deprecation was announced in version `1.52.0`, and while we had planned to continue publishing this build for the next few releases, Java 21 is not being built for this architecture which means we can no longer support it. Please see thread in [Adoptium support](https://github.com/adoptium/adoptium-support/issues/962) or the [Adoptium release status](https://github.com/adoptium/temurin/issues/49) for additional details. * Related to [GitHub Issue #2473](https://github.com/FusionAuth/fusionauth-issues/issues/2473) ### New * The Webhook Event Log! The Webhook Event Log will contain a record of each triggered event and the corresponding attempts to deliver the event to each configured webhook. This log will be useful for monitoring events that have succeeded or failed to be received by your configured webhooks. The attempt log will provide you with timing, the status code returned by your webhook, and other metadata. The longer term goal of this feature will be to allow events to be retried when one or more webhooks failed to receive the event, or for some reason was unable to process the event. This is the first step towards that goal. You will find this new feature in the FusionAuth Admin UI under System -> Webhook Log. See the [API docs](/docs/apis/webhook-event-logs) and [Webhook Event Log documentation](/docs/extend/events-and-webhooks/webhook-event-log) for more detail. * Resolves [GitHub Issue #1314](https://github.com/FusionAuth/fusionauth-issues/issues/1314) * A new lambda function has been introduced that can be used to prevent login based on information in a user record, an application registration, and more. This allows the notion of a valid login to be extended beyond the standard items such as credential checks and MFA. See [Login Validation Lambda](/docs/extend/code/lambdas/login-validation) for more detail. * Resolves [GitHub Issue #1282](https://github.com/FusionAuth/fusionauth-issues/issues/1282) ### Fixed * When using an SSO TTL of `0` seconds or a very small number, it is possible that a user may not be able to complete login using the FusionAuth hosted login pages. If you encounter this problem prior to this version, you may work around the issue by increasing the TTL to something larger than `0`, ideally at least `30` seconds. The potential for this issue has existed for some time, but some changes made in version `1.50.0` made it more likely for this to occur. * Resolves [GitHub Issue #2736](https://github.com/FusionAuth/fusionauth-issues/issues/2736) * When using the start and end times in the Advanced search criteria in the FusionAuth admin UI for the Audit Log, Event Log, and Login Records the selected values were being incorrectly adjusted. This bug was introduced in version `1.52.0`. * Resolves [GitHub Issue #2843](https://github.com/FusionAuth/fusionauth-issues/issues/2843). Thanks to [@runely](https://github.com/runely) for reporting this! ⭐️ ### Enhancements * In the FusionAuth admin UI, tables had one-too-many 😜 action buttons. These action buttons have been replaced with a dropdown menu. The number of buttons on some pages grew to the point that it was becoming difficult to differentiate between the buttons, and was also visually cluttering up the view. We hope you like it! More UI and UX updates coming! * Resolves [GitHub Issue #2810](https://github.com/FusionAuth/fusionauth-issues/issues/2810) ### Internal * Java 21 LTS. Upgrade from Java 17, to the latest long term support (LTS) version of Java which is 21. * Resolves [GitHub Issue #2473](https://github.com/FusionAuth/fusionauth-issues/issues/2473) * Improve database connection resiliency under heavy load by separating interactive and non-interactive tasks into separate connection pools. This change should improve performance and scalability. Please note that if you are self-hosting FusionAuth you will see an increase in the number of open connections to the relational database from FusionAuth. Previously each FusionAuth node would open `10` connections. Starting in this release, this number will increase to a minimum of `21`, and can scale to a maximum of `50`. These numbers are subject to change in future releases. To calculate the total number of connections to the relational database, multiple these numbers by the number of nodes in your cluster. If you have a `3` node FusionAuth cluster, the minimum number of connections open to your database will be `63` with a maximum of `150`. * Resolves [GitHub Issue #2700](https://github.com/FusionAuth/fusionauth-issues/issues/2700) * Update dependencies. * Upgrade `js/handlebars.js` `4.7.6` -> `4.7.8` * Resolves [GitHub Issue #2829](https://github.com/FusionAuth/fusionauth-issues/issues/2829) ### Fixed * The SCIM Patch operation now properly handles removing multiple array elements, such as group memberships, in a single request. * Resolves [GitHub Issue #2834](https://github.com/FusionAuth/fusionauth-issues/issues/2834) ### Internal * Update dependencies. * Upgrade `io.fusionauth:fusionauth-scim` `2.2.1` -> `2.2.2` * Resolves [GitHub Issue #2858](https://github.com/FusionAuth/fusionauth-issues/issues/2858) **User Registrations API** When using the User Registrations API, the `data` field for the FusionAuth application with Id `3c219e58-ed0e-4b18-ad48-f4f92793ae32` may now contain a `preferences` object. This object is reserved and should not be modified. **Upgrading in an air-gapped configuration** If you are not using an air-gapped license, this message can be disregarded. Have a good day! For those running in an air-gapped configuration, you'll want to review this note. To ensure your premium features remain active after upgrading, please do the following: * Navigate to the [Plan page](https://account.fusionauth.io/account/plan) in your FusionAuth account * Pick up your license key and newly generated license text * Navigate to `Reactor` in your Admin UI on your FusionAuth instance * Decommission your license * Reactivate FusionAuth Reactor using the license key and text More details on activating and deactivating your license can be found in the [Licensing docs](/docs/get-started/core-concepts/licensing). **Group Member API** The `user` field on the Group Member API responses is being deprecated. This field was not documented, and has never been populated on the API response. However, because this field was generated and part of the domain in FusionAuth client libraries, we are providing a deprecation notice in case this may affect your integration. Client library users should remove references at your earliest convenience. Removal of this field is targeted for the end of 2024. **Docker architectures** We are planning to discontinue publishing Docker images for the following architectures: `linux/arm/v7`, `linux/ppc64le`, and `linux/s390x`. The rationale behind this decision is that we do not believe they are actively being used, and we would like to move to the GraalVM Java distribution which does not provide builds for these architectures. * https://hub.docker.com/r/fusionauth/fusionauth-app We plan to stop publishing docker images for these architectures at the end of 2024. If you are actively using any of these architectures, please let us know how this could affect you by contacting support or reaching out to sales. A new date picker element with enhanced styling and mobile support is now available. ### Known Issues * When using the start and end times in the Advanced search criteria in the FusionAuth admin UI for the Audit Log, Event Log and Login Records the selected value was being incorrectly adjusted. * Resolved in version `1.53.0` via [GitHub Issue #2843](https://github.com/FusionAuth/fusionauth-issues/issues/2843) ### Security * When detecting impossible travel or similarly suspicious login events, it is possible that not all device trust cookies were correctly revoked. These are now automatically revoked. * Resolves [GitHub Issue #2753](https://github.com/FusionAuth/fusionauth-issues/issues/2753) ### New * A free community license is now available, which adds WebAuthn (Passkeys) to the Community plan. All those with a Community license will now find a license key in their [FusionAuth account plan](https://account.fusionauth.io/account/plan) page. And there was much rejoicing! 🥳 * Resolves [GitHub Issue #2662](https://github.com/FusionAuth/fusionauth-issues/issues/2662) * Resolves [GitHub Issue #2663](https://github.com/FusionAuth/fusionauth-issues/issues/2663) ### Fixed * Clicking the toggle checkbox element in the admin UI quickly may cause the checkbox state to be inverted. This can be easily fixed by refreshing the page. You should now be able to click as fast as you want! Go forth and click! * Resolves [GitHub Issue #2718](https://github.com/FusionAuth/fusionauth-issues/issues/2718) * Attempting to sort API keys by key value in the admin UI by clicking the key value header would result in an error. * Resolves [GitHub Issue #2738](https://github.com/FusionAuth/fusionauth-issues/issues/2738) * When using the API Key API and specifying an invalid `tenantId` on the request in order to create a tenant-scoped API key, the request fails with a `500` status code. This error has been corrected, and an appropriate validation error is now returned. * Resolves [GitHub Issue #2749](https://github.com/FusionAuth/fusionauth-issues/issues/2749) * The date picker that was being used for birthdates and custom date fields was not styled correctly based upon the selected theme. The date picker has been changed to the browser-default date picker, which should work much better on mobile devices. This picker style will now be used in themed hosted login pages, as well as the admin UI for searching a date range or selecting a birthdate. This change should not affect any existing advanced theme that may still use the older style date picker. See [theme upgrade notes](/docs/customize/look-and-feel/upgrade#version-1520) for details on updating an existing advanced theme to use this new option. * Resolves [GitHub Issue #2770](https://github.com/FusionAuth/fusionauth-issues/issues/2770) * Adding custom message keys to your theme messages using the admin UI was failing to persist these changed messages. The UI for editing messages in the simple theme editor has also been improved to make it easier to understand which messages have been modified. * Resolves [GitHub Issue #2778](https://github.com/FusionAuth/fusionauth-issues/issues/2778) * When the Browser preview button was used to open a new tab for simple themes in the admin UI the page would render without any applied CSS when using the Firefox browser. Sorry Firefox users, we ask for your forgiveness. 😔 * Resolves [GitHub Issue #2794](https://github.com/FusionAuth/fusionauth-issues/issues/2794) * The default `orderBy` parameter value for the [Group Member Search API](/docs/apis/groups#search-for-group-members) did not provide a consistent ordering of results because the default sort was on `insertInstant ASC` which may not always be unique. This API is used by the SCIM Groups Resource API which then can cause inconsistent results for the SCIM client. The default `orderBy` is now set to `insertInstant ASC, userId ASC, groupId ASC` to ensure a consistent result between API calls. * Resolves [GitHub Issue #2798](https://github.com/FusionAuth/fusionauth-issues/issues/2798) * When using the simple theme editor in the admin UI, the color picker did not always render next to the input field. The color picker will now always correctly render adjacent to the input field you select. * Resolves [GitHub Issue #2803](https://github.com/FusionAuth/fusionauth-issues/issues/2803) * Newlines and tabs were not rendered when viewing audit entries in the view dialog from the admin UI. If you are using new lines or tabs in your audit log messages, you may now enjoy viewing them in all their intended glory! * Resolves [GitHub Issue #2808](https://github.com/FusionAuth/fusionauth-issues/issues/2808) * When using the interactive maintenance mode to upgrade your database schema, it is possible that you had to click the Submit button twice to exit maintenance mode. This was only a cosmetic issue but may be annoying or confusing to the user. We are sorry if you had to click the Submit button twice. 😬 * Resolves [GitHub Issue #2815](https://github.com/FusionAuth/fusionauth-issues/issues/2815) ### Enhancements * Add the new health check endpoint (`/api/health`) that was added in `1.51.1` to the client libraries. * Resolves [GitHub Issue #2804](https://github.com/FusionAuth/fusionauth-issues/issues/2804) ### Internal * For users in FusionAuth Cloud, attempting to save a Simple theme may result in an error. * Resolves [GitHub Issue #2777](https://github.com/FusionAuth/fusionauth-issues/issues/2777) * An equals (`=`) sign in query parameter value was not being parsed correctly. There are no known issues related to this bug as generally speaking an equals (`=`) sign will be URL encoded as `%3D`. However, because it is legal use an equals (`=`) sign un-encoded in a query string name or query string value, this has been corrected. * Resolves [GitHub Issue #2792](https://github.com/FusionAuth/fusionauth-issues/issues/2792) * An unused template was removed from the self-service login workflow. In practice this page was never rendered and was not included in the theme configuration. This change should not impact anyone using themes. * Resolves [GitHub Issue #2818](https://github.com/FusionAuth/fusionauth-issues/issues/2818) * Update dependencies. * Upgrade `org.freemarker:freemarker` `2.3.32` -> `2.3.33` * Upgrade `org.primeframework:prime-mvc` `4.22.7` -> `4.22.12` * Upgrade `org.apache.kafka:kafka-clients` `3.6.1` -> `3.7.1` * Upgrade `com.fasterxml.jackson.*` `2.15.4` -> `2.17.2` * Upgrade base docker image `ubuntu:jammy (22.04)` -> `ubuntu:noble (24.04)` * Resolves [GitHub Issue #2726](https://github.com/FusionAuth/fusionauth-issues/issues/2726) ### Security * A XSS (Cross-Site Scripting) vulnerability was identified in the FusionAuth admin UI. * Resolves [GitHub Issue #2801](https://github.com/FusionAuth/fusionauth-issues/issues/2801) ### Fixed * An HTTP request sent to FusionAuth with non-ASCII characters in request header values caused the request to be rejected and caused the connection to be closed without a response. Generally speaking values outside of the ASCII character set are not allowed, but in practice they may be used, and so these values are now treated as opaque and ignored by the HTTP request parser. * Resolves [GitHub Issue #2774](https://github.com/FusionAuth/fusionauth-issues/issues/2774) * A typo was found in the description of the `user.password.reset.send` event on the tenant edit page. * Resolves [GitHub Issue #2782](https://github.com/FusionAuth/fusionauth-issues/issues/2782) * The SCIM API is not properly handling reading, creating, and updating groups with more than one hundred memberships. Responses containing groups with more than one hundred memberships are only returning the first one hundred. Create and update operations are only creating or updating one hundred, and deleting the remainder. This defect also caused the FusionAuth event for `group.member.update` and `group.member.update.complete` to contain the same truncated list of members. * Resolves [GitHub Issue #2784](https://github.com/FusionAuth/fusionauth-issues/issues/2784) ### New * A Health API `/api/health` has been added. Prior to this addition, the `/api/status` endpoint was the best option for performing health checks. The Status API may not be ideal for all use cases because it returns a JSON body and the status code is used to indicate the status of various health checks that may not be valuable by a load balancer to indicate if requests should be routed to this node. This new endpoint provides a binary indication of the healthiness or unhealthiness of a FusionAuth instance by only returning a `200` or `500` status code w/out a JSON response. This new API also runs fewer health checks and may perform better than the Status API. * Resolves [GitHub Issue #1166](https://github.com/FusionAuth/fusionauth-issues/issues/1166) ### Internal Update dependencies. * Upgrade `io.fusionauth:java-http` `0.3.4` to `0.3.5` * Resolves [GitHub Issue #2786](https://github.com/FusionAuth/fusionauth-issues/issues/2786) ### Fixed * In version `1.45.0` we added a hosted OAuth backend capability, allowing a developer to write a front end-only application, but still take advantage of an authorization code grant workflow by leveraging the backend provided by FusionAuth. Multi-segment domain suffixes (e.g. `.co.uk`) are not handled correctly by this hosted backend when setting the domain on cookies. Cookie domains are now set properly. * Resolves [GitHub Issue #2735](https://github.com/FusionAuth/fusionauth-issues/issues/2735) * A SAML login request that is missing a `Content-Type` header yields a cryptic error message. A more meaningful error message is now provided. Additionally, sending a `binding` parameter would lead to an error message, when this parameter is not one we process. We now ignore this parameter if it is provided. * Resolves [GitHub Issue #2722](https://github.com/FusionAuth/fusionauth-issues/issues/2722) * A SMS two factor messages template can be set at the Tenant level and should be overridable at the Application level. When a template is set at the Application level it is not being honored and the Tenant-level template is always used. Application overrides of SMS two-factor templates are now used correctly. * Resolves [GitHub Issue #2728](https://github.com/FusionAuth/fusionauth-issues/issues/2728) ### Security * Improve SAMLv2 callback handing with malformed requests. * Resolves [GitHub Issue #2757](https://github.com/FusionAuth/fusionauth-issues/issues/2757) ### New * WYSIWYG theme editing! Version `1.51.0` introduces a new Simple Theme type, along with a visual editor. This first version of visual theme editing allows you to change the basic styling of FusionAuth hosted pages, including logos and background images, colors, fonts, and more. See the [Simple Theme Editor docs](/docs/customize/look-and-feel/simple-theme-editor) for more information. * Resolves [GitHub Issue #2669](https://github.com/FusionAuth/fusionauth-issues/issues/2669) ### Internal * Update dependencies. * Upgrade `org.graalvm.sdk:*:22.3.3` to `org.graalvm.polyglot:*:23.1.2` * Upgrade `org.graalvm.js:js` `22.3.3` to `23.0.3` * Upgrade `io.fusionauth:java-http` `0.3.2` to `0.3.4` * Resolves [GitHub Issue #2727](https://github.com/FusionAuth/fusionauth-issues/issues/2727) ### Fixed * FusionAuth added a First Time Setup wizard in 1.50.0. This release fixes a couple of usability items related to the new wizard. * Items related to the first time setup wizard are being show after upgrades, when the intent was to only show them for new installations. These are now only being shown for unconfigured FusionAuth instances. * In the First Time Setup summary page, FusionAuth shows sample configuration for various [quickstarts](/docs/quickstarts/). The configuration for the [React quickstart](/docs/quickstarts/quickstart-javascript-react-web) corresponds to a previous version of the quickstart and is incompatible with the current version. The React quickstart configuration is now formatted for the current quickstart version. * Resolves [GitHub Issue #2729](https://github.com/FusionAuth/fusionauth-issues/issues/2729) This release makes significant changes to the default behavior of new Applications with regard to scopes in OAuth workflows. The database migration will update existing Applications to behave in a backwards compatible manner. See the OAuth [Scopes](/docs/lifecycle/authenticate-users/oauth/scopes) documentation for more information, in particular the `Relationship`, `Unknown scope policy`, and `Scope handling policy` configurations. If you are using IFRAMEs to access the FusionAuth hosted login pages please check that the IFRAME `src` is from the same domain as the FusionAuth pages. [FusionAuth uses cookies](/docs/reference/cookies) to manage user state with the `SameSite` attribute set to `Lax` or `Strict`. Browsers will block `Set-Cookie` headers on cross-domain requests. This release introduces a new redirect into the OAuth flows to `/oauth2/consent` as part of the OAuth [Scopes](/docs/lifecycle/authenticate-users/oauth/scopes) feature. This redirect will occur during each browser-based interactive OAuth workflow. Prior to this version it was possible to complete an OAuth code grant flow without cookies being set as long as there were no additional redirects to FusionAuth before the final redirect to the configured redirect_url. As a result it did not matter if the `Set-Cookie` headers were blocked. The redirect with the code would still work. However, in this version the browser will not be able to send the FusionAuth cookies required to maintain user state along with the redirect to `/oauth2/consent` and the login flow will fail. The user will be redirected back to `/oauth2/authorize` and will be unable to log in. The use of JWT authentication for the `/api/user` API is being deprecated. This functionality will be removed in a future release. If you are using this API with JWT authentication, you will need to modify your integration to use the `/oauth2/userinfo` endpoint if you have obtained your JWT using an OAuth2 grant, or authenticate the request to the User API using an API key. Removal of this authentication type is targeted for the end of 2024. The new consent prompt themed page requires the `scopeConsentField` macro and `resolveScopeMessaging` function to be defined in the *Helpers* template in order to render scope consent form fields. These *must* be added to a custom theme in order for it to function. ### Known Issues * When using an SSO TTL of `0` seconds or a very small number, it is possible that a user may not be able to complete login using the FusionAuth hosted login pages. You may work around the issue by increasing the TTL to something larger than `0`, ideally at least `30` seconds. * Resolved in version `1.53.0` via [GitHub Issue #2736](https://github.com/FusionAuth/fusionauth-issues/issues/2736) ### Changed * The `/oauth2/userinfo` endpoint now requires the `aud` claim to be present on the provided access token, allowing for tighter compliance with the OIDC spec. See the [UserInfo endpoint](/docs/lifecycle/authenticate-users/oauth/endpoints#userinfo) for more detail. If you are not using OAuth, and your JWT does not contain the `aud` claim, consider using the [JWT validate](/docs/apis/jwt#validate-a-jwt) API instead. * GitHub issue pending * Resolves [GitHub Issue #2725](https://github.com/FusionAuth/fusionauth-issues/issues/2725) * Applications now offer an `Unknown Scope Policy`. This can be used to enhance security by rejected or removing unrecognized scopes during an OAuth workflow. See the application [Scopes tab](/docs/get-started/core-concepts/applications#scopes) for more detail. * Delivered as part of the Custom OAuth Scopes body of work, which resolves [GitHub Issue #275](https://github.com/FusionAuth/fusionauth-issues/issues/275) (see below) * Applications now have a new Scope Handling Policy. The `Strict` option provides behaviors that are more compliant with the OIDC specification, while the `Compatibility` option provides backwards-compatible behavior. Specifically, `Strict` mode limits information in access tokens and populates Id tokens and UserInfo responses based on the requested OAuth scopes. This option also restricts the UserInfo endpoint to accepting only access tokens containing the `openid` scope. See [Scope handling policy](/docs/lifecycle/authenticate-users/oauth/scopes#scope-handling-policy) for more detail. * New applications will default to the `Strict` option. If your integration requires the `Compatibility` policy because you need backwards compatible behavior, please specify that option when creating the application. * Resolves [GitHub Issue #1582](https://github.com/FusionAuth/fusionauth-issues/issues/1582) and [GitHub Issue #1475](https://github.com/FusionAuth/fusionauth-issues/issues/1475), thanks to [@awoodobvio](https://github.com/awoodobvio) for the suggestions! * The [Refresh Token Grant](/docs/lifecycle/authenticate-users/oauth/endpoints#refresh-token-grant-request) request now supports requesting a subset of the original scopes. The former behavior was to respond with an `invalid_scope` OAuth error. * Resolves [GitHub Issue #2590](https://github.com/FusionAuth/fusionauth-issues/issues/2590) * Support for optional expansion of the `application.roles` and `application.scopes` properties on the Application Search API. This change is backwards compatible, but you may optionally request the Search API omit these properties on the response which may improve performance. See the [Application Search](/docs/apis/applications#search-for-applications) API for additional details on using the `expand` request parameter, and the `expandable` response value. * Resolves [GitHub Issue #2724](https://github.com/FusionAuth/fusionauth-issues/issues/2724) * The `/oauth2/device/user-code` endpoint now returns the `scope` parameter value that should be used in the interactive portion of the Device Code Grant workflow. See [Device User Code](/docs/lifecycle/authenticate-users/oauth/endpoints#device-user-code) for more detail. * Addressed as part of the Custom OAuth Scopes body of work, which resolves [GitHub Issue #275](https://github.com/FusionAuth/fusionauth-issues/issues/275) (see below) ### Fixed * FusionAuth will now limit passwords to 50 characters when using the bcrypt algorithm. This restriction is due to limitations in the bcrypt algorithm. This limit will be enforced even when the tenant policy allows for a maximum password length greater than 50. If the tenant policy requires a maximum password length of less than 50, the tenant policy will take precedence. * Resolves [GitHub Issue #2671](https://github.com/FusionAuth/fusionauth-issues/issues/2671) * There are several scenarios where implicit email verification can occur. They are, during registration verification, password change, passwordless authentication, and MFA code validation. In these cases, a configured email verification email was not being sent, and the email verification event was not being generated. The email and event will both be triggered during implicit verification now. * Resolves [GitHub Issue #1651](https://github.com/FusionAuth/fusionauth-issues/issues/1651) and [GitHub Issue #2672](https://github.com/FusionAuth/fusionauth-issues/issues/2672). Thanks to [@ashutoshningot](https://github.com/ashutoshningot) and [@mou](https://github.com/mou), respectively, for the suggestions! * When configuring MFA for an application, the `Trust policy` selector is not being shown when MFA is required for the application, but only shown when MFA enabled for optional use. The selector is now shown when the `On login policy` is set to either `Enabled` or `Required`. * Resolves [GitHub Issue #2593](https://github.com/FusionAuth/fusionauth-issues/issues/2593) * When using FusionAuth behind a proxy, a missing `X-Forwarded-Proto` header could incorrectly cause a warning of a missing `X-Forwarded-Port` header. These warnings are now reported accurately. Additionally, FusionAuth will now be smarter about determining the forwarded port, taking it from one of multiple sources including `X-Forwarded-Host`, `X-Forwarded-Port`, or inferring it from `X-Forwarded-Proto`. This should make FusionAuth work with more proxies out of the box without additional configuration. * Resolves [GitHub Issue #2702](https://github.com/FusionAuth/fusionauth-issues/issues/2702) * When authentication with an identity provider fails due to misconfiguration, and a user falls back to logging in with a username and password, the `authenticationType` that is reported by FusionAuth is for the original identity provider despite the user having logged in with a username and password. FusionAuth now correctly reports the authentication type as `PASSWORD`. Thanks to [@charlesericjs](https://github.com/charlesericjs) for bringing this to our attention! * Resolves [GitHub Issue #2670](https://github.com/FusionAuth/fusionauth-issues/issues/2670) ### Enhancements * FusionAuth will now enforce a maximum password length of 256 characters in the tenant password policy. This decision was made to strike a balance between allowing for very secure passwords, but also for maintaining acceptable performance when using a large number of hash iterations. * Resolves [GitHub Issue #2688](https://github.com/FusionAuth/fusionauth-issues/issues/2688) ### New * Custom OAuth scopes are now supported for applications. Custom OAuth scopes come along with a number of related features, including support for third-party applications, themeable user consent, and much more. See the [API docs](/docs/apis/scopes) and [OAuth Scopes documentation](/docs/get-started/core-concepts/scopes) for more detail. * Resolves [GitHub Issue #275](https://github.com/FusionAuth/fusionauth-issues/issues/275), thanks to [@badaz](https://github.com/https://github.com/badaz) for the suggestion! * Applications may now be designated as third-party applications. In addition to the prompting for authorization that comes with the `Custom OAuth Scopes` feature (see above), limitations are being added to how third-party applications may interact with FusionAuth. * Resolves [GitHub Issue #2723](https://github.com/FusionAuth/fusionauth-issues/issues/2723) * Applications can now be configured to prompt users to grant consent to requested OAuth scopes using the `/oauth2/consent` [themed](/docs/customize/look-and-feel/) page. See the OAuth [Scopes](/docs/lifecycle/authenticate-users/oauth/scopes) for more detail. * Resolves [GitHub Issue #411](https://github.com/FusionAuth/fusionauth-issues/issues/411) * A new lambda function has been introduced that can be used to customize the UserInfo response for an application. See [UserInfo Populate Lambda](/docs/extend/code/lambdas/userinfo-populate) for more detail. * Resolves [GitHub Issue #1647](https://github.com/FusionAuth/fusionauth-issues/issues/1647) and [GitHub Issue #659](https://github.com/FusionAuth/fusionauth-issues/issues/659), thanks to [@themobi](https://github.com/themobi) and [@soullivaneuh](https://github.com/soullivaneuh) for the suggestions! * A new, optional First Time Setup wizard has been added, which guides a developer through the basic setup needed to integrate their first application. After installing FusionAuth, you'll be able to access this from the main admin dashboard, as well as from the top of the left hand navigation. * Resolves [GitHub Issue #2717](https://github.com/FusionAuth/fusionauth-issues/issues/2717) ### Internal * Update dependencies. * Upgrade `ch.qos.logback:logback-*` `1.4.14` to `1.5.6` * Upgrade `com.fasterxml.jackson.*` `2.15.3` to `2.15.4` * Upgrade `io.fusionauth:java-http` `0.2.10` to `0.3.2` * Upgrade `org.mybatis:mybatis` `3.5.15` to `3.5.16` * Upgrade `org.primeframework:prime-mvc` `4.22.0` to `4.22.7` * Upgrade `org.postgresql:postgresql` `42.7.2` to `42.7.3` * Upgrade `org.slf4j:slf4j-api` `2.0.7` to `2.0.13` * Resolves [GitHub Issue #2678](https://github.com/FusionAuth/fusionauth-issues/issues/2678) ### New * The search index default refresh interval may now be configured. In general this should not be modified, but the configuration option has been added and will default to `1s`. The new configuration is named `fusionauth-app.search.default-refresh-interval`. See the [Configuration](/docs/reference/configuration) reference for additional detail. * Resolves [GitHub Issue #2679](https://github.com/FusionAuth/fusionauth-issues/issues/2679) ### Fixed * When configured to use an email verification strategy of `Form Field` without setting the unverified behavior to `Gated` the verification strategy was always functionally using `Clickable Link` which means the user would receive an email with a clickable URL instead of a short code. With this fix, you may now use an unverified behavior of `Allow` with a verification strategy of `Form Field`. When you configure FusionAuth this way, it is assumed that you will be handling the verification process in your own application. * Resolves [GitHub Issue #1734](https://github.com/FusionAuth/fusionauth-issues/issues/1734) * When using the Bulk User Import API `/api/user/import` the search index refresh interval is modified to improve performance. Specifically the index `refresh_interval` is set equal to `-1`. When this API is called in parallel, it is possible that this index setting is not reset and will stay configured as `-1`. The symptom of this error is that changes to the index are not reflected by the Search API and the search results may no longer be accurate. * Resolves [GitHub Issue #2679](https://github.com/FusionAuth/fusionauth-issues/issues/2679) * When Advanced Threat Detection is enabled, an IP location database will be downloaded and used for IP address resolution. For these licensed customers, it is possible that a corrupted IP location database was downloaded and not correctly discarded and as a result the IP address location data may not be available. You may have been impacted if you were using version `1.47.0` or later, between February 1st, 2024 and February 23rd, 2024. The observable symptom would be that your license status for the Advanced Threat Detection will show `Pending` instead of `Active`. This condition has already been corrected for FusionAuth Cloud. If you are self-hosting FusionAuth, upgrading will correct this condition. If you have a support contract and believe you are currently in this state and are not able to upgrade, please reach out to support for assistance. * Resolves [GitHub Issue #2673](https://github.com/FusionAuth/fusionauth-issues/issues/2673) ### Enhancements * Add email and registration verification Ids to the User and Registration API responses when available for consistency and to better enable out of band management of these verification workflows. * Resolves [GitHub Issue#2681](https://github.com/FusionAuth/fusionauth-issues/issues/2681) ### Changed * The Nashorn JavaScript engine has been removed from FusionAuth. All Lambda functions will now use the GraalJS engine which has been available since version `1.35.0`. No action is required, but please note that if you had any Lambda functions still configured to use the Nashorn engine they will be migrated to use GraalJS. * Resolves [GitHub Issue #1828](https://github.com/FusionAuth/fusionauth-issues/issues/1828) * In prior versions of FusionAuth, if a new themed page was added, until you upgraded your theme by adding this new page, the end user may be shown a page indicate the page was missing. This was shown because it was assumed that a new page would only be shown for a new feature that had not been enabled, and this page would only ever been seen during development. In this release we are adding a new page that may be shown w/out any additional features being enabled. For this reason, we have removed this place holder page, and we will always fall back to the default theme when a page is missing. You will still want to upgrade your theme as part of your upgrade process, but this change will ensure that we will not break any new or existing workflows when a new page is added. * Resolves [GitHub Issue #2443](https://github.com/FusionAuth/fusionauth-issues/issues/2443) ### Security * An incorrectly formatted SAML request may cause excessive CPU load. * Resolves [GitHub Issue #1681](https://github.com/FusionAuth/fusionauth-issues/issues/1681) * Disable additional JNDI settings in the LDAP connector. This update is proactive, there are no known exploits. * Resolves [GitHub Issue #2605](https://github.com/FusionAuth/fusionauth-issues/issues/2605) * Add additional protection against cross-site attacks when FusionAuth is acting as a SAML IdP. * Resolves [GitHub Issue #2611](https://github.com/FusionAuth/fusionauth-issues/issues/2611) * Audit log entries added by the FusionAuth admin application may contain sensitive information. Sensitive fields will now be masked when written to the audit log. Please note that this does not affect the Audit Log API, only the use of this API by the FusionAuth admin app. * Resolves [GitHub Issue #2623](https://github.com/FusionAuth/fusionauth-issues/issues/2623) * Added additional protection against cross-site attacks when using the self-service account pages. * Resolves [GitHub Issue #2626](https://github.com/FusionAuth/fusionauth-issues/issues/2626) ### Fixed * The default permissions in AWS RDS PostgreSQL version 15.2 caused the initial configuration of FusionAuth to fail to create the tables required to complete the initial configuration. The required permissions are now being explicitly granted, and the errors reported back to the user have been improved. * Resolves [GitHub Issue #2264](https://github.com/FusionAuth/fusionauth-issues/issues/2264) * If a user starts a Forgot Password flow, and clicks on a change password link in an email after the link has expired, the redirect back to the original Forgot Password form will not include the locale parameter. This fix ensures that a locale parameter, when present in the change password link, is preserved through this workflow and allows for localization to remain consistent. * Resolves [GitHub Issue #2328](https://github.com/FusionAuth/fusionauth-issues/issues/2328) * When setting up a Facebook IdP, an option was provided in the admin UI to select `Use vendor JavaScript` as a Login method. This option is not applicable and has been removed. * Resolves [GitHub Issue #2351](https://github.com/FusionAuth/fusionauth-issues/issues/2351) * Fix the SCIM filter when filtering on `userName eq {username}` to always return a single result. * Resolves [GitHub Issue #2455](https://github.com/FusionAuth/fusionauth-issues/issues/2455) * The LinkedIn APIs have changed, and the LinkedIn IdP no longer worked for new LinkedIn applications. This update allows FusionAuth to work with new and legacy LinkedIn applications. * Resolves [GitHub Issue #2496](https://github.com/FusionAuth/fusionauth-issues/issues/2496) * The FusionAuth TypeScript client library was incorrectly encoding arrays values into query parameters. This bug was preventing a few specific search queries from working correctly. * Resolves [GitHub Issue #2513](https://github.com/FusionAuth/fusionauth-issues/issues/2513) * When using MySQL, the default Admin user form was missing the `First name` field. The field could be added to the form, but was missing in the default version. * Resolves [GitHub Issue #2529](https://github.com/FusionAuth/fusionauth-issues/issues/2529) * When an invalid Tenant Id was provided on the `.well-known/openid-configuration` the default configuration was returned. This has been updated to return a `404` status code. * Resolves [GitHub Issue #2538](https://github.com/FusionAuth/fusionauth-issues/issues/2538) * When creating a User with a group membership with a specified member Id that was already in use, the requested completed w/out a validation error and the membership was ignored. The API now correctly validates this condition and will return a `400` and a JSON response. * Resolves [GitHub Issue #2586](https://github.com/FusionAuth/fusionauth-issues/issues/2586) * When retrieving all refresh tokens for a user, the response may contain the user's SSO token. The SSO token can be identified because it does not contain an `applicationId` and it may not be refreshed. Validation has been improved when using the Refresh Grant, or the Refresh API to ensure FusionAuth correctly fails indicating the token is invalid and may not be refreshed. * Resolves [GitHub Issue #2594](https://github.com/FusionAuth/fusionauth-issues/issues/2594) * A regression was introduced in version `1.47.0` to the Change Password themed page. The issue is that the `passwordValidationRules` variable may be `null` on the first render. If you had been referencing this field in your template, the render may fail. * Resolves [GitHub Issue #2616](https://github.com/FusionAuth/fusionauth-issues/issues/2616) * The Identity Provider Link API states that a `token` parameter can be accepted during a create. When provided, the token was not being persisted on the link. * Resolves [GitHub Issue #2622](https://github.com/FusionAuth/fusionauth-issues/issues/2622) * Fix the "Getting Started" link found in the index page in the default theme. * Resolves [GitHub Issue #2625](https://github.com/FusionAuth/fusionauth-issues/issues/2625) * When viewing a User's Consents in the FusionAuth admin UI, if one or more of the consents have been granted by another user that is not a member of their family, an error is shown in the `Given by` column. * Resolves [GitHub Issue #2639](https://github.com/FusionAuth/fusionauth-issues/issues/2639) * When you have configured the JWT signing key with the `ES512` algorithm, the generated signature may be intermittently invalid. This means that JWTs may seemingly fail to validate randomly and you may think you are crazy. You are not crazy. If you are using this signing algorithm, it is recommended you use a different algorithm until you are able to upgrade. * Resolves [GitHub Issue #2661](https://github.com/FusionAuth/fusionauth-issues/issues/2661) * SCIM PATCH requests may fail to parse if an op path value contains a named schema containing a `.` (dot). This parsing error has been corrected. For example: `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department` * Resolves [GitHub Issue #2667](https://github.com/FusionAuth/fusionauth-issues/issues/2667) * When an SCIM create or update request contains schemas for which no properties exist, subsequent PATCH requests to those schema namespaces may fail. For example, if the initial request contains a schema `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User` without any properties, the default lambda function used to map this request to FusionAuth was not persisting this schema namespace. Then a subsequent PATCH request to add a member to that namespace such as `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department` would fail. The default SCIM request converter (Lambda function) has been updated to correct this behavior. * Resolves [GitHub Issue #2667](https://github.com/FusionAuth/fusionauth-issues/issues/2667) ### Enhancements * Link checkers are great. They aim to protect end users from malicious links and phishing attacks. However, they wreak havoc and pain on identity providers using email based workflows to complete passwordless login, or email verification. And FusionAuth is one of those identity providers! FusionAuth has employed various tactics over the years to stay ahead of the techniques used by these 3rd party tools. Their techniques continue to evolve making it difficult or impossible to know the difference between a link checker and a real human interacting with the link. A new confirmation page has been added that is intended to protect the user, and make our email workflows immune to link checkers. For example, when a user initiates a request such as passwordless login, and then completes the request in the same browser, the user will not observe any change. If the user completes the request on a different browser, or completes a request they did not initiate - such as clicking on an email verification link sent when a use is provisioned by an administrator, the user will be prompted to confirm they wish to complete the request. If you are using a custom theme, you will want to upgrade your theme to include this new page. Until you complete this upgrade, the default theme will be used for this new page. In the FusionAuth admin UI, the theme page will be named *Confirmation required*. * Resolves [GitHub Issue #2443](https://github.com/FusionAuth/fusionauth-issues/issues/2443) * Ensure the Login API never fails validation due to a timing issue with an Application cache. This rarely affects runtime, but this can be useful for testing where you may create an application and immediately perform a login. * Resolves [GitHub Issue #2557](https://github.com/FusionAuth/fusionauth-issues/issues/2557) * Add a trusted proxy configuration to the System Configuration. This new configuration allows you to define one or more trusted upstream proxies using an IP address, or range of addresses using a CIDR notation. A client IP address will be captured in a login record, sent to webhooks, and used to provide access when IP ACLs are configured. To correctly resolve the client IP address, we often will need to use the `X-Forwarded-For` request header. This header is modified when it passes through a proxy. In order to trust the contents of this header and resolve the client IP address, FusionAuth must know if it can trust all proxies implicitly, or to only trust those that are explicitly configured as trusted. The change is to optionally configure FusionAuth to no longer trust any upstream proxy that is not explicitly configured as trusted. This new configuration can be found in the FusionAuth admin UI by navigating to `Settings > System > Networking`, or on the System Configuration API. * Resolves [GitHub Issue #2624](https://github.com/FusionAuth/fusionauth-issues/issues/2624) ### Internal * Update dependencies. * Upgrade `org.postgresql:postgresql` `42.6.0` to `42.7.2` * Upgrade `com.fasterxml.jackson.*` `2.15.2` to `2.15.3` * Upgrade `org.mybatis:mybatis` `3.5.13` to `3.5.15` * Resolves [GitHub Issue #2534](https://github.com/FusionAuth/fusionauth-issues/issues/2534) * During a reindex operation, log the progress based upon a fixed time interval instead of every 250k records. This ensures the output is predictable regardless of the reindex performance. * Resolves [GitHub Issue #2565](https://github.com/FusionAuth/fusionauth-issues/issues/2565) ### Fixed * Update the refresh token TTL when using the sliding window with a maximum lifetime JWT Expiration Policy. The symptom of this bug is that a refresh token will expire before the maximum configured lifetime. * Resolves [GitHub Issue #2566](https://github.com/FusionAuth/fusionauth-issues/issues/2566) ### Fixed * When paging beyond 10,000 in the FusionAuth admin UI for Users or Entities, the bottom set of pagination controls may not work. If you encounter an error when clicking on the pagination controls, use the top set of controls instead. This bug is specific to the new pagination introduced in version `1.48.0`. * Resolves [GitHub Issue #2544](https://github.com/FusionAuth/fusionauth-issues/issues/2544) * In some cases when using with FusionAuth-hosted pages in an non-secure context, such as accessing FusionAuth on `localhost`, the `PublicKeyCredential` JavaScript API will not be available. This may cause an error on your JavaScript console `PublicKeyCredential is not defined`. This error kept the form on the page from correctly submitting. * Resolves [GitHub Issue #2500](https://github.com/FusionAuth/fusionauth-issues/issues/2500) * In version `1.48.0` a change was made to reject a link request from an OpenID Connect IdP when the `email_verified` claim is supplied with a value of `false`. An assumption was made that the `email` and `email_verified` claims would both be present in the `Userinfo` response or the `id_token`. Some providers may split these claims, so this assumption has been removed. * Resolves [GitHub Issue #2542](https://github.com/FusionAuth/fusionauth-issues/issues/2542) ### Security * Correct the validation of the `post_logout_redirect_uri` parameter on the OAuth2 Logout request for relative URIs intended for use for FusionAuth applications. * Resolves [GitHub Issue #2539](https://github.com/FusionAuth/fusionauth-issues/issues/2539) ### Internal * Improve our JWT validation for internal security schemes by failing faster on invalid tokens. * Resolves [GitHub Issue #2555](https://github.com/FusionAuth/fusionauth-issues/issues/2555) ### Fixed * A bug was identified in a change made in version `1.48.0` that may affect performance for those with > 1M users. * Resolves [GitHub Issue #2535](https://github.com/FusionAuth/fusionauth-issues/issues/2535) ### Known Issues * A bug was identified in a change made in this version that may affect performance for those with > 1M users. * Resolved in version `1.48.1` via [GitHub Issue #2535](https://github.com/FusionAuth/fusionauth-issues/issues/2535) ### Changed * We are officially announcing the end of life for the Nashorn JavaScript engine used by FusionAuth Lambda functions. All new functions have defaulted to the GraalJS since version `1.35.0`. The engine is not being removed in the release, but this is an official notice that we plan to remove this engine in early 2024. Please review your lambda functions and ensure the `engineType` is set to `GraalJS`. * Resolves [GitHub Issue #1828](https://github.com/FusionAuth/fusionauth-issues/issues/1828) * We are officially announcing the end of life for the `fusionauth-search` package. This is currently available in a `.deb`, `.rpm` and `.zip` bundle for various platforms. This package is still available, but the plan is to stop building this at the end of 2023. Please make plans to discontinue use of the `fusionauth-search` package if you are currently using it. * Resolves [GitHub Issue #2532](https://github.com/FusionAuth/fusionauth-issues/issues/2532) * When the OpenID Connect or External JWT Identity Provider is configured to Link by Email and the IdP returns a claim named `email_verified` and the value is `false`, the link request will be rejected. This change is intended to reduce the risk of linking on an un-verified email address. * Resolves [GitHub Issue #2423](https://github.com/FusionAuth/fusionauth-issues/issues/2423) ### Security * When an IdP is configured to Link by Email or Link by Username and a user already exists with this email or username respectively, perform additional validation to ensure the user does not already have an existing link to the current Identity Provider. This only affects IdP that allow for one to many tenants to be accessed through a single IdP configuration. In practice this means that the IdP cannot guarantee that an email address is considered globally unique and only assigned to a single user. * Resolves [GitHub Issue #2512](https://github.com/FusionAuth/fusionauth-issues/issues/2512) * A bug was identified in the `multipart/form-data` parser that may cause elevated CPU usage in some specific cases. * Resolves [GitHub Issue #2385](https://github.com/FusionAuth/fusionauth-issues/issues/2385) ### Fixed * Enhance the widget used in multi-value select controls to accept a value when pasting. For example, you may now paste a value from the clipboard directly into the `Authorized redirect URLs` field. While previously the paste operation worked, the user would have to click the value to confirm. If you clicked off of the field, the value would not be saved. * Resolves [GitHub Issue #1784](https://github.com/FusionAuth/fusionauth-issues/issues/1784) * Correct the error message when a user has enabled MFA and a webhook returns a non-200 status code for the `user.login.success` event. The message will now correctly indicate the webhook has failed instead of the previously incorrect error indicating an invalid token was used. * Resolves [GitHub Issue #1955](https://github.com/FusionAuth/fusionauth-issues/issues/1955) * When viewing an Email Template in the FusionAuth admin UI, two dialogs open instead of one. This was the result of two event handlers being bound instead of one. * Resolves [GitHub Issue #2304](https://github.com/FusionAuth/fusionauth-issues/issues/2304) * When using the asynchronous tenant delete, it is possible for the delete job to fail if the system is under heavy load. When this occurs the delete job status may not be correctly updated and you are stuck in a `Deleting` state. The asynchronous job processor has been enhanced to account for this potential failure condition so the job can be correctly restarted if necessary. * Resolves [GitHub Issue #2307](https://github.com/FusionAuth/fusionauth-issues/issues/2307) * Correct a potential race condition that could cause a request to the `/.well-known/jwks.json` endpoint to exception and return a `500` status code when under heavy load. * Resolves [GitHub Issue #2390](https://github.com/FusionAuth/fusionauth-issues/issues/2390) * The Lambda metrics introduced in version `1.47.0` may not always correctly increment the failed count when a lambda invocation failed. This affects the `lambda.[*].failures` and `lambda.[{webhookId}].failures` metric names. * Resolves [GitHub Issue #2408](https://github.com/FusionAuth/fusionauth-issues/issues/2408) * When using the `PATCH` method on the Tenant API, if you previously had any explicit webhooks configured for this tenant, the association between the tenant and the webhook was lost. If you are not using webhooks, or all of your webhooks are configured for `All tenants` (`webhook.global`), this bug would not affect you. * Resolves [GitHub Issue #2411](https://github.com/FusionAuth/fusionauth-issues/issues/2411) * Improve the validation for the Entity API to correctly validate the `type.id` value. Because this value was not being correctly validated, it means the API caller may receive a `500` status code instead of a `400` with a developer friendly JSON response body to indicate how the input can be corrected. * Resolves [GitHub Issue #2412](https://github.com/FusionAuth/fusionauth-issues/issues/2412) * A critical bug was identified that caused FusionAuth to incorrectly identify users eligible for deletion based upon the tenant policy to delete users with an unverified email address. Until you have upgraded to version `1.48.0` please disable `Delete unverified users` if you currently have enabled `Email verification`, `Verify email when changed` and `Delete unverified users`. * Resolves [GitHub Issue #2441](https://github.com/FusionAuth/fusionauth-issues/issues/2441) * A bug was identified that affected several APIs when using the `PATCH` method with fields that require custom deserializers in FusionAuth. Affected APIs included Application, Connector, Message Template and Identity Provider. The symptom you will observe is a failed request with a `500` status code. * Resolves [GitHub Issue #2454](https://github.com/FusionAuth/fusionauth-issues/issues/2454) * When using PostgreSQL, under heavy load, a potential deadlock conditions exists when attempting to write login metrics to the database. MySQL database was not affected by this bug. If you were to encounter this bug you may observe some exceptions in the log related to the LoginQueue. * Resolves [GitHub Issue #2465](https://github.com/FusionAuth/fusionauth-issues/issues/2465) * Fix a JavaScript error that was preventing Audit Log searches by user from returning results. * Resolves [GitHub Issue #2470](https://github.com/FusionAuth/fusionauth-issues/issues/2470) * Resolve an issue where users could not enable two-factor authentication during authentication when they were not registered for the application. Thanks to [@wproffitt-elder](https://github.com/wproffitt-elder) for reporting! * Resolves [GitHub Issue #2474](https://github.com/FusionAuth/fusionauth-issues/issues/2474) * When using the Refresh Token API, un-expired SSO sessions may be incorrectly omitted from the API response. The result of this bug is that an active SSO session may not be displayed in the FusionAuth admin UI. This has now been corrected, and the FusionAuth admin UI and the Refresh Token API will correctly return all valid SSO sessions. * Resolves [GitHub Issue #2489](https://github.com/FusionAuth/fusionauth-issues/issues/2489) * If the `search.servers` configuration value was not added to the `fusionauth.properties` configuration file, and you omit the `SEARCH_SERVERS` environment value, FusionAuth would fail to start. The correct behavior is for FusionAuth to default to `http://localhost:9021`. * Resolves [GitHub Issue #2507](https://github.com/FusionAuth/fusionauth-issues/issues/2507) ### Enhancements * Enhance the User and Entity Search APIs to paginate beyond 10,000 results. The Search API response will now include a `nextResults` value that can be used to ask for the next set of search results which enables the API to paginate through the entire available result set. * See the [Entity Search APIs](/docs/apis/entities/entities#search-for-entities) and [User Search APIs](/docs/apis/users#search-for-users) for API details. * Resolves [GitHub Issue #494](https://github.com/FusionAuth/fusionauth-issues/issues/494) * When using the Webhook test action in the FusionAuth admin UI, additional information will now be returned if the webhook returns a non-200 status code. This should make it simpler to debug your webhook integration. Prior to this change, the response would only indicate if the response was successful or not. * Resolves [GitHub Issue #793](https://github.com/FusionAuth/fusionauth-issues/issues/793) * When using the Webhook test action in the UI, changes to the example request body were not preserved. Changes will now be preserved across send requests for the browser session. This means a test can be run repeatedly without having to perform the same edits to the default event request body. * Resolves [GitHub Issue #797](https://github.com/FusionAuth/fusionauth-issues/issues/797) * Support specifying webhook SSL certificates from Key Master. Prior to this enhancement, if you needed to specify an SSL certificate, it had to be added to the webhook in PEM format. You may now store this certificate in Key Master and then use this same certificate between webhooks. This change is backwards compatible, but the ability to manually specify X.509 certificates in PEM format on the webhook configuration has been deprecated and may be removed in the future. See the [Webhook](/docs/apis/webhooks) API `sslCertificateKeyId` field for additional details. * Resolves [GitHub Issue #883](https://github.com/FusionAuth/fusionauth-issues/issues/883) * Modal dialogs in the FusionAuth admin UI can now be closed by using the escape key or by clicking outside of the modal. * Resolves [GitHub Issue #903](https://github.com/FusionAuth/fusionauth-issues/issues/903) * Add support for signing webhook events with a SHA-256 hash function. This feature will allow consumers of FusionAuth events to verify the message body has not been modified. The signature is contained in a JWT and will be sent using an HTTP request header named `X-FusionAuth-Signature-JWT`. You may use existing JWT verification strategies including consuming the public key from the JWKS endpoint. * See the [Signing Webhooks](/docs/extend/events-and-webhooks/signing) and [Webhooks APIs](/docs/apis/webhooks) for signing and verification details. * Resolves [GitHub Issue #1859](https://github.com/FusionAuth/fusionauth-issues/issues/1859) * Expose the `id_token` returned by the Identity Provider to the Reconcile Lambda function when available. If the `id_token` is returned by the IdP and the signature can be verified it will be now be passed to the lambda function in the `tokens` argument. Example: `tokens.id_token`. * Resolves [GitHub Issue #2189](https://github.com/FusionAuth/fusionauth-issues/issues/2189) * Add the `curl` command to the FusionAuth Docker image. This allows you to use the `curl` command for use in health checks or anytime you need to use `curl`! * Resolves [GitHub Issue #2272](https://github.com/FusionAuth/fusionauth-issues/issues/2272) * Support for optional expansion of the `user.registrations` and `user.memberships` properties on the User Search API. This change is backwards compatible, but you may optionally request the Search API omit these properties on the response which may improve performance. See the [User Search](/docs/apis/users#search-for-users) API for additional details on using the `expand` request parameter, and the `expandable` response value. * Resolves [GitHub Issue #2319](https://github.com/FusionAuth/fusionauth-issues/issues/2319) * Enhance the error messaging returned to the end user when using the Test SMTP button in the FusionAuth admin UI. This enhancement will make it easier to test your SMTP configuration. * Resolves [GitHub Issue #2373](https://github.com/FusionAuth/fusionauth-issues/issues/2373) * Reduce un-necessary logging when fuzzers send parameter names containing `class`. * Resolves [GitHub Issue #2393](https://github.com/FusionAuth/fusionauth-issues/issues/2393) * When updating a theme, a validation error will be returned if you are missing messages. Currently the error response does include the missing message keys. This error response is now enhanced to return the keys and the default values from the default theme. This allows you to optionally parse the response for the missing keys and values. * Resolves [GitHub Issue #2427](https://github.com/FusionAuth/fusionauth-issues/issues/2427) * Expose the `access_token` returned by the Identity Provider to the Reconcile Lambda function. The `access_token` will now be passed to the lambda function in the `tokens` argument. Example: `tokens.access_token`. * Resolves [GitHub Issue #2494](https://github.com/FusionAuth/fusionauth-issues/issues/2494) * When the `id_token` is returned from the IdP and the signature can be verified it will now be used to optionally resolve the `uniqueIdClaim` in addition to the `emailClaim` and `usernameClaim`. This means you can configure the `uniqueIdClaim` to a claim that is only available in the `id_token`. Prior to this change, the `id_token` could only be verified if it was signed using the an HMAC algorithm using the `client_secret`. With this change, if the IdP publishes public keys using the JWKS endpoint that is resolved from the `.well-known/openid-configuration` FusionAuth will attempt to validate the signature. * Resolves [GitHub Issue #2501](https://github.com/FusionAuth/fusionauth-issues/issues/2501) ### Internal * Update dependencies to remove CVE scan warnings and to stay current. These upgrades are simply a precautionary measure to stay current. * Upgrade `com.google.inject:guice` `5.1.0` to `6.0.0` * Upgrade `com.google.guava:guava` `30.1.0` to `32.1.2` * Upgrade `io.fusionauth:java-http` `0.2.0` to `0.2.9` * Upgrade `org.apache.kafka:kafka-clients` `2.8.2` to `3.6.0` * Upgrade `org.primeframework:prime-mvc` `4.11.0` to `4.17.1` * Upgrade `org.xerial.snappy:snappy-java` `1.1.8.1` to `1.1.10.4` * Resolves [GitHub Issue #2385](https://github.com/FusionAuth/fusionauth-issues/issues/2385) * Upgrade to the latest Java 17 LTS. Upgraded from `17.0.3+7` to `17.0.8+1`. * Resolves [GitHub Issue #2386](https://github.com/FusionAuth/fusionauth-issues/issues/2386) * Update the logging configuration when using the `fusionauth-search` distribution (`.deb`, `.rpm`, or `.zip`) to be more consistent with the `fusionauth-app` logging configuration. If you are using Elasticsearch or OpenSearch in Docker or other off the shelf installation of Elasticsearch or OpenSearch this change will not affect you. * Resolves [GitHub Issue #2391](https://github.com/FusionAuth/fusionauth-issues/issues/2391) * Update the FusionAuth static file resolution configuration to further limit class path resolution. While no known security risks exist with the current behavior, it is not necessary. * Resolves [GitHub Issue #2462](https://github.com/FusionAuth/fusionauth-issues/issues/2462) ### Fixed * Revert the GC (garbage collection) logging change introduced in version `1.47.0` for compatibility with the FusionAuth docker image. * Resolves [GitHub Issue #2392](https://github.com/FusionAuth/fusionauth-issues/issues/2392), thanks to [@pigletto](https://github.com/pigletto) and [@patricknwn](https://github.com/patricknwn) for reporting. Please be sure to read the notes in the **Changed** section before upgrading. ### Known Issues * The garbage collection logging change introduced in version `1.47.0` was not compatible with the way the FusionAuth docker image was built. You will need to use version `1.47.1` if you will be using the FusionAuth docker image. * The `passwordValidationRules` variable may be `null` on the first render of the Change Password themed page. If you had been referencing this field in your template, the render may fail. * The CSRF token used with federated login is not being applied when all configured IdPs for an application use managed domains and an `/oauth2/authorize` request for the application includes an `idp_hint` parameter. ### Security * A race condition exists when using a refresh token with a one-time-use policy where the same token value could successfully be used twice to obtain a new access token. In practice this would be very difficult to replicate outside of a scripted example. * Resolves [GitHub Issue #1840](https://github.com/FusionAuth/fusionauth-issues/issues/1840) Thanks to [@avitsrimer](https://github.com/avitsrimer) for reporting the issue! * Use a CSRF token with all federated login requests. This change will add additional protection when using a federated login to ensure the login is completed from the same browser that started the login workflow. This mitigates an attack vector that can be used in phishing attacks where a victim could be convinced to click on a link that would cause the user to unknowingly complete a login. * Resolves [GitHub Issue #2238](https://github.com/FusionAuth/fusionauth-issues/issues/2238) ### Changed * A change was made to the OAuth2 origin validation code. This change is not expected to cause any change in behavior for anyone with configured Authorized Origin URLs. The change is to inspect the port in addition to the schema and host when comparing the request and the `Referer` or `Host` header to determine if the request has originated from FusionAuth. One possible edge case that could be affected is if you using `localhost` in development for both FusionAuth and another application. In this example, it is possible that FusionAuth was not validating the Origin of requests from your application running on `localhost` correctly. If you encounter this case, you can either remove all Authorized Origin URLs from your configuration, or add the origin of your application so that it can be correctly validated. * Due to the necessary change related to adding a CSRF token when performing a federated login, a manual change may be required to your themed login pages. Please read through these details to understand if you will be affected. If you are using any 3rd party IdP configurations such as OpenID Connect, SAML v2, Google, Facebook with a custom theme, you will need to make a modification to your template in order for federated login to continue to work correctly. If you are not using any 3rd party IdP configurations, or you are not using a custom theme, no change will be necessary. If you will be affected by this change, please review the following details and then make the update to your theme as part of your upgrade process. 1. Find the `alternativeLogins` macro usage in `oauth2Authorize` and `oauth2Register` and add `federatedCSRFToken=federatedCSRFToken` as the last argument to this macro. ```html [#-- Updated macro usage. Line breaks added for readability. --] [@helpers.alternativeLogins clientId=client_id identityProviders=identityProviders passwordlessEnabled=passwordlessEnabled bootstrapWebauthnEnabled=bootstrapWebauthnEnabled idpRedirectState=idpRedirectState federatedCSRFToken=federatedCSRFToken/] ``` 2. Find the macro named `alternativeLogins` in `helpers` and add `federatedCSRFToken=""` as the last argument to this macro. ```html [#-- Updated macro in helpers. Line breaks added for readability. --] [#macro alternativeLogins clientId identityProviders passwordlessEnabled bootstrapWebauthnEnabled=false idpRedirectState="" federatedCSRFToken=""] ``` 3. Find the element `