## FusionAuth.io Full Documentation
# 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.
# 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).
# 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.
# Archived Release Notes
import Breadcrumb from 'src/components/Breadcrumb.astro';
import DatabaseMigrationWarning from 'src/components/docs/release-notes/DatabaseMigrationWarning.mdx';
import GeneralMigrationWarning from 'src/components/docs/release-notes/GeneralMigrationWarning.astro';
import GeneralUpgradeInfo from 'src/components/docs/release-notes/GeneralUpgradeInfo.mdx';
import InlineField from 'src/components/InlineField.astro';
import ReleaseNoteHeading from 'src/components/docs/release-notes/ReleaseNoteHeading.astro';
import ReleaseNotesSelector from 'src/components/docs/release-notes/ReleaseNotesSelector.astro';
import SearchIndexWarning from 'src/components/docs/release-notes/SearchIndexWarning.mdx';
Looking for release notes newer than 1.43.2? Look at the latest [release notes](/docs/release-notes/).
### Changed
* The User and User Registration APIs will now restrict `user.preferredLanguages` and `registration.preferredLanguages` to a maximum of `20` values. Additionally each value can be no longer than `24` characters. This change is not expected to impact any existing integrations. Do let us know if you have a use case that is not compatible with this change.
### Fixed
* When an event fails to be sent to a Kafka topic, do not attempt to send an `event-log.create` event that results from the failed request.
Correct an edge case that exists where an `event-log.create` event fails to be sent to a Kafka topic, and this error causes another `event-log.create` event to be triggered.
* Resolves [GitHub Issue #2362](https://github.com/FusionAuth/fusionauth-issues/issues/2362)
* Limit the length of a valid value for `user.preferredLanguages` and `registration.preferredLanguages` to a maximum of `24` characters, and restrict the total number of values to `20` or less.
* Resolves [GitHub Issue #2363](https://github.com/FusionAuth/fusionauth-issues/issues/2363)
### Internal
* Reduce Kafka logging to make it much less noisy at runtime
* Resolves [GitHub Issue #2359](https://github.com/FusionAuth/fusionauth-issues/issues/2359)
### Fixed
* Correct a potential FreeMarker render error caused by a missing CSRF token when performing an SAML v2 IdP initiated login to the FusionAuth admin UI. This error is a side effect of the caller not requesting the `scope=offline_access` parameter. With this fix, you should no longer encounter the error, and the `offline_access` scope is now optional on the request. A workaround is to request the `offline_access` scope.
* Resolves [GitHub Issue #2125](https://github.com/FusionAuth/fusionauth-issues/issues/2125)
### Known Issues
* Creating a new application from another application with `sourceApplicationId` returns a `500` error when the source application has SAML v2 enabled and configured. If you have not configured SAML v2, you will not be affected by this issue. Workaround is to call Create Application API without the `sourceApplicationId` parameter and supply all the parameters copied from the source application.
* Resolved in `1.44.0` via [GitHub Issue #2118](https://github.com/FusionAuth/fusionauth-issues/issues/2118).
### Fixed
* Support importing an x.509 certificate with a private key into KeyMaster in the admin UI.
* Resolves [GitHub Issue #1805](https://github.com/FusionAuth/fusionauth-issues/issues/1805), thanks to [@konvergence](https://github.com/konvergence) for reporting!
* When using the Forgot Password workflow on the FusionAuth login page with a user without an email address, the page would refresh instead of redirecting to the success screen indicating an email had been sent.
* Resolves [GitHub Issue #1809](https://github.com/FusionAuth/fusionauth-issues/issues/1809), thanks to one of our MVPs [@epbensimpson](https://github.com/epbensimpson) for letting us know.
* The Change Password API was incorrectly failing indicating a Trust Token was required even when provided if the user has MFA enabled.
* Resolves [GitHub Issue #1909](https://github.com/FusionAuth/fusionauth-issues/issues/1909), thanks to [@timyourivh](https://github.com/timyourivh) for the report!
* Ensure that we correctly terminate an SSO session when beginning a new passwordless login flow with a different user in the same browser.
* Resolves [GitHub Issue #1912](https://github.com/FusionAuth/fusionauth-issues/issues/1912)
* Fix various limitations with adding a consent to a self-service account form.
* Resolves [GitHub Issue #1920](https://github.com/FusionAuth/fusionauth-issues/issues/1920)
* An error may occur when logging into the FusionAuth admin UI with an IdP initiated request from a SAML v2 IdP.
* Resolves [GitHub Issue #1941](https://github.com/FusionAuth/fusionauth-issues/issues/1941), thanks to [@jon-at-advarra](https://github.com/jon-at-advarra) for filing the bug!
* An error may occur when logging into the FusionAuth admin UI with an IdP initiated request from a SAML v2 IdP and then navigating to your own profile page.
* Resolves [GitHub Issue #1976](https://github.com/FusionAuth/fusionauth-issues/issues/1976), thanks to [@jon-at-advarra](https://github.com/jon-at-advarra), this was a great edge case.
* When taking a User Action, the duration is localized for the event. The localization is only available for a fixed number of locales. When an un-supported locale, such as Serbian is requested, an exception will occur. This has been fixed to avoid the exception, and if an un-supported Locale is requested, English will be used as the default.
* Resolves [GitHub Issue #1978](https://github.com/FusionAuth/fusionauth-issues/issues/1978)
* When sending a test event to verify the Kafka configuration, the topic was not being validated as required.
* Resolves [GitHub Issue #1985](https://github.com/FusionAuth/fusionauth-issues/issues/1985), thanks to [@sixhobbits](https://github.com/sixhobbits), nice catch!
* When completing the forgot password workflow using the FusionAuth themed pages outside of an OAuth context, you may receive an error that says `Oops. It looks like you've gotten here by accident.`.
* Resolves [GitHub Issue #1989](https://github.com/FusionAuth/fusionauth-issues/issues/1989)
* Update the Email Template preview in the view dialog to be consistent with the preview in the edit page.
* Resolves [GitHub Issue #2007](https://github.com/FusionAuth/fusionauth-issues/issues/2007), thanks to [@lancegliser](https://github.com/lancegliser) for pointing this out!
* Restrict the Two Factor Trust during a Change Password request to be used for the workflow that started the request.
* Resolves [GitHub Issue #2010](https://github.com/FusionAuth/fusionauth-issues/issues/2010)
* Fix the edit Form Field in the FusionAuth admin UI for a consent field.
* Resolves [GitHub Issue #2026](https://github.com/FusionAuth/fusionauth-issues/issues/2026)
* Using password reset to unlock account may not work when MFA is enabled for the user. This is a bug in this new feature that was added in version `1.42.0`.
* Resolves [GitHub Issue #2032](https://github.com/FusionAuth/fusionauth-issues/issues/2032)
### Enhancements
* Additional configuration for the Apple IdP to support login from Mobile and Desktop.
* Resolves [GitHub Issue #778](https://github.com/FusionAuth/fusionauth-issues/issues/778), thanks to [@johnmaia](https://github.com/johnmaia) for his persistence!
* Resolves [GitHub Issue #1248](https://github.com/FusionAuth/fusionauth-issues/issues/1248), thanks to [@Brunom50](https://github.com/Brunom50) to documenting this limitation.
* Update the System Log viewer in the FusionAuth admin UI to order logs for easier viewing pleasure.
* Resolves [GitHub Issue #1612](https://github.com/FusionAuth/fusionauth-issues/issues/1612)
* Allow Forgot Password API usage when the Forgot Password Email template is not configured if `sendForgotPasswordEmail` is `false`.
* Resolves [GitHub Issue #1735](https://github.com/FusionAuth/fusionauth-issues/issues/1735), thanks to [@epbensimpson](https://github.com/epbensimpson) for the suggestion.
* Provide better developer feedback on the Change Password API when using an API key.
* Resolves [GitHub Issue #1897](https://github.com/FusionAuth/fusionauth-issues/issues/1897), thanks to [@sujkattimani](https://github.com/sujkattimani) for the feedback!
* Allow the SAML v2 IdP to be used for both SP and IdP initiated login. Previously to utilize SP and IdP initiated login for the same SAML v2 IdP, you would have to create two separate configurations. It is still recommended to use the separate SAML v2 IdP initiated configuration if you will not be using an SP initiated login.
* Resolves [GitHub Issue #1900](https://github.com/FusionAuth/fusionauth-issues/issues/1900), thanks to [@leesmith110](https://github.com/leesmith110) for opening the issue and providing us so much valuable feedback.
* Support for PostgreSQL 15
* Resolves [GitHub Issue #1944](https://github.com/FusionAuth/fusionauth-issues/issues/1944)
* Resolves [GitHub Issue #2015](https://github.com/FusionAuth/fusionauth-issues/issues/2015)
* Add an option to include archived logs in gzip format on the System Log Download API. This will be the default when downloading the logs in the FusionAuth admin UI.
* Resolves [GitHub Issue #1942](https://github.com/FusionAuth/fusionauth-issues/issues/1942)
* Allow the login hint that is passed to a 3rd Party SAML v2 IdP to be configured. Previously this was always `login_hint`, but Azure will expect `username`, this can now be configured.
* Resolves [GitHub Issue #1946](https://github.com/FusionAuth/fusionauth-issues/issues/1946)
* Add `sourceApplicationId` to the Application API to create an app from an existing Application to copy settings. This allows you to more easily use a single Application as a template, or to just make a copy.
* Resolves [GitHub Issue #1957](https://github.com/FusionAuth/fusionauth-issues/issues/1957)
* Ship default email templates for Add and Remove Multi-Factor methods.
* Resolves [GitHub Issue #1993](https://github.com/FusionAuth/fusionauth-issues/issues/1993)
* Add additional SAML IdP config to allow advanced assertion capabilities such as allow any destination, or alternate values. This is sort of a dangerous power user feature, but can be useful when migrating IdP configurations into FusionAuth w/out requiring each IdP to update their ACS.
* Resolves [GitHub Issue #1995](https://github.com/FusionAuth/fusionauth-issues/issues/1995)
* Add additional detail to the edit registration form in the FusionAuth admin UI so you know which user you are editing. Seemed like a good idea.
* Resolves [GitHub Issue #2045](https://github.com/FusionAuth/fusionauth-issues/issues/2045)
* Do not validate `Content-Type` when a payload has not been provided.
* Resolves [GitHub Issue #2085](https://github.com/FusionAuth/fusionauth-issues/issues/2085)
### New
* Support for wild cards in OAuth2 Authorized Origin and Authorized Redirect URL configurations. Use with caution - but have fun with it!
* Resolves [GitHub Issue #437](https://github.com/FusionAuth/fusionauth-issues/issues/437). This one has been a long time coming, and we really appreciate all of the feedback and suggestions on this issue. In chronological order, thank you to [@SeanStayn](https://github.com/SeanStayn), [@Jank1310](https://github.com/Jank1310), [@JuliusPC](https://github.com/JuliusPC), [@dystopiandev](https://github.com/dystopiandev), [@alessandrojcm](https://github.com/alessandrojcm), [@sjmog](https://github.com/sjmog), [@huysentruitw](https://github.com/huysentruitw) and [@mdnadm](https://github.com/mdnadm).
* Support for native TLS configuration in the FusionAuth HTTP server without the requirement to use a proxy with TLS termination.
* Resolves [GitHub Issue #1996](https://github.com/FusionAuth/fusionauth-issues/issues/1996)
* Add support for `salted-pbkdf2-hmac-sha512-512` password hash algorithm.
* See [Salted PBKDF2 HMAC SHA-512](/docs/reference/password-hashes#salted-pbkdf2-hmac-sha-512) for additional details.
* Resolves [GitHub Issue #2054](https://github.com/FusionAuth/fusionauth-issues/issues/2054)
### Fixed
* A regression error in version `1.42.0` may cause a user to no longer be able to login after a successful login. In order to encounter this bug, you must have your tenant configured to re-hash passwords on login, and have a user login when their password encryption scheme or factor that does not match the configured tenant defaults. If you may have this type of configuration, please do not upgrade to version `1.42.0` and instead upgrade directly to this version.
* Resolves [GitHub Issue #2043](https://github.com/FusionAuth/fusionauth-issues/issues/2043)
### Known Issues
* In this release, you may now create a policy to allow a user to unlock their account after too many failed login attempts by completing a forgot password workflow. A bug was identified in this new feature that may cause this workflow to fail if the user also has 2FA enabled.
* Resolved in `1.43.0` via [GitHub Issue #2032](https://github.com/FusionAuth/fusionauth-issues/issues/2032)
* An error was introduced that may, after one successful login, cause subsequent logins to fail for a user. In order to encounter this bug, you must have your tenant configured to re-hash passwords on login, and have a user login when their password encryption scheme or factor that does not match the configured tenant defaults. If you may have this type of configuration, please do not upgrade to version `1.42.0` and instead upgrade directly to version `1.42.1`.
* Resolved in `1.42.1` via [GitHub Issue #2043](https://github.com/FusionAuth/fusionauth-issues/issues/2043)
### Changed
* When building a WebAuthn credential, the user's current email address or username will now be used as the credential name. Previously this value was generated to be unique to help the user identify multiple credentials. However, Safari on macOS and Edge on Windows may display this value to the end user, so this will no longer be generated but set to a value the user should recognize.
* Resolves [GitHub Issue #1929](https://github.com/FusionAuth/fusionauth-issues/issues/1929)
* New themed templates for enabling two-factor authentication during login. Please review your themes to ensure the new templates and localized messages are added.
* `theme.templates.oauth2TwoFactorEnable -> /oauth2/two-factor-enable`
* `theme.templates.oauth2TwoFactorEnableComplete -> /oauth2/two-factor-enable-complete`
* Related [GitHub Issue #197](https://github.com/FusionAuth/fusionauth-issues/issues/197)
### Fixed
* Minor WebAuthn related fixes.
* Resolves [GitHub Issue #1979](https://github.com/FusionAuth/fusionauth-issues/issues/1979)
* Resolves [GitHub Issue #1986](https://github.com/FusionAuth/fusionauth-issues/issues/1986)
* When providing both the `entityId` and `userId` on the Entity Search API, an exception will occur.
* Resolves [GitHub Issue #1883](https://github.com/FusionAuth/fusionauth-issues/issues/1883)
* Remove SCIM endpoints from the API key configuration in the admin UI, these endpoints do not use API keys.
* Resolves [GitHub Issue #1987](https://github.com/FusionAuth/fusionauth-issues/issues/1987)
* Fix various rendering issues with the Theme preview in the admin UI
* Resolves [GitHub Issue #1755](https://github.com/FusionAuth/fusionauth-issues/issues/1755), thanks to [Steve-MP](https://github.com/Steve-MP) for reporting!
### Enhancements
* Allow a user to unlock their account after being locked due to too many failed authentication attempts by completing a password reset workflow. See the `Cancel action on password reset` in the Tenant configuration. `Tenants > Edit > Password > Failed authentication settings`.
* Resolves [GitHub Issue #383](https://github.com/FusionAuth/fusionauth-issues/issues/383), thanks [@colingm](https://github.com/colingm) for the request, and [@davidmw](https://github.com/davidmw) and [@Jlintonjr](https://github.com/Jlintonjr) for the advice and feedback!
* Use the existing tenant configuration for `modifyEncryptionSchemeOnLogin` to also update the hash when changed.
* Resolves [GitHub Issue #1062](https://github.com/FusionAuth/fusionauth-issues/issues/1062)
* Add additional configuration to the `Failed authentication settings` in the tenant configuration to optionally email the user when the configured action is also configured to allow emailing.
* Resolves [GitHub Issue #1823](https://github.com/FusionAuth/fusionauth-issues/issues/1823)
* Update the `System > About` panel in the admin UI to report OpenSearch when using OpenSearch instead of Elasticsearch.
* Resolves [GitHub Issue #1982](https://github.com/FusionAuth/fusionauth-issues/issues/1982)
### New
* Additional Multi-Factor policy option to require a user to enable multi-factor during login if not yet configured. See `Tenants > Edit > MFA > Policies > On login > Required.`. Application specific configuration can also be configured, see `Applications > Edit > MFA > Policies > On login > Required.`, using the application configuration requires an Enterprise plan.
* Resolves [GitHub Issue #197](https://github.com/FusionAuth/fusionauth-issues/issues/197)
* Allow refresh tokens to be revoked for a user when enabling two-factor authentication. See `Tenants > Edit > JWT > Refresh token settings > Refresh token revocation > On multi-factor enable`.
* Resolves [GitHub Issue #1794](https://github.com/FusionAuth/fusionauth-issues/issues/1794)
* A new lambda function can be assigned to perform custom validation for any step during a self-service registration. This feature is only available when using a custom form, and is not available when using basic self-service registration. This may be useful to perform advanced field validation, or to call a 3rd party API to perform additional identity verification.
* Resolves [GitHub Issue #1833](https://github.com/FusionAuth/fusionauth-issues/issues/1833)
### Security
* Mitigate a potential directory traversal attack. CloudFlare, AWS and similar cloud providers will generally block these requests by default.
* Please note, FusionAuth Cloud customers are not vulnerable to this type of attack.
### Fixed
* Allow licensed features such as SCIM or WebAuthn to be configured during kickstart.
* Resolves [GitHub Issue #1969](https://github.com/FusionAuth/fusionauth-issues/issues/1969)
### Security
* Remove the app template files from the classpath.
* Resolves [GitHub Issue #1964](https://github.com/FusionAuth/fusionauth-issues/issues/1964), thanks to [@vtcdanh](https://github.com/vtcdanh) for reporting.
### Fixed
* Improve synchronization of a user during a connector login. Specifically, allow previously obtained refresh tokens to be preserved during the user update procedures during a connector synchronization event.
* Resolves [GitHub Issue #1907](https://github.com/FusionAuth/fusionauth-issues/issues/1907), thanks to [@yuezhou1998](https://github.com/yuezhou1998) for letting us know.
* Allow for invalid language values to be provided in the `Accept-Language` HTTP request header. When an invalid language is provided, the `Accept-Language` header will be discarded.
* Resolves [GitHub Issue #1958](https://github.com/FusionAuth/fusionauth-issues/issues/1958)
* Better support for beginning a forgot password workflow using the API and completing the workflow in a themed page when a user also has 2FA enabled.
* Resolves [GitHub Issue #1965](https://github.com/FusionAuth/fusionauth-issues/issues/1965)
### Known Issues
* A change to the FusionAuth HTTP server may cause issues with reverse proxies that default upstream connections to `HTTP/1.0`. The HTTP server we are using no longer supports `HTTP/1.0`. We have identified that `nginx` defaults all upstream connections to `HTTP/1.0`, and the HTTP server we are using no longer supports `HTTP/1.0`. For `nginx` specifically, you will need to set the proxy version by adding `proxy_http_version 1.1;` to your proxy config.
### Security
* Update `com.fasterxml.jackson.*` dependencies to version `2.14.0`. This update is proactive, there are no known exploits. See [CVE-2022-42003](https://nvd.nist.gov/vuln/detail/CVE-2022-42003) and [CVE-2022-42004](https://nvd.nist.gov/vuln/detail/CVE-2022-42004).
* Resolves [GitHub Issue #1913](https://github.com/FusionAuth/fusionauth-issues/issues/1913)
### Changed
* New themed pages added for WebAuthn. Please review your themes to ensure the new templates and localized messages are added.
* See the [Theme](/docs/apis/themes) API and the [Theme](/docs/customize/look-and-feel/) documentation for additional details. Review the [Upgrading](/docs/customize/look-and-feel/advanced-theme-editor#upgrading) section for information on how to resolve potential breaking changes.
* WebAuthn re-authentication requires a new hidden form field named `userVerifyingPlatformAuthenticatorAvailable` to detect compatible devices/browsers and prompt the user to register a passkey. You can view the default templates to determine in which form to insert this field into any customized templates. This field must be present on the following pages:
* OAuth authorize
* OAuth complete registration
* OAuth passwordless
* OAuth register
* OAuth two-factor
* OAuth WebAuthn (new)
### Fixed
* Correct signature verification of a SAML v2 AuthN response after the certificate has been removed from Key Master.
* Resolves [GitHub #1906](https://github.com/FusionAuth/fusionauth-issues/issues/1906)
* An exception may be thrown when there are no keys to be returned from the `/api/jwt/public-key` when requesting keys by an `applicationId`.
* Resolves [GitHub Issue #1918](https://github.com/FusionAuth/fusionauth-issues/issues/1918)
* When using Firefox, using the SSO logout a zero byte file may be downloaded.
* Resolves [GitHub Issue #1934](https://github.com/FusionAuth/fusionauth-issues/issues/1934)
* When multiple webhooks are configured, and more than one webhook is configured to receive the `event-log.create` event, a failed webhook may cause an event loop.
* Resolves [GitHub Issue #1945](https://github.com/FusionAuth/fusionauth-issues/issues/1945)
* Correct deserialization of the `userType` and `title` fields in a SCIM resource.
* Resolves [GitHub Issue #1954](https://github.com/FusionAuth/fusionauth-issues/issues/1954)
### Enhancements
* Support passing the Assertion Consumer Service (ACS) in the `RelayState` query parameter.
* Resolves [GitHub Issue #1785](https://github.com/FusionAuth/fusionauth-issues/issues/1785)
* Support using an `appId` and `sessionTicket` to complete login with the Steam Identity Provider.
* Resolves [GitHub Issue #1873](https://github.com/FusionAuth/fusionauth-issues/issues/1873)
* Add back support for some legacy HTTP Servlet Request methods for use in themed templates.
* Resolves [GitHub Issue #1904](https://github.com/FusionAuth/fusionauth-issues/issues/1904)
### New
* WebAuthn! Passkeys, Touch ID, Face ID, Android fingerprint, Windows Hello!
* Resolves [GitHub Issue #77](https://github.com/FusionAuth/fusionauth-issues/issues/77)
* Allow users to be provisioned into the FusionAuth app using an IdP
* Resolves [GitHub Issue #1915](https://github.com/FusionAuth/fusionauth-issues/issues/1915)
* Allow FusionAuth to initiate a SAML v2 login request to a SAML v2 Service Provider.
* Resolves [GitHub Issue #1927](https://github.com/FusionAuth/fusionauth-issues/issues/1927)
### Internal
* Update the docker image to `ubuntu:jammy`.
* Resolves [GitHub Issue #1936](https://github.com/FusionAuth/fusionauth-issues/issues/1936)
* New HTTP server
### Fixed
* A two-factor trust may expire early causing a user to be prompted to complete two-factor during login. This issue was introduced in version `1.37.0`.
* Resolves [GitHub Issue #1905](https://github.com/FusionAuth/fusionauth-issues/issues/1905)
### Fixed
* A SAML v2 IdP Initiated login request will fail if PKCE is configured as required.
* Resolves [GitHub Issue #1800](https://github.com/FusionAuth/fusionauth-issues/issues/1800)
* The path attribute in some cookies may be set to the request path instead of `/` which may affect a SAML v2 IdP initiated login request.
* Resolves [GitHub Issue #1891](https://github.com/FusionAuth/fusionauth-issues/issues/1891)
### Enhancements
* Support `Content-Type` in Kickstart when using `PATCH` request to support `application/json-patch+json` and `application/merge-patch+json`.
* Resolves [GitHub Issue #1885](https://github.com/FusionAuth/fusionauth-issues/issues/1885)
* Remove un-necessary logging when the `Content-Type` request header is invalid or unset.
* Resolves [GitHub Issue #1895](https://github.com/FusionAuth/fusionauth-issues/issues/1895)
### Changed
* If you are using MySQL or plan to use MySQL you will need to manually download the JDBC connector to allow FusionAuth to connect to a MySQL database. If you are using PostgreSQL, this change will not affect you. See the installation guide for additional information. We apologize in advance for the inconvenience this causes you, but the Oracle GPL licensing model makes it difficult for FusionAuth to easily delivery this capability.
* Resolves [GitHub Issue #1862](https://github.com/FusionAuth/fusionauth-issues/issues/1862)
### Fixed
* An exception may occur when you attempt to perform a `PATCH` request on a Group using a `roleId` that does not exist.
* Resolves [GitHub Issue #1872](https://github.com/FusionAuth/fusionauth-issues/issues/1872)
* URL escape the `identityProviderUser` in the admin UI to correctly build the View and Delete actions links.
* Resolves [GitHub Issue #1882](https://github.com/FusionAuth/fusionauth-issues/issues/1882), thanks to one of our MVPs [@epbensimpson](https://github.com/epbensimpson) for letting us know and providing excellent recreation steps.
### Enhancements
* Support changes to `user.active` for `PUT` or `PATCH` on the SCIM User or Enterprise User endpoints.
* Resolves [GitHub Issue #1871](https://github.com/FusionAuth/fusionauth-issues/issues/1871)
* Performance improvement for SAML v2 request parsing.
* [GitHub Issue #1884](https://github.com/FusionAuth/fusionauth-issues/issues/1884)
### New
* Native Windows support has been re-instated. We apologize for the gap in native Windows support, for those who have been waiting to upgrade since version `1.37.0` you may now upgrade with a native installer. Thank you for all of you who have voiced your opinions with how we are support a native Windows installation.
* Resolves [GitHub Issue #1848](https://github.com/FusionAuth/fusionauth-issues/issues/1848)
### Fixed
* When appending the `locale` request parameter on the Authorize request to pre-select the user's locale, the locale may still be incorrect for validation errors. For example, appending `locale=fr` will allow the initial render of the page to be localized in French when available. However, because the user did not manually modify the locale selector on the page, if the login fails due to a validation error, the error messages will be returned in the default locale which is generally English.
* Resolves [GitHub Issue #1713](https://github.com/FusionAuth/fusionauth-issues/issues/1713)
* Group application roles removed during a `PATCH` request to the Group API.
* Resolves [GitHub Issue #1717](https://github.com/FusionAuth/fusionauth-issues/issues/1717), thank you to [@paul-fink-silvacom](https://github.com/paul-fink-silvacom) for raising the issue!
* Corrections to the SAML v2 SP and IdP meta data.
* The HTTP scheme was missing from the `entityID`. This issue was introduced in version `1.37.0`.
* The `NameIdFormat` found in the SP meta data was always showing `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` regardless of the value configured in the SAML v2 IdP.
* Resolves [GitHub Issue #1842](https://github.com/FusionAuth/fusionauth-issues/issues/1842)
* The potential exists to see an exception in the FusionAuth system logs when the internal login record service runs. It is unlikely you will experience this error unless you have very large login volumes.
* Resolves [GitHub Issue #1854](https://github.com/FusionAuth/fusionauth-issues/issues/1854)
* There is the potential for the Elasticsearch index to become out of sync with respect to group memberships when groups are being deleted, or group members are being deleted from a group.
* Resolves [GitHub Issue #1855](https://github.com/FusionAuth/fusionauth-issues/issues/1855)
* Add missing support for `en_GB` time and data format support in the FusionAuth admin UI when setting your preferred locale to `en_GB`.
* Resolves [GitHub Issue #1858](https://github.com/FusionAuth/fusionauth-issues/issues/1858), thanks to [@adambowen](https://github.com/adambowen) for bringing this to our attention. It wasn't our intention to force our friends in the United Kingdom 🇬🇧 to painfully read dates and times in the American 🇺🇸 format. Please accept our apologies. 😎
### Enhancements
* Better support for JSON Patch. Now supporting RFC 7386 `application/merge-patch+json` and RFC 6902 `application/json-patch+json`. Note that you may still make a request using the `PATCH` HTTP method using `application/json` and the current behavior should not be changed. All `patch*` methods found in the FusionAuth client libraries will still be using `application/json` for backwards compatibility. However, now that support for these new content types exists, we will be working to build support into our client libraries.
* Resolves [GitHub Issue #441](https://github.com/FusionAuth/fusionauth-issues/issues/441)
* Better developer feedback when the `Content-Type` request header is missing or incorrect.
* Resolves [GitHub Issue #604](https://github.com/FusionAuth/fusionauth-issues/issues/604)
* Additional SCIM support for the `PATCH` HTTP request method, and `filter` and `excludedAttributes` request attributes. The addition of these features allow the FusionAuth SCIM server to be compatible with Azure AD SCIM client and Okta SCIM client. The Group filter support has some limitations, see the [SCIM Group](/docs/apis/scim/scim-group#retrieve-a-group) API doc for additional details.
* Resolves [GitHub Issue #1761](https://github.com/FusionAuth/fusionauth-issues/issues/1761)
* Resolves [GitHub Issue #1791](https://github.com/FusionAuth/fusionauth-issues/issues/1791)
* Add some missing message keys to default Theme message bundle.
* Resolves [GitHub Issue #1839](https://github.com/FusionAuth/fusionauth-issues/issues/1839)
* Remove an un-necessary db request when validating the user security scheme for a user in the FusionAuth admin UI.
* Resolves [GitHub Issue #1856](https://github.com/FusionAuth/fusionauth-issues/issues/1856)
### Fixed
* Static resources such as CSS and JS may be missing a `Content-Type` header which may cause a proxy using `X-Content-Type-Options: nosniff` to fail to load the resource. This issue was introduced in version `1.37.0`.
* Resolves [GitHub Issue #1831](https://github.com/FusionAuth/fusionauth-issues/issues/1831), thanks to [@sinqinc](https://github.com/sinqinc) for reporting.
* Resolves [GitHub Issue #1834](https://github.com/FusionAuth/fusionauth-issues/issues/1834), thanks to [@Aaron-Ritter](https://github.com/Aaron-Ritter) for reporting.
* Fix a potential error issue caused by a webhook handler calling back to FusionAuth which may trigger another webhook event. This fix should also improve the performance when sending many events for webhooks.
* Resolves [GitHub Issue #1836](https://github.com/FusionAuth/fusionauth-issues/issues/1836)
* Correct behavior during login when both self-service registration and require registration features are enabled. This configuration may cause a user to be directed to the registration required page during login instead of being registered automatically. If you encounter this error, you may either upgrade or disable the require registration configuration. This appears to be a regression introduced in version `1.36.5`.
* Resolves [GitHub Issue #1837](https://github.com/FusionAuth/fusionauth-issues/issues/1837)
### Fixed
* Remove dead Tomcat files from Docker image
* Resolves [GitHub Issue #1820](https://github.com/FusionAuth/fusionauth-issues/issues/1820), thanks to [@kevcube](https://github.com/kevcube) for letting us know!
### New
* Group and Group Membership Webhooks
* Resolves [GitHub Issue #633](https://github.com/FusionAuth/fusionauth-issues/issues/633), thanks to [@JLyne](https://github.com/JLyne), [@ric-sapasap](https://github.com/ric-sapasap) and [@rabshire](https://github.com/rabshire) for the feedback!
* Resolves [GitHub Issue #1803](https://github.com/FusionAuth/fusionauth-issues/issues/1803), thanks to [@matthew-jump](https://github.com/matthew-jump) for making the request.
### Fixed
* A regression error was introduced in version `1.37.0` that causes HTTP request headers to be malformed when being sent to a Webhook, Generic Messenger or a Generic Connector.
* Resolves [GitHub Issue #1818](https://github.com/FusionAuth/fusionauth-issues/issues/1818)
### Enhancements
* In version `1.37.0` you may now create a user in the FusionAuth admin UI optionally performing email verification. The UI controls and messaging have been enhanced to remove potential confusion.
* Resolves [GitHub Issue #1819](https://github.com/FusionAuth/fusionauth-issues/issues/1819)
### Fixed
* An exception may occur while trying to capture the debug log event during an authentication request using a Connector.
* Resolves [GitHub Issue #1799](https://github.com/FusionAuth/fusionauth-issues/issues/1799)
* When configuring a User Action to prevent login and using that event with the Failed Login configuration, if you configure the User Action to email the user, the email will not be sent.
* Resolves [GitHub Issue #1801](https://github.com/FusionAuth/fusionauth-issues/issues/1801)
* Kickstart fails because it does not wait for FusionAuth to complete startup.
* Resolves [GitHub Issue #1816](https://github.com/FusionAuth/fusionauth-issues/issues/1816)
* Creating an application in the FusionAuth admin UI may fail due to a licensing error if you do not have an Enterprise license.
* Resolves [GitHub Issue #1817](https://github.com/FusionAuth/fusionauth-issues/issues/1817)
### Known Issues
* Kickstart fails because it does not wait for FusionAuth to complete startup.
* Resolved in version `1.37.1` via [GitHub Issue #1816](https://github.com/FusionAuth/fusionauth-issues/issues/1816)
* Creating an application in the FusionAuth admin UI may fail due to a licensing error if you do not have an Enterprise license.
* Resolved in version `1.37.1` via [GitHub Issue #1817](https://github.com/FusionAuth/fusionauth-issues/issues/1817)
* A regression error was introduced in version `1.37.0` that causes HTTP request headers to be malformed when being sent to a Webhook, Generic Messenger or a Generic Connector.
* Resolved in version `1.37.2` via [GitHub Issue #1818](https://github.com/FusionAuth/fusionauth-issues/issues/1818)
* Static resources such as CSS and JS may be missing a `Content-Type` header which may cause a proxy using `X-Content-Type-Options: nosniff` to fail to load the resource.
* Resolved in version `1.38.1` via [GitHub Issue #1831](https://github.com/FusionAuth/fusionauth-issues/issues/1831)
* A two-factor trust may expire early causing a user to be prompted to complete two-factor during login.
* Resolved in version `1.40.2` via [GitHub Issue #1905](https://github.com/FusionAuth/fusionauth-issues/issues/1905)
* A theme issue may exist on a form action and may cause breaking changes when upgrading to this version.
* If you are upgrading, please verify your theme files accurately create a form action. The following themes should be updated as follows:
* OAuth authorize -> `action="/oauth2/authorize"`
* Child registration not allowed -> `action="/oauth2/child-registration-not-allowed"`
* OAuth passwordless -> `action="/oauth2/passwordless"`
* OAuth register -> `action="/oauth2/register"`
* OAuth two factor -> `action="/oauth2/two-factor"`
* Change password form -> `action="/password/change"`
* Forgot password -> `action="/password/forgot"`
### Security
* Allow deprecated XML signature algorithms that were removed in Java 17. It is still not recommended that you use any of these legacy SHA1 algorithms, but if you are unable to utilize a modern algorithm, they will be allowed.
* Resolves [GitHub Issue #1814](https://github.com/FusionAuth/fusionauth-issues/issues/1814)
### Changed
* Windows install has been removed. Our strategy is to support Windows using [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/about) with our provided Debian package. Please plan to utilize this strategy, and open a GitHub issue if you encounter issues with the installation.
* Due to customer feedback, a native Windows installation option has been restored as of version `1.40.0`.
* Webhooks are no longer configured as "All applications" or limited to a single Application. They are now scoped to one or more tenants. If you previously had multiple webhooks configured within the same tenant, but scoped to separate Applications you will want to review your configuration and filter events in your own Webhook handler by the `applicationId`.
* Resolves [GitHub Issue #1812](https://github.com/FusionAuth/fusionauth-issues/issues/1812)
* Deprecate Apache Tomcat specific configuration. See the [Configuration](/docs/reference/configuration) reference for additional detail.
* `fusionauth-app.http.max-header-size` The default maximum size is now `64k`.
* `fusionauth-app.http.cookie-same-site-policy` In most cases, cookies will be written using `SameSite=Lax`, and cookies used by the FusionAuth admin UI utilize `SameSite=Strict`. If you think there would be value in further customizing cookies by name, or security settings such as `SameSite`, please upvote [GitHub Issue #1414](https://github.com/FusionAuth/fusionauth-issues/issues/1414) and describe your intended use-case.
* `fusionauth-app.management.port` This was an Apache Tomcat specific port that is no longer required.
* `fusionauth-app.ajp.port` is now deprecated, this was an Apache Tomcat specific binary protocol used by Java applications.
* `fusionauth-app.http.relaxed-path-chars` This option was not likely documented or in-use by anyone.
* `fusionauth-app.http.relaxed-query-chars` This option was not likely documented or in-use by anyone.
* FastPath and normal startup commands have changed. For example, starting FusionAuth based upon Apache Tomcat used `catalina.sh` or `catalina.bat`, the startup process will now use `start.sh`. See install documentation for more details.
* When using the FusionAuth Docker image with MySQL, you will need to bundle the MySQL connector jar in the image, or add a layer to the stock FusionAuth image to ensure that `curl` is installed so that the MySQL connector jar can be downloaded it during startup. It is recommended that you build the connector into the image. See our example [Dockerfile](https://github.com/FusionAuth/fusionauth-containers/tree/main/docker/fusionauth/fusionauth-app-mysql) on GitHub for an example.
### Fixed
* Add the appropriate feedback to the users when attempting to change an email during a gated email verification that is already in-use.
* Resolves [GitHub Issue #1547](https://github.com/FusionAuth/fusionauth-issues/issues/1547)
* Correct the validation when deleting a key from Key Master when in use by a de-activated application.
* Resolves [GitHub Issue #1676](https://github.com/FusionAuth/fusionauth-issues/issues/1676)
* Perform implicit email verification when enabled and a setup password email request is completed.
* Resolves [GitHub Issue #1705](https://github.com/FusionAuth/fusionauth-issues/issues/1705)
* Handle URL encoded characters in the user-information part of the URL when connecting to Elasticsearch. This allows a username or password to be provided in the URL that have been URL encoded.
* Resolves [GitHub Issue #1745](https://github.com/FusionAuth/fusionauth-issues/issues/1745)
* When using the Change Password workflow in the hosted login pages for a user that has enabled 2FA, if you are not adding the OAuth2 parameters found in the `state` on the Change Password link built in the email template an error may occur when the user tries to complete the workflow.
* Resolves [GitHub Issue #1764](https://github.com/FusionAuth/fusionauth-issues/issues/1764)
* The Refresh Token retrieve API and the Session tab in admin UI will no longer show expired refresh tokens. While the previous behavior was working as designed, it was confusing to some clients, and an admin was not able to manually remove expired tokens.
* Resolves [GitHub Issue #1772](https://github.com/FusionAuth/fusionauth-issues/issues/1772)
* Fix Lambda JS validation when using ES6 features with the GraalJS engine.
* Resolves [GitHub Issue #1790](https://github.com/FusionAuth/fusionauth-issues/issues/1790), thanks to [@theogravity](https://github.com/theogravity) for reporting the issue!
### Enhancements
* Administrative Email Verification using the API or FusionAuth admin UI. When creating a user in the admin UI, you may now optionally create the user with an un-verified email when Email verification is enabled. See the [Verify Email](/docs/apis/users#verify-a-users-email) API for additional details.
* Resolves [GitHub Issue #1319](https://github.com/FusionAuth/fusionauth-issues/issues/1319)
* The Oauth2 Logout does not log a user out of FusionAuth app if logging out of another application in the same default tenant.
* Resolves [GitHub Issue #1699](https://github.com/FusionAuth/fusionauth-issues/issues/1699)
* Updates to our initial SCIM Server implementation released in version `1.36.0`.
* Resolves [GitHub Issue #1702](https://github.com/FusionAuth/fusionauth-issues/issues/1702)
* Resolves [GitHub Issue #1703](https://github.com/FusionAuth/fusionauth-issues/issues/1703)
* Better options to capture debug information when troubleshooting an SMTP connection issue. You no longer need to specify `mail.debug=true` in the advanced SMTP settings, and instead when enabling `debug` on the SMTP configuration a debug Event Log will be produced with the SMTP debug information.
* Resolves [GitHub Issue #1743](https://github.com/FusionAuth/fusionauth-issues/issues/1743)
* Support larger email templates on MySQL. Prior to this version the `TEXT` column data type was utilized which has a maximum size of `16k` in MySQL, now we are using `MEDIUMTEXT` which supports up to `16M`.
* Resolves [GitHub #1788](https://github.com/FusionAuth/fusionauth-issues/issues/1788), thanks to [@darkeagle1337](https://github.com/darkeagle1337) for making the request!
* Improvements to the OAuth2 Logout endpoint. This endpoint now correctly supports the `POST` method in addition to the `GET` method, and you may now use an expired `id_token` in the `id_token_hint` parameter.
* Resolves [GitHub Issue #1792](https://github.com/FusionAuth/fusionauth-issues/issues/1792)
* Webhooks are now scoped to one or more tenants. Webhooks will no longer receive all events, but only events for the configured tenants. There is still an option for "All tenants" if you still wish to preserve the previous behavior.
* Resolves [GitHub Issue #1812](https://github.com/FusionAuth/fusionauth-issues/issues/1812)
* Any API response that returns a Refresh Token will now also return a `refresh_token_id` when in OAuth2 or a `refreshTokenId` in all other APIs. This may be useful to identify a refresh token for revocation when using a one-time use Refresh Token. This identifier is the primary key of the Refresh Token and can be used by the Refresh Token API.
* The Access Token will contain a new claim named `sid` which is the immutable identifier Refresh Token. This claim is not reserved, so it can be removed and will only be present when a refresh token is requested. This is different from the `sid` claim that is already returned in the `id_token`, that `sid` or Session Identifier is the SSO session identifier and is primarily used by FusionAuth to validate a logout request.
* When available the Refresh Token is now returned in the `JWTRefreshTokenRevokeEvent` event in the `refreshToken` field.
* The Login Ping API may now optionally take the request as a POST body.
### New
* Application scoped Multi-Factor authentication. This feature allows an application choose to participate in Multi-Factor when enabled, and optionally specify a separate TTL for trust scoped to a single application.
* Resolves [GitHub Issue #763](https://github.com/FusionAuth/fusionauth-issues/issues/763)
* You may optionally disable the IdP linking strategy for an Identity Provider. This allows you to restrict any automatic linking and manage all IdP linking through the API.
* Resolves [GitHub Issue #1551](https://github.com/FusionAuth/fusionauth-issues/issues/1551), thanks to [@epbensimpson](https://github.com/epbensimpson) for the suggestion.
* Added `fusionauth-app.http.read-timeout` to the configuration to optionally set the maximum read timeout when making requests to FusionAuth. See the [Configuration](/docs/reference/configuration) reference for additional detail.
### Internal
* Remove Apache Tomcat as the underlying application server, in favor of a more modern HTTP server based upon Netty.
* Resolves [GitHub Issue #1671](https://github.com/FusionAuth/fusionauth-issues/issues/1671)
### Fixed
* Fix the placeholder text in the entity grants search field.
* Resolves [GitHub Issue #1774](https://github.com/FusionAuth/fusionauth-issues/issues/1774)
* Correct the SCIM HTTP response code when a new resource is created to be `201`.
* Resolves [GitHub Issue #1775](https://github.com/FusionAuth/fusionauth-issues/issues/1775)
* Correct the SCIM HTTP response code when a duplicate resource is attempted to be created to be `409`.
* Resolves [GitHub Issue #1776](https://github.com/FusionAuth/fusionauth-issues/issues/1776)
### Security
* Ensure the provided `client_id` matches the Application represented by the Refresh Token when performing a Refresh grant. This is marked as a security fix because the intended design is to ensure the Refresh Token does indeed match the requested `client_id`. However, the risk is minimal due to the caller still being required to have a valid set of client credentials, and must still present a valid refresh token.
* Resolves [GitHub Issue #1766](https://github.com/FusionAuth/fusionauth-issues/issues/1766) Thanks to [@gnarlium](https://github.com/gnarlium) for reporting the issue!
### Fixed
* The initial "start" phase of a user action triggered by a failed login configuration is not sent.
* Resolves [GitHub Issue #1654](https://github.com/FusionAuth/fusionauth-issues/issues/1654)
* When a SAML v2 SP is using an HTTP redirect binding during the Logout request FusionAuth make fail to complete the logout request.
* Resolves [GitHub Issue #1723](https://github.com/FusionAuth/fusionauth-issues/issues/1723)
* A timing issue exists where under load of creating logins and then deleting applications programatically, a login record for a now deleted application may get stuck in the queue causing exceptions when attempting to write the record to the database.
* Resolves [GitHub Issue #1765](https://github.com/FusionAuth/fusionauth-issues/issues/1765)
* Correct the `Content-Type` HTTP response header returned from the SCIM endpoints.
* Resolves [GitHub Issue #1769](https://github.com/FusionAuth/fusionauth-issues/issues/1769)
### Fixed
* When using Rate Limiting for Failed logins, the user may be able to login successfully after being rate limited - but prior to the end of the configured time period.
* Resolves [GitHub Issue #1758](https://github.com/FusionAuth/fusionauth-issues/issues/1758)
* When using a JWT Populate lambda and modifying the default value of the `aud` claim to be an array instead of a string value, this token can no longer be used by the Introspect endpoint. This fix allows you to modify the `aud` claim to be an array, and it may be used with the Introspect endpoint as long as the requested `client_id` is contained in the `aud` claim. The OAuth2 Logout endpoint was also updated to allow this same `aud` modification to be using an `id_token` as the `id_token_hint`. When using this style of token as an `id_token_hint`, the first value in the `aud` claim that is equal to a FusionAuth application Id will be utilized.
* Resolves [GitHub Issue #1759](https://github.com/FusionAuth/fusionauth-issues/issues/1759)
### Security
* Upgrade Java to get the patch for [CVE-2022-21449](https://nvd.nist.gov/vuln/detail/CVE-2022-21449). Note that in version `1.36.4` FusionAuth manually patched this vulnerability. To ensure you are not vulnerable to this vulnerability, upgrade to FusionAuth version `1.36.4` or later, or discontinue use of the Elliptic Curve algorithm.
* Resolves [GitHub Issue #1672](https://github.com/FusionAuth/fusionauth-issues/issues/1672)
* Fix validation of the Oauth2 Logout endpoint when using the `post_logout_redirect` parameter. As [documented here](/docs/lifecycle/authenticate-users/oauth/endpoints#logout), you must ensure that any value for this parameter is in the Authorized URLs list for the application. This may be a breaking change if you do not.
* Resolves [GitHub Issue #1750](https://github.com/FusionAuth/fusionauth-issues/issues/1750)
### Fixed
* Fix a UI bug that caused the application column to show "Single sign-on" instead of the Application name in the Session tab of the user management panel.
* Resolves [GitHub Issue #1706](https://github.com/FusionAuth/fusionauth-issues/issues/1706)
* If you have enabled Two-Factor authentication and self-service registration, a user may not be routed to the Complete Registration step correctly after completing the Two-Factor challenge.
* Resolves [GitHub Issue #1708](https://github.com/FusionAuth/fusionauth-issues/issues/1708), thanks to [@chimericdream](https://github.com/chimericdream) for reporting the issue!
* The `displayName` property on the [Link a User](/docs/apis/identity-providers/links#link-a-user) API is ignored. This is a regression bug that was introduced in version `1.36.0`.
* Resolves [GitHub Issue #1728](https://github.com/FusionAuth/fusionauth-issues/issues/1728)
* A 3rd party Web Application Firewall such as CloudFlare may inject JavaScript into the `head` element and this may cause a failure to properly initialize support for an Identity Provider such as Twitter.
* Resolves [GitHub Issue #1731](https://github.com/FusionAuth/fusionauth-issues/issues/1731), thanks to [@atakane](https://github.com/atakane) for helping us track this one down!
### Internal
* Upgrade to the latest Java 17 LTS. Upgraded from 17.0.1+12 to 17.0.3+7.
* Resolves [GitHub Issue #1672](https://github.com/FusionAuth/fusionauth-issues/issues/1672)
### Security
* Proactive patch for Java [CVE-2022-21449](https://nvd.nist.gov/vuln/detail/CVE-2022-21449). This release will patch the vulnerability described in the referenced CVE until we are able to release a version of FusionAuth using the upcoming patched release of Java. If you are not able to upgrade to this release, discontinue use of ECDSA keys in FusionAuth for JWT or SAML signing.
* Resolves [GitHub Issue #1694](https://github.com/FusionAuth/fusionauth-issues/issues/1694)
### Fixed
* An additional edge case was identified in the issue resolved by [GitHub Issue #1687](https://github.com/FusionAuth/fusionauth-issues/issues/1687). If you did encounter the issue resolved by [GitHub Issue #1687](https://github.com/FusionAuth/fusionauth-issues/issues/1687), you should plan to upgrade to this patch version so that you can fully utilize the new `auth_time` claim introduced in `1.36.0`.
* Resolves [GitHub Issue #1688](https://github.com/FusionAuth/fusionauth-issues/issues/1688)
### Fixed
* If you are using the `openid` scope which produces an `id_token`, and you utilize a 3rd party library that consumes the `id_token` to validate the signature, expiration or similar claims, the token may be incorrectly identified as expired. This is because after a refresh token is used to generate a new `id_token` the `auth_time` claim may have lost precision from the original value in the initial `id_token`.
* Resolves [GitHub Issue #1687](https://github.com/FusionAuth/fusionauth-issues/issues/1687)
### Fixed
* When building an entity grant in the UI for a user or other entity, the search results may contain entities from all tenants. If you attempt to select an entity in a tenant other than the tenant for which the user or entity belongs, an exception will occur.
* Resolves [GitHub Issue #1579](https://github.com/FusionAuth/fusionauth-issues/issues/1579)
* If you create an empty directory in the FusionAuth plugin directory, or create a directory that does not contain any FusionAuth plugin jars, and have other plugin jars in the root of the plugin directory, the legitimate plugin jar may not be loaded. If you encounter this problem, either remove the empty directories, or make the empty directories read only.
* Resolves [GitHub Issue #1683](https://github.com/FusionAuth/fusionauth-issues/issues/1683)
* If you are using the Client Credentials Grant and omit the permissions from the `target-entity:` scope, the expected permissions will not be returned as part of the access token claims.
* Resolves [GitHub Issue #1686](https://github.com/FusionAuth/fusionauth-issues/issues/1686)
### Known Issues
* If you create an empty directory in the FusionAuth plugin directory, or create a directory that does not contain any FusionAuth plugin jars, and have other plugin jars in the root of the plugin directory, the legitimate plugin jar may not be loaded. If you encounter this problem, either remove the empty directories, or make the empty directories read only.
* This has been resolved in version `1.36.1`.
* If you are using the Client Credentials Grant and omit the permissions from the `target-entity:` scope, the expected permissions will not be returned as part of the access token claims.
* This has been resolved in version `1.36.1`.
* If you are using the `openid` scope which produces an `id_token`, and you utilize a 3rd party library that consumes the `id_token` to validate the signature, expiration or similar claims, the token may be incorrectly identified as expired. This is because after a refresh token is used to generate a new `id_token` the `auth_time` claim may have lost precision from the original value in the initial `id_token`.
* This has been resolved in version `1.36.3`.
### Security
* Ensure that the Change Password identifier is revoked if an API is used to change a user's password after the user has initiated a change password request.
* Resolves [GitHub Issue #1632](https://github.com/FusionAuth/fusionauth-issues/issues/1632)
### Changed
* The JWT authorization method is no longer supported when using the `GET` method on the [Retrieve Refresh Tokens](/docs/apis/jwt#retrieve-refresh-tokens) API.
* The reason for this potentially breaking change is due to concern of potential abuse. If you were previously using a JWT to authorize the request to the `GET` HTTP method, you will need to modify your integration to utilize an API key. See the [Retrieve Refresh Tokens](/docs/apis/jwt#retrieve-refresh-tokens) API for additional details.
* Resolves [GitHub Issue #1646](https://github.com/FusionAuth/fusionauth-issues/issues/1646)
* Updated reserved JWT claims by grant type. The `amr` claims is marked as reserved, and will be available in a future release.
* Reserved for authorization code and implicit grant, `amr`, `exp`, `iat`, `sub` and `tid`. Only `amr` and `tid` are new for this release.
* Reserved for Vending API `amr`, `exp` and `iat`. Only the `amr` claim is new for this release.
* Reserved for Client Credentials grant, `amr`, `aud`, `exp`, `iat`, `permissions`, `sub` and `tid`.
* Resolves [GitHub Issue #1669](https://github.com/FusionAuth/fusionauth-issues/issues/1669)
### Fixed
* The requested `AssertionConsumerServiceURL` in a SAML v2 `AuthNRequest` is ignored and the first URL configured is used instead.
* Resolves [GitHub Issue #1278](https://github.com/FusionAuth/fusionauth-issues/issues/1278), thanks to [@pakomp](https://github.com/pakomp) for letting us know!
* Entities don't support the use of `:` in the permission name, this limitation has been removed.
* Resolves [GitHub Issue #1480](https://github.com/FusionAuth/fusionauth-issues/issues/1480), thanks to [@matthewhartstonge](https://github.com/matthewhartstonge) for the help!
* An application role may not be immediately available to assign to a user after initial creation. This issue was due to some additional caching introduced in version `1.32.1`.
* Resolves [GitHub Issue #1575](https://github.com/FusionAuth/fusionauth-issues/issues/1575)
* The Password Grant response is missing the Two Factor Method Ids when a Two-Factor challenge is required. This issue was introduced in version `1.26.0` when Two-Factor Method Ids were added to the Login API response.
* Resolves [GitHub Issue #1585](https://github.com/FusionAuth/fusionauth-issues/issues/1585)
* The Tenant edit and add panel displays Webhook events that are not configured at the Tenant level.
* Resolves [GitHub Issue #1593](https://github.com/FusionAuth/fusionauth-issues/issues/1593)
* FusionAuth may fail to start on Windows when using the `startup.bat` script. See linked issue for a workaround.
* Resolves [GitHub Issue #1624](https://github.com/FusionAuth/fusionauth-issues/issues/1624), thanks to [@James-M-Oswald](https://github.com/James-M-Oswald) for the assist!
* Enhance email validation to keep obviously incorrect emails from being used during self-service user registration.
* Resolves [GitHub Issue #1625](https://github.com/FusionAuth/fusionauth-issues/issues/1625), thanks to [@pablomadrigal](https://github.com/pablomadrigal) for letting us know!
* When using the GraalJS Lambda engine, you cannot use ECMA 6 features such as `const` or `let`.
* This only affects version `1.35.0` when using the new GraalJS engine, and does not represent a regression because prior to version `1.35.0` the only Lambda engine available was Nashorn which only supported ECMA 5.1.
* Resolves [GitHub Issue #1630](https://github.com/FusionAuth/fusionauth-issues/issues/1630)
* When using a Connector, a timing issue exists that could cause a login to fail. See the linked issue for an example exception that you may observe if you encounter this issue.
* Resolves [GitHub Issue #1633](https://github.com/FusionAuth/fusionauth-issues/issues/1633)
* The Tenant View dialog may show the incorrect Event transaction setting for a Tenant created via the API.
* Resolves [GitHub Issue #1642](https://github.com/FusionAuth/fusionauth-issues/issues/1642)
* When the `openid` scope is used along with the `offline_access` scope and then the resulting refresh token is used in a Refresh grant, the returned `id_token` may be signed with the key configured for the `access_token`.
* Resolves [GitHub Issue #1643](https://github.com/FusionAuth/fusionauth-issues/issues/1643)
* Ignore read-only directories inside of the configured plugin directory instead of throwing an exception.
* Resolves [GitHub Issue #1655](https://github.com/FusionAuth/fusionauth-issues/issues/1655)
### Enhancements
* Add a separate execute thread pool in the Apache Tomcat configuration to separate incoming requests from localhost callback requests to reduce thread contention.
* Resolves [GitHub Issue #1659](https://github.com/FusionAuth/fusionauth-issues/issues/1659)
* Allow for plugins that require dependent jars in their classpath.
* To take advantage of this capability, create a sub-directory in the configured plugin directory. Place your plugin jar, and any dependant jars in the same directory or nested sub-directories. Each immediate sub-directory of the configured plugin directory will be considered a discrete classloader. Each of these class loaders will still share the parent classloader, so it is still advised to keep dependencies to a bare minimum such that you don't conflict with existing dependencies of FusionAuth.
* Resolves [GitHub Issue #1663](https://github.com/FusionAuth/fusionauth-issues/issues/1663)
* Minimize the duration of the database Transaction during authentication. This should improve login performance, especially when using an LDAP or Generic Connector.
* Resolves [GitHub Issue #1666](https://github.com/FusionAuth/fusionauth-issues/issues/1666) (666 😱 yikes)
* Alphabetize the Applications in Select form controls in the FusionAuth admin UI, this should make it easier for those are not robots to navigate when you have many applications.
* [GitHub Issue #1668](https://github.com/FusionAuth/fusionauth-issues/issues/1668)
* Allow a login using a 3rd party IdP such as Google to succeed even if an Elasticsearch exception occurs when attempting to re-index the user.
* Resolves [GitHub Issue #1673](https://github.com/FusionAuth/fusionauth-issues/issues/1673)
### New
* Initial technology preview for SCIM Server, this feature is available in the Enterprise plan.
* Resolves [GitHub Issue #106](https://github.com/FusionAuth/fusionauth-issues/issues/106)
* Nintendo Online Identity Provider, this feature is available with all licensed plans of FusionAuth.
* Resolves [GitHub Issue #1206](https://github.com/FusionAuth/fusionauth-issues/issues/1206)
* New Identity Provider Link & Unlink Events
* Resolves [GitHub Issue #1589](https://github.com/FusionAuth/fusionauth-issues/issues/1589)
* Default the Event Transaction Type in the Tenant configuration to `None`
* Resolves [GitHub Issue #1644](https://github.com/FusionAuth/fusionauth-issues/issues/1644)
* New JWT claims
* The `tid` claim is now being set in all JWTs. This is the FusionAuth Tenant Id, and is marked as reserved.
* The JWT header will also now contain a `gty` claim which will represent the grant types in order of use for this token.
* Resolves [GitHub Issue #1669](https://github.com/FusionAuth/fusionauth-issues/issues/1669)
### Internal
* Update Apache Tomcat from `8.5.72` to `8.5.77`.
* Resolves [GitHub Issue #1620](https://github.com/FusionAuth/fusionauth-issues/issues/1620)
### Fixed
* When using the FastPath installation for Windows, the startup may fail to download Java if you are using the `startup.bat` option for starting services.
* Resolves [GitHub Issue #1597](https://github.com/FusionAuth/fusionauth-issues/issues/1597), thanks to [@gkrothammer](https://github.com/gkrothammer) for the help!
* Using the Identity Provider Link API when more than one tenant is configured may fail unless you are specifying the tenant Id using the `X-FusionAuth-TenantId` HTTP request header.
* Resolves [GitHub Issue #1609](https://github.com/FusionAuth/fusionauth-issues/issues/1609)
* Self-service registration may fail to validate an email address beginning with `@`.
* Resolves [GitHub Issue #1617](https://github.com/FusionAuth/fusionauth-issues/issues/1617), thanks to [@pablomadrigal](https://github.com/pablomadrigal) for letting us know!
* Using the Passwordless API without passing the OAuth2 state parameters on the URL such as `client_id`, and the user is not registered for the Application, the request may fail.
* Resolves [GitHub Issue #1623](https://github.com/FusionAuth/fusionauth-issues/issues/1623)
### New
* Initial technology preview for HTTP requests within a lambda function, termed Lambda HTTP Connect. All previously configured lambdas will continue to run on the legacy JS engine. Starting in this release the default engine for newly created lambdas will be GraalJS, but you have the ability to select the preferred engine. When using the GraalJS engine, you will be able to begin making HTTP requests within the lambda function. At some point in the future we will deprecate and fully remove the legacy JS engine (Nashorn). For the time being, use the new engine if you are able, and provide us feedback if you find anything is not working. If you do encounter a problem open an issue, and switch the lambda back to the Nashorn engine.
* HTTP requests (AJAX) in the lambda requires Essentials or Enterprise plans.
* Resolves [GitHub Issue #267](https://github.com/FusionAuth/fusionauth-issues/issues/267)
* Resolves [GitHub Issue #571](https://github.com/FusionAuth/fusionauth-issues/issues/571)
### Fixed
* SAML v2 Login to FusionAuth may fail due to an exception.
* Resolves [GitHub Issue #1606](https://github.com/FusionAuth/fusionauth-issues/issues/1606), thanks so much to [@kristianvld](https://github.com/kristianvld) for letting us know.
### Known Issues
* SAML v2 Login to FusionAuth may fail due to an exception. Please upgrade directly to FusionAuth version >= 1.34.1
* See [GitHub Issue #1606](https://github.com/FusionAuth/fusionauth-issues/issues/1606) for additional details.
### Security
* Resolve a potential vulnerability in the IdP Link API. If you are actively using any IdP configured to use the `CreatePendingLink` linking strategy, please upgrade at your earliest convenience.
* Resolves [GitHub Issue #1600](https://github.com/FusionAuth/fusionauth-issues/issues/1600)
### Changed
* When using the OpenID Connect identity provider, you have the option to select one of three client authentication options. You may select `none`, `client_secret_basic` or `client_secret_post`. Some 3rd party identity providers do not allow the `client_id` to be sent in the request body when using `client_secret_basic`. A strict reading of the OAuth2 and OpenID Connect specifications imply that the `client_id` should only be present in the request body when a client secret is not used, or you have selected `none` or `client_secret_post` for an authentication method. This change is to make FusionAuth more compliant with 3rd party IdPs that enforce this behavior. It is not expected that this change will have any negative impact on OpenID Connect configurations that have been working up until this release. However, please be aware of this change and verify existing OpenID Connect identity providers continue to behave as expected.
* Resolves [GitHub Issue #1595](https://github.com/FusionAuth/fusionauth-issues/issues/1595)
* Utilize PKCE anytime FusionAuth is initiating an Authorization Code grant to FusionAuth. While most of this will be transparent and should not affect any of your integrations, there is one use case in which it is important for FusionAuth to utilize PKCE when performing an Authorization Code grant to FusionAuth. This use case is when you are using an application with PKCE configured as required, and you then use the Device grant using the themed FusionAuth pages. In this case FusionAuth must utilize PKCE in order to pass PKCE validation during the request.
* Resolves [GitHub Issue #1598](https://github.com/FusionAuth/fusionauth-issues/issues/1598)
* When using the interactive Setup Wizard to perform initial setup of FusionAuth, the checkbox to sign up for the FusionAuth newsletter has been changed to be checked by default. This means that prior to this release you had to opt-in, and starting in this release, you will need to opt-out during this step. You also have the option to un-subscribe from the newsletter at any point in the future.
* Resolves [GitHub Issue #1577](https://github.com/FusionAuth/fusionauth-issues/issues/1577)
### New
* Native support for PBKDF2 using a 512-bit derived key length. The default PBKDF2 algorithm uses a 256-bit derived key length. Some IdPs such as KeyCloak use a 512-bit key, so this plugin should support an import from KeyCloak without using a custom plugin. This new algorithm is available using the value `salted-pbkdf2-hmac-sha256-512` during the User Import API.
* Resolves [GitHub Issue #1604](https://github.com/FusionAuth/fusionauth-issues/issues/1604)
### Security
* Add `-Dlog4j2.formatMsgNoLookups=true` to the `fusionauth-search` bundled version of Elasticsearch.
* Please note, that if you are running a standalone version of Elasticsearch, this will not affect you, and you should still complete any suggested mitigation steps for your Elasticsearch instance. This VM argument added to the `fusionauth-search` bundle is only added to make people feel warm and fuzzy. FusionAuth Cloud users are not vulnerable to [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228), and even if you are self-hosting FusionAuth and utilizing the Elasticsearch bundled with `fusionauth-search` you are not vulnerable if you have followed our suggested securing steps. Also due to the version of Java we are using to run Elasticsearch, you are not vulnerable. But we all like to put on our tinfoil hats sometimes, so we are making this change for good measure.
* Resolves [GitHub Issue #1520](https://github.com/FusionAuth/fusionauth-issues/issues/1520)
* Updated PostgreSQL JDBC driver from version `42.2.22` to `42.3.2`.
* This update is only pertinent to you if you are using a PostgreSQL database. If you are using MySQL, you are not vulnerable.
* FusionAuth Cloud users are not affected. If you are self-hosting FusionAuth you are only vulnerable if you allow un-authorized modifications to your JDBC connection string used by FusionAuth to connect to the database. I hope you are not doing this. 😉 Please read the following CVE to better understand the vulnerability to see how it may or may not affect you.
* [CVE-2022-21724](https://nvd.nist.gov/vuln/detail/CVE-2022-21724).
* Resolves [GitHub Issue #1535](https://github.com/FusionAuth/fusionauth-issues/issues/1535)
* Proactively upgrade Logback. Instead of Log4J, FusionAuth uses Logback. In response to the recent vulnerabilities in Log4J, the Logback team has proactively added some additional hardening to their library to ensure similar vulnerabilities are not found.
* Resolves [GitHub Issue #1530](https://github.com/FusionAuth/fusionauth-issues/issues/1530)
* Better protection against malicious actors that have access to configuring Themed templates.
* Resolves [GitHub Issue #1549](https://github.com/FusionAuth/fusionauth-issues/issues/1549)
* Ensure we enforce a Two-Factor challenge before changing a password using the Change Password API.
* Resolves [GitHub Issue #1591](https://github.com/FusionAuth/fusionauth-issues/issues/1591)
### Changed
* If you are using the Change Password API with users that have Two-Factor enabled you may need to adjust your integration. Beginning in this release, to use the Change Password API for a user with Two-Factor enabled, you will need to obtain a Trust Token from the Two Factor Login API in order to complete this request. This is potentially a breaking change, the decision was made to make this potentially breaking change due to the enhanced security provided by this change.
* Resolves [GitHub Issue #1591](https://github.com/FusionAuth/fusionauth-issues/issues/1591)
### Fixed
* The FastPath install may fail to download Java on versions `>= 1.32.0`. The issue was that the `curl` request needed to be configured to follow a redirect with the new URLs for the Java download. See the linked issue for a workaround if you want to use FastPath for an older version.
* Resolves [GitHub Issue #1519](https://github.com/FusionAuth/fusionauth-issues/issues/1519)
* Ensure we are able to handle Login records that may contain more than one IP address. When passing through a proxy, the `X-Forwarded-For` HTTP request header may contain more than one IP address. This fix ensures we parse this header correctly and handle existing Login records that may have been recorded with more than one value.
* Resolves [GitHub Issue #1521](https://github.com/FusionAuth/fusionauth-issues/issues/1521)
* Using the Login with Apple button on a themed login or registration page may fail when using Safari on iOS 12. A workaround is documented in the linked GitHub issue if you are unable to upgrade FusionAuth.
* Resolves [GitHub Issue #1526](https://github.com/FusionAuth/fusionauth-issues/issues/1526)
* The Event Log, Audit Log, Login Records search feature in the FusionAuth admin UI may not reset the pagination correctly when beginning a new search request.
* Resolves [GitHub Issue #1501](https://github.com/FusionAuth/fusionauth-issues/issues/1501)
* Group Membership may not be preserved after the first login request when using a Connector without migration.
* Resolves [GitHub Issue #1432](https://github.com/FusionAuth/fusionauth-issues/issues/1432)
* The `jwt.refresh-token.revoke` event may not be sent during a request to the Logout API (`/api/logout`).
* Resolves [GitHub Issue #1522](https://github.com/FusionAuth/fusionauth-issues/issues/1522), thanks to [@TimVanHerwijnen](https://github.com/TimVanHerwijnen) for all the help!
* A consent added to a self-service registration form may show up incorrectly during a complete registration step during login.
* Resolves [GitHub Issue #1259](https://github.com/FusionAuth/fusionauth-issues/issues/1259)
* Resolves [GitHub Issue #1261](https://github.com/FusionAuth/fusionauth-issues/issues/1261)
* Better support for `user.birthDate` when using Advanced self-service registration when Family is enabled with child registration.
* [GitHub Issue #1490](https://github.com/FusionAuth/fusionauth-issues/issues/1490)
* When configuring more than one preferred language in the FusionAuth admin UI on the User or User Registration, the order may not be preserved. For example, if you configured `French, English` where `French` is the preferred languages, with a second option of `English`, when saving the form, the serialized value will become `English, French` and will not likely be saved in the order you expect.
* [GitHub Issue #1131](https://github.com/FusionAuth/fusionauth-issues/issues/1131)
* Fix a potential memory leak in the Email services. If you are sending a lot of email through FusionAuth, this error may cause your FusionAuth service to run out of memory. Restarting the service periodically can mitigate this potential if you are unable to upgrade. This issue was most likely introduced in version `1.30.1`.
* Resolves [GitHub Issue #1548](https://github.com/FusionAuth/fusionauth-issues/issues/1548)
* When completing a Family workflow where a parent joins a child to a family, the `parentEmail` field may not be properly updated in the search index.
* Resolves [GitHub Issue #1550](https://github.com/FusionAuth/fusionauth-issues/issues/1550)
* If you have previously configured Basic Self-Service registration, and then begin using Advanced Self-Service it is possible that a validation may occur that you did not expect.
* Resolves [GitHub Issue #1560](https://github.com/FusionAuth/fusionauth-issues/issues/1560)
* Some edge cases exist when using the Async Tenant Delete API or deleting a Tenant in the FusionAuth admin UI where a tenant may get stuck in the Pending Delete state.
* Resolves [GitHub Issue #1559](https://github.com/FusionAuth/fusionauth-issues/issues/1559)
### Enhancements
* Add the underlying host architecture and operating system name and version to the About panel in the FusionAuth admin UI. See System -> About.
* Resolves [GitHub Issue #1531](https://github.com/FusionAuth/fusionauth-issues/issues/1531)
* Add a tooltip to the Webhook Application configuration to help reduce some confusion until we deprecate this Application configuration.
* Resolves [GitHub Issue #1542](https://github.com/FusionAuth/fusionauth-issues/issues/1542)
* Support longer Refresh Tokens on the Refresh Tokens Import API. The previous limitation was that the refresh token was less than or equal to `191` characters. The assumption was made that this token was opaque and that `191` was very adequate. Some IdPs utilize JWTs for Refresh Tokens and in this case, the length is likely to exceed the previous limitation. This enhancements allows for longer refresh tokens. In particular this will provide better support for importing Refresh Tokens from KeyCloak. See the [Import Refresh Tokens](/docs/apis/users#import-refresh-tokens) API for additional details.
* Resolves [GitHub Issue #1541](https://github.com/FusionAuth/fusionauth-issues/issues/1541)
* Use a better thread pooling strategy for Webhooks to better support a very large volume of events where the event recipient may not respond quickly enough. This allows more events to be queued up if we cannot send them fast enough while waiting for a response from the webhook.
* Resolves [GitHub Issue #1500](https://github.com/FusionAuth/fusionauth-issues/issues/1500)
* Improve licensing errors on the API and FusionAuth admin UI to better differentiate between not licensed, and a feature that requires a specific licensed feature. In particular, some of the features introduced as part of the Threat Detection feature require an Enterprise License with this feature enabled. So you may have a licensed FusionAuth plan, and a feature may still not be available. This change should make it clearer why a particular feature cannot be enabled.
* Resolves [GitHub Issue #1555](https://github.com/FusionAuth/fusionauth-issues/issues/1555)
* Add `tokenExpirationInstant` to the Login Response similar to how the Token endpoint response returns `expires_in` to indicate when the access token returned in the response will expire.
* Resolves [GitHub Issue #1309](https://github.com/FusionAuth/fusionauth-issues/issues/1309)
* Additional User API validation in support of Family configuration with child registration restrictions.
* Resolves [GitHub Issue #1561](https://github.com/FusionAuth/fusionauth-issues/issues/1561)
* Support for ARM 64, the Apple M1, AWS Graviton, etc. Docker images are now published for Intel, and various ARM architectures, and FastPath and other installation paths have support for downloading Java for the correct architecture.
* Resolves [GitHub Issue #1532](https://github.com/FusionAuth/fusionauth-issues/issues/1523), [GitHub Issue #49](https://github.com/FusionAuth/fusionauth-containers/issues/49). Thanks to many of our community superstars for the help with this one! [@rscheuermann](https://github.com/rscheuermann), [@jerryhopper](https://github.com/jerryhopper), [@ceefour](https://github.com/ceefour), [@dmitryzan](https://github.com/dmitryzan)
* Add the option to use the `userId` on the Start Two-Factor API
** Resolves [GitHub Issue #1571](https://github.com/FusionAuth/fusionauth-issues/issues/1571)
* Move the `changePasswordId` to the request body during a POST request. For backwards compatibility, the `changePasswordId` will also be accepted on the URL segment.
* Resolves [GitHub Issue #1214](https://github.com/FusionAuth/fusionauth-issues/issues/1214)
### Fixed
* If you are modifying the user email or username in an Identity Provider Reconcile Lambda, the lambda may be invoked more than once after the initial link has been established. This may cause User registration data to be modified, or lost. If you have not yet upgraded to this version, it is advised that you wait until you can update to version `1.32.1`.
* Resolves [GitHub Issue #1517](https://github.com/FusionAuth/fusionauth-issues/issues/1517), thanks to [@Oceanswave](https://github.com/Oceanswave) for letting us know and for the fantastic bug write up!
* The `1.32.0` version of the Docker image was initially released with a missing Java module that may cause the image to fail during startup. An updated version of the image has been released, if you encounter an issue, please delete your local version of the image and pull it again. The issue is also resolved in this version, so you may also pull the `latest` tag once this version is available.
* Resolves [GitHub Issue #1518](https://github.com/FusionAuth/fusionauth-issues/issues/1518)
### Changed
* This version of FusionAuth will now run on Java 17. If you are using any SAML v2 IdP configurations that still utilize a legacy XML signature algorithm, this upgrade may break that integration.
* It is recommended to test your SAML v2 IdP logins with this version prior to upgrading, or confirm that all of your IdPs are not using any of the following restricted XML signature algorithms:
* `http://www.w3.org/2000/09/xmldsig#sha1`
* `http://www.w3.org/2000/09/xmldsig#dsa-sha1`
* `http://www.w3.org/2000/09/xmldsig#rsa-sha1`
* See [GitHub Issue #1202](https://github.com/FusionAuth/fusionauth-site/issues/1202) for additional details and an optional workaround if you are unable to discontinue use of these algorithms.
### Fixed
* The global and application registration count rollup may fail when using PostgreSQL. This will cause the registration count reports to be incorrect.
* Resolves [GitHub Issue #1498](https://github.com/FusionAuth/fusionauth-issues/issues/1498)
* When using the Development Reset feature (technical preview) and the FusionAuth application is configured to use a specific theme, the reset will fail.
* Resolves [GitHub Issue #1514](https://github.com/FusionAuth/fusionauth-issues/issues/1514)
### Enhancements
* Identity provider linking that was introduced in version 1.28.0 can now optionally be configured to limit the number of unique links to an IdP for a particular user.
* Resolves [GitHub Issue #1310](https://github.com/FusionAuth/fusionauth-issues/issues/1310)
* Allow application URIs to be configured as an OAuth2 Authorized request origin URLs. For example, you may now configure `android-app://com.example` as a valid Authorized request origin.
* Resolves [GitHub Issue #1443](https://github.com/FusionAuth/fusionauth-issues/issues/1443), thanks to [@bonify-b2b](https://github.com/bonify-b2b) for the request.
* Add configuration to allow implicit email verification to be disabled. For example, prior to this release, email based workflows such as Passwordless login, email based registration verification, email based password change, and verifying a two-factor code during login through an email would implicitly mark a user's email as verified if email verification was enabled and the user had not yet completed email verification. In most cases this seems to be the best choice for the end user such that they do not perform redundant tasks to verify their email address once they have provided evidence they have access to the email address. This configuration allows this behavior to be disabled if you wish to require your end user to always go through a specific email verification process for legal or other similar reasons.
* Resolves [GitHub Issue #1467](https://github.com/FusionAuth/fusionauth-issues/issues/1467), thanks to [@lliu-20200701](https://github.com/lliu-20200701) for the request.
* Add a notice on the Device workflow panel when an existing SSO session exists to allow the user to optionally logout prior to continuing.
* Resolves [GitHub Issue #1495](https://github.com/FusionAuth/fusionauth-issues/issues/1495)
### New
* You may optionally specify custom SMTP headers in the Tenant email configuration. These configured headers will be added to all outbound messages.
* Resolves [GitHub Issue #628](https://github.com/FusionAuth/fusionauth-issues/issues/628), thanks to [arni-inaba](https://github.com/arni-inaba) for the suggestion.
### Internal
* Java 17 LTS. Upgrade from Java 14, to the latest long term support (LTS) version of Java which is 17.
### Known Issues
* If you are modifying the user email or username in an Identity Provider Reconcile Lambda, the lambda may be invoked more than once after the initial link has been established. This may cause User registration data to be modified, or lost. If you have not yet upgraded to this version, it is advised that you wait until you can update to version `1.32.1`.
* Resolved in `1.32.1` by [GitHub Issue #1517](https://github.com/FusionAuth/fusionauth-issues/issues/1517)
### Changed
* You may now modify, or fabricate an email or username in the Identity Provider Reconcile Lambda regardless of the Identity Provider type.
* Some of this capability has been provided in the past for the OpenID Connect Identity Provider. This capability was removed in version `1.28.0` when Identity Provider Linking was introduced due to the additional use cases now supported through linking strategies. Due to high demand, and many real world use-cases presented by our users, this decision has been reversed in favor of flexibility for the developer. Please use caution when using this capability, and note that if you create or modify a `username` or `email` in the Reconcile lambda, the lambda will be invoked twice during a single login request.
* Resolves [GitHub Issue #1425](https://github.com/FusionAuth/fusionauth-issues/issues/1425)
### Fixed
* Requiring a birthdate on a self-service registration form when also requiring a parent email may cause an exception.
* Resolves [GitHub Issue #702](https://github.com/FusionAuth/fusionauth-issues/issues/702)
* Improvements to locale handling to expand beyond ISO 639 support to support locales such as `es_419`, `aghem` and others.
* Resolves [GitHub Issue #978](https://github.com/FusionAuth/fusionauth-issues/issues/978)
* Resolves [GitHub Issue #1132](https://github.com/FusionAuth/fusionauth-issues/issues/1132)
* Disabling webhooks on the tenant configuration by clicking on the Enabled table header doesn't work as expected.
* Resolves [GitHub Issue #1123](https://github.com/FusionAuth/fusionauth-issues/issues/1123)
* Fix general message template issues when using the preview action for a message template, or a localized version of the template.
* Resolves [GitHub Issue #1171](https://github.com/FusionAuth/fusionauth-issues/issues/1171)
* An API key created using Kickstart is not validated for length correctly.
* Resolves [GitHub Issue #1397](https://github.com/FusionAuth/fusionauth-issues/issues/1397), thanks to [@miaucl](https://github.com/miaucl) for reporting!
* The error message returned to the end user when a webhook fails during a Self-Service Registration is not able to be customized through a theme.
* Resolves [GitHub Issue #1446](https://github.com/FusionAuth/fusionauth-issues/issues/1446)
* The Theme preview may not render the Account Edit themed page when a Self-Service form is configured
* Resolves [GitHub Issue #1448](https://github.com/FusionAuth/fusionauth-issues/issues/1448)
* Unable to delete an email template when an email template is not assigned to a Consent.
* Resolves [GitHub Issue #1449](https://github.com/FusionAuth/fusionauth-issues/issues/1449)
* A timing issue exists when creating a new Application role, and then immediately attempting to register a user with that role.
* This issue was introduced in version `1.30.2`
* Resolves [GitHub Issue #1452](https://github.com/FusionAuth/fusionauth-issues/issues/1452), thanks to one of our MVPs [@johnmaia](https://github.com/johnmaia) for reporting!
* Using an expired Passwordless link may result in an infinite redirect
* This issue was introduced in version `1.27.0` when support for Microsoft Outlook Safe Links was added via [GitHub Issue #629](https://github.com/FusionAuth/fusionauth-issues/issues/629)
* Resolves [GitHub Issue #1456](https://github.com/FusionAuth/fusionauth-issues/issues/1456), thanks to [@rscheuermann](https://github.com/rscheuermann) for the report!
* Missing validation on the Registration API to ensure the User exists by Id when passing the `userId` on the HTTP request URL segment
* Resolves [GitHub Issue #1457](https://github.com/FusionAuth/fusionauth-issues/issues/1457)
* When copying a Tenant in the FusionAuth admin UI when the source Tenant has Blocked domain configuration present, the Blocked domain configuration is not copied to the new tenant.
* Resolves [GitHub Issue #1459](https://github.com/FusionAuth/fusionauth-issues/issues/1459)
* When using the OAuth2 Password grant (Resource Owner Credentials grant), and the `client_id` is provided in the HTTP Basic Authorization header, but not in the HTTP post body, the resulting JWT will not contain the `aud` claim.
* Resolves [GitHub Issue #1462](https://github.com/FusionAuth/fusionauth-issues/issues/1462)
* A database foreign key violation may occur in the Registration Count aggregation service if you delete a Tenant before the aggregator runs.
* This issue was introduced in version `1.30.2`.
* Resolves [GitHub Issue #1466](https://github.com/FusionAuth/fusionauth-issues/issues/1466)
* Enabling Two-Factor in the Self-Service themed forms, or in the admin UI may fail to render the QR code if the encoded string used to build the QR code is between 192 and 220 characters in length.
* Resolves [GitHub Issue #1470](https://github.com/FusionAuth/fusionauth-issues/issues/1470), thanks to [@jasonaowen](https://github.com/jasonaowen) for letting us know and helping us debug it!
* When a user is assigned roles explicitly through a User Registration in addition to a Group membership, the roles assigned by the Group membership will not be returned.
* This issue was introduced in version `1.30.2` vi [GitHub Issue #480](https://github.com/FusionAuth/fusionauth-issues/issues/480)
* Resolves [GitHub Issue #1473](https://github.com/FusionAuth/fusionauth-issues/issues/1473)
* When using the Setup Password email template provided by FusionAuth with the User Registration API to create a User and a Registration in a single API call the URL generated and sent to the user may not be usable. A `client_id` will have been added to the URL which will result in an error when the FusionAuth page is rendered. To work around the issue prior to this release, please remove the `client_id` from the Email template.
* Resolves [GitHub Issue #1476](https://github.com/FusionAuth/fusionauth-issues/issues/1476)
* A SAML v2 SP using an HTTP Redirect Binding that has URL encoded the query string using lower case percent encoding may cause FusionAuth to fail to validate the signature.
* Resolves [GitHub Issue #1496](https://github.com/FusionAuth/fusionauth-issues/issues/1496), thanks to engineering team at [HAProxy](https://www.haproxy.com) for the assist!
### Enhancements
* You may now access the `id_token` when available during an OpenID Connect Reconcile lambda
* Resolves [GitHub Issue #323](https://github.com/FusionAuth/fusionauth-issues/issues/323), thanks to [@Thammada](https://github.com/Thammada) for opening the issue!
* Add additional support for `idp_hint` for Apple and Twitter Identity Providers.
* Resolves [GitHub Issue #1306](https://github.com/FusionAuth/fusionauth-issues/issues/1306)
* Add an example use and changed user to the Audit Log Test event when using the Webhook Tester in the FusionAuth admin UI
* Resolves [GitHub Issue #1360](https://github.com/FusionAuth/fusionauth-issues/issues/1360)
* When FusionAuth is unable to discover OpenID endpoints using the configured Issuer during configuration of an OpenID Connect Identity Provider an Event Log will be produced to assist you in debugging the connection.
* Resolves [GitHub Issue #1417](https://github.com/FusionAuth/fusionauth-issues/issues/1417)
### Internal
* Update the internal scheduler library.
* Resolves [GitHub Issue #1461](https://github.com/FusionAuth/fusionauth-issues/issues/1461)
### Fixed
* When logging in with an anonymous user from an IdP that now has a linking strategy other than Anonymous an exception occurs. This can occur if you change your linking strategy from Anonymous to something else, and users that were created while configured as Anonymous log in again.
* Resolves [GitHub Issue #1316](https://github.com/FusionAuth/fusionauth-issues/issues/1316)
* The view dialog may not completely render for an SAML v2 IdP Initiated IdP configuration. The dialog fails to completely render due to a FreeMarker exception.
* Resolves [GitHub Issue #1324](https://github.com/FusionAuth/fusionauth-issues/issues/1324)
* If you are activating FusionAuth Reactor during initial startup via Kickstart, and you have CAPTCHA enabled for the FusionAuth admin application, you may not be able to login until the Threat Detection feature comes online. Depending upon your network connection, this may take a few seconds, or a few minutes.
* Resolves [GitHub Issue #1358](https://github.com/FusionAuth/fusionauth-issues/issues/1358)
* The .NET client library handled `exp` and other JWT timestamp values incorrectly.
* Resolves [GitHub Issue #1362](https://github.com/FusionAuth/fusionauth-issues/issues/1362), thanks to [@RyanDennis2018](https://github.com/RyanDennis2018) for reporting.
* When using the duplicate Application button in the admin UI, if the source Application has SAML v2 configured, but not enabled, the copy may fail with an exception.
* Resolves [GitHub Issue #1366](https://github.com/FusionAuth/fusionauth-issues/issues/1366)
* Updating a connector will add an additional `*` domain configuration. This is a regression issue introduced in version `1.28.0`.
* Resolves [GitHub Issue #1367](https://github.com/FusionAuth/fusionauth-issues/issues/1367)
* When generating an RSA Key, a user cannot specify a certain Id.
* Resolves [GitHub Issue #1368](https://github.com/FusionAuth/fusionauth-issues/issues/1368)
* If using kickstart to activate a licensed instance with advanced threat detection enabled, it is possible to get stuck in the Setup Wizard.
* Resolves [GitHub Issue #1369](https://github.com/FusionAuth/fusionauth-issues/issues/1369)
* A user can add new entries to an access control list, but can't delete them using the administrative user interface.
* Resolves [GitHub Issue #1371](https://github.com/FusionAuth/fusionauth-issues/issues/1371)
* Default lambdas are no longer available in Kickstart environment variables. This is a regression introduced in version `1.30.0`.
* Resolves [GitHub Issue #1373](https://github.com/FusionAuth/fusionauth-issues/issues/1373)
* The event payload for a user deactivation was not complete when the deactivation happened via the administrative user interface. It lacked some information such as the IP address of the request.
* Resolves [GitHub Issue #1375](https://github.com/FusionAuth/fusionauth-issues/issues/1375)
* When both Kickstart and maintenance mode occur during an upgrade, a NullPointerException could occur if the default tenant Id was being modified.
* Resolves [GitHub Issue #1382](https://github.com/FusionAuth/fusionauth-issues/issues/1382)
* The IP address can be missing from login records in certain circumstances.
* Resolves [GitHub Issue #1391](https://github.com/FusionAuth/fusionauth-issues/issues/1391)
* Requests with IPv6 addresses cause NumberFormatExceptions.
* Resolves [GitHub Issue #1392](https://github.com/FusionAuth/fusionauth-issues/issues/1392)
* CAPTCHA may not work on the email verification required page.
* Resolves [GitHub Issue #1396](https://github.com/FusionAuth/fusionauth-issues/issues/1396)
* Rendering the passwordValidationRules object on the register page in theme preview does not work.
* Resolves [GitHub Issue #1398](https://github.com/FusionAuth/fusionauth-issues/issues/1398)
* User search widget has an empty value if the user does not have a name.
* Resolves [GitHub Issue #1399](https://github.com/FusionAuth/fusionauth-issues/issues/1399)
* Filling out a CAPTCHA through self service registration or other paths does not save device trust; the user will be prompted a second time.
* Resolves [GitHub Issue #1400](https://github.com/FusionAuth/fusionauth-issues/issues/1400)
* Setup Wizard may be shown in a multi-node environment after it has completed.
* Resolves [GitHub Issue #1402](https://github.com/FusionAuth/fusionauth-issues/issues/1402)
* When using advanced threat detection rate limiting, users are unable to set the rate limit configuration to 1 to allow a limited action be performed only once.
* Resolves [GitHub Issue #1407](https://github.com/FusionAuth/fusionauth-issues/issues/1407)
* Custom data for webhooks not displayed in the admin UI.
* Resolves [GitHub Issue #1422](https://github.com/FusionAuth/fusionauth-issues/issues/1422)
* A truncated deflated SAML AuthN request was not handled as well as it should have been.
* Resolves [GitHub Issue #1424](https://github.com/FusionAuth/fusionauth-issues/issues/1424)
* Some key pairs capable of signing a SAML request are not eligible in the UI.
* Resolves [GitHub Issue #1430](https://github.com/FusionAuth/fusionauth-issues/issues/1430)
* Custom data for connectors not displayed in the admin UI.
* Resolves [GitHub Issue #1435](https://github.com/FusionAuth/fusionauth-issues/issues/1435)
### Enhancements
* When using MySQL with a large number of applications, and application roles, it may become slow to retrieve a user. This change should improve performance when using MySQL.
* Resolves [GitHub Issue #480](https://github.com/FusionAuth/fusionauth-issues/issues/480), thanks to [@nikos](https://github.com/nikos) and David B. for the assist!
* Improve the performance of using the Public Key API endpoint when you have a lot of applications and keys.
* Resolves [GitHub Issue #1145](https://github.com/FusionAuth/fusionauth-issues/issues/1145), thanks to [@nulian](https://github.com/nulian) for reporting, and [@Johpie](https://github.com/Johpie) for the additional debug.
* Display the database version and elastic search versions in the administrative user interface.
* Resolves [GitHub Issue #1390](https://github.com/FusionAuth/fusionauth-issues/issues/1390)
* Improve User and Registration API performance at scale.
* Resolves [GitHub Issue #1415](https://github.com/FusionAuth/fusionauth-issues/issues/1415)
* Try to support SAML POST bindings with SSO even when cookie `SameSite` policy is set to `SameSite=Lax`.
* Resolves [GitHub Issue #1426](https://github.com/FusionAuth/fusionauth-issues/issues/1426)
* Add a default NameID format when one is not provided on SAML AuthN or Logout requests.
* Resolves [GitHub Issue #1428](https://github.com/FusionAuth/fusionauth-issues/issues/1428)
### Internal
* Update Apache Tomcat from `8.5.63` to `8.5.72`.
* Resolves [GitHub Issue #1433](https://github.com/FusionAuth/fusionauth-issues/issues/1433)
### Known Issues
* Registration counts may fail to be rolled up into reports when using PostgreSQL. Updating to `1.30.2` should resolve the issue.
* Resolved in `1.32.0` by [GitHub Issue #1498](https://github.com/FusionAuth/fusionauth-issues/issues/1498)
* A potential memory leak was introduced in this version. Updating to `1.33.0` should resolve the issue, if you are unable to upgrade, restarting the service periodically can mitigate this potential issue.
* Resolved in `1.33.0` by [GitHub Issue #1548](https://github.com/FusionAuth/fusionauth-issues/issues/1548)
### Fixed
* The Text MIME type of an email may not render Unicode correctly when the host system does not have `UTF-8` set as the default character set.
* Resolves [GitHub Issue #1122](https://github.com/FusionAuth/fusionauth-issues/issues/1122), thanks to [@soullivaneuh](https://github.com/soullivaneuh) for the report!
* Unable to assign an IP ACL to an application if one is not already assigned to the tenant.
* Resolves [GitHub Issue #1349](https://github.com/FusionAuth/fusionauth-issues/issues/1349)
* Unable to delete an IP ACL in use by a tenant
* Resolves [GitHub Issue #1350](https://github.com/FusionAuth/fusionauth-issues/issues/1350)
### Enhancements
* General performance improvements for login, OAuth2 grants, and user create and registration.
* Add the User Two Factor methods to the Elasticsearch index.
* If you have existing users with Two-Factor enabled, you will want to perform a re-index in order to search on two-factor configuration.
* Resolves [GitHub Issue #1352](https://github.com/FusionAuth/fusionauth-issues/issues/1352), thanks to one of our favorite FusionAuth users [@flangfeldt](https://github.com/flangfeldt) for making the request.
### Internal
* Performance improvements
Features that require the Threat Detection feature:
- CAPTCHA
- Domain blocking in registration
- IP access control lists
- IP location
- Some of the new events and transactional emails
- Rate limiting
### Known Issues
* If you are referencing any Reconcile Lambda Ids using the syntax `FUSIONAUTH_LAMBDA{type}_ID` - this may no longer work due to a change in how these default lambdas are initialized.
* The current work around is to modify your kickstart to build your own version of this lambda instead of using the FusionAuth default.
* You will find a copy of the default lambdas shipped with FusionAuth in the [Lambda](/docs/extend/code/lambdas/) documentation that you may use to copy into your kickstart.
* The issue is being tracked here [GitHub Issue #1373](https://github.com/FusionAuth/fusionauth-issues/issues/1373)
### Fixed
* Unable to enable `user.action` event at the tenant using the UI. If you encounter this issue, you may work around it by using the Tenant API.
* Resolves [GitHub Issue #1307](https://github.com/FusionAuth/fusionauth-issues/issues/1307)
* If you make an API request to `/api/two-factor/login` with an empty JSON body, an exception will occur instead of a validation error being returned with a `400` status code.
* Resolves [GitHub Issue #1330](https://github.com/FusionAuth/fusionauth-issues/issues/1330)
* When using an IdP with a linking mode other than Create Pending Link, the token may not correctly be stored. If you previously had been using the token stored on the User Registration, and are now looking for it in the Identity Provider Link, you may not find it. This fix resolves the issue.
* Resolves [GitHub Issue #1341](https://github.com/FusionAuth/fusionauth-issues/issues/1341)
* When you are using FusionAuth as a SAML v2 IdP with Redirect bindings, you were unable to use idp_hint to bypass the login page to federate to another provider.
* Resolves [GitHub Issue #1331](https://github.com/FusionAuth/fusionauth-issues/issues/1331)
### Changed
* New themed page added for Unauthorized access.
* See the [Theme](/docs/apis/themes) API and the [Theme](/docs/customize/look-and-feel/) documentation for additional details.
* A macro available to themes named `[@helpers.input]` was modified to be able to build a checkbox. This change could affect you if you try to copy and paste the checkbox usage without modifying the macro definition in your Helper file. Review the [Upgrading](/docs/customize/look-and-feel/advanced-theme-editor#upgrading) section for information on how to resolve potential breaking changes.
### New
* JWT Vending machine
* This allows a JWT to be created for a not-yet-existing user with a payload defined by the API caller.
* Resolves [GitHub Issue #525](https://github.com/FusionAuth/fusionauth-issues/issues/525)
* FusionAuth wasn't awesome enough, so we added a robust Threat Detection feature for enterprise customers. This feature includes:
* IP Access Control for API keys
* This allows support for an API key to be further restricted by the origin IP address.
* Resolves [GitHub Issue #933](https://github.com/FusionAuth/fusionauth-issues/issues/933)
* IP Access Control for SSO and self service forms
* This allows you to limit access to the FusionAuth SSO or a particular application login through SSO by IP address
* Blocked domain configuration to limit registrations from specific email domains
* Rate limiting per user for the following requests:
* Failed login (only used if Failed Login configuration is not in use)
* Forgot password
* Send email verification
* Send passwordless
* Send registration verification
* Send two-factor
* CAPTCHA - add CAPTCHA to login and other end user forms to help ensure only humans are submitting forms.
* This feature is in tech preview and is subject to change.
* Support for Google ReCaptcha v2, Google ReCaptcha v3, HCaptcha and HCaptcha Enterprise
* Resolves [GitHub Issue #278](https://github.com/FusionAuth/fusionauth-issues/issues/278)
* IP location.
* When possible, an IP address will be resolved to include city, country, region, zip code, longitude and latitude.
* IP location will be included in login records and will be available in some email templates and webhook events
* Used to calculate impossible travel between login locations
* New Webhook events:
* Audit Log Create `audit-log.create`
* Event Log Create `event-log.create`
* Kickstart Success `kickstart.success`
* User Create Complete `user.create.complete`
* User Delete Complete `user.delete.complete`
* User Update Complete `user.update.complete`
* User LoginId Duplicate On Create `user.loginId.duplicate.create`
* User LoginId Duplicate Update `user.loginId.duplicate.update`
* User Email Update `user.email.update`
* User Login New Device `user.login.new-device`
* User Login Suspicious `user.login.suspicious`
* User Password Reset Success `user.password.reset.success`
* User Password Reset Send `user.password.reset.send`
* User Password Reset Start `user.password.reset.start`
* User Password Update `user.password.update`
* User Registration Create Complete `user.registration.create.complete`
* User Registration Delete Complete `user.registration.delete.complete`
* User Registration Update Complete `user.registration.update.complete`
* User Two Factor Method Added `user.two-factor.method.add`
* User Two Factor Method Removed `user.two-factor.method.remove`
* See the [Event Webhooks](/docs/extend/events-and-webhooks/) documentation for additional details.
* Resolves [GitHub Issue #1308](https://github.com/FusionAuth/fusionauth-issues/issues/1308), thanks to [@adoliver](https://github.com/adoliver) for the suggestion!
* Resolves [GitHub Issue #1178](https://github.com/FusionAuth/fusionauth-issues/issues/1178)
* Resolves [GitHub Issue #1128](https://github.com/FusionAuth/fusionauth-issues/issues/1128)
* Resolves [GitHub Issue #1129](https://github.com/FusionAuth/fusionauth-issues/issues/1129)
* New transactional emails:
* Email update
* Login Id duplicate on create
* Login Id duplicate on update
* Login with new device
* Suspicious login
* Password reset success
* Password update
* Two-factor method added
* Two-factor method removed
### Enhancements
* Search on `oldValue`, `newValue` and `reason` in the Audit Log.
* See the [Audit Log Search](/docs/apis/audit-logs#search-the-audit-log) API for additional details on searching on `oldValue`, `newValue` and `reason` in the audit log.
* When using IdP linking in conjunction with the Oauth2 Device grant, the recently completed links will be available on the Device complete themed page by using the `completedLinks` variable.
* See the [Device Complete](/docs/customize/look-and-feel/template-variables#oauth-device-complete) themed page documentation for additional details.
* More themed pages will have access to the currently logged in user using the `currentUser` variable.
* See the [Theme](/docs/customize/look-and-feel/) documentation for additional details.
### Fixed
* When a user is required to complete registration after login, the user may no longer be able to login w/out a password reset. This is a regression from version 1.28.0, and only affects those using self-service registration that will have existing users that do not have all required fields on their account.
* Resolves [GitHub Issue #1344](https://github.com/FusionAuth/fusionauth-issues/issues/1344), thanks to [@flangfeldt](https://github.com/flangfeldt) for reporting the issue
### Fixed
* A `404` may be returned when attempting to update a user with `PUT` or `PATCH` on the User API if the user has an unverified email and email verification has been disabled.
* Resolves [GitHub Issue #1333](https://github.com/FusionAuth/fusionauth-issues/issues/1333)
### Fixed
* When using a SAML v2 IdP that does not send back a `KeyInfo` element in the XML response, an exception may occur when attempting to parse the response.
* Resolves [GitHub Issue #1332](https://github.com/FusionAuth/fusionauth-issues/issues/1332)
### Fixed
* In a multi-tenant configuration, SSO sessions may be pre-maturely terminated if one tenant has a lower TTL configuration than the other tenants. To work around this issue prior to this release, ensure all SSO TTL configurations are equal.
* Resolves [GitHub Issue #1262](https://github.com/FusionAuth/fusionauth-issues/issues/1262)
* The arg names in the `LambdaType` enum were not all correct.
* Resolves [GitHub Issue #1284](https://github.com/FusionAuth/fusionauth-issues/issues/1284)
* An IdP Debug event log may not get produced when a unique Id could not be resolved.
* Resolves [GitHub Issue #1315](https://github.com/FusionAuth/fusionauth-issues/issues/1315)
* When enabling the SAML v2 IdP debug log an exception may be taken when attempting to produce the debug event log. The result is that the debug log will not be produced.
* Resolves [GitHub Issue #1317](https://github.com/FusionAuth/fusionauth-issues/issues/1317)
### Fixed
* When viewing the theme preview for the `oauth2/start-idp-link.ftl` template, and error may be logged.
* Resolves [GitHub Issue #1276](https://github.com/FusionAuth/fusionauth-issues/issues/1276)
* When a webhook transaction fails to create a user or registration on a themed page, a non-themed error page may be displayed
* Resolves [GitHub Issue #1279](https://github.com/FusionAuth/fusionauth-issues/issues/1279)
### Enhancements
* Enhance the Link API to retrieve a user by a 3rd party unique Id to identify a FusionAuth user is linked to the user. See the [Link](/docs/apis/identity-providers/links) API for additional details.
* Resolves [GitHub Issue #1277](https://github.com/FusionAuth/fusionauth-issues/issues/1277)
* During a device link request which contains a device linking token, show an intermediate page asking the user if they would like to sign in with an existing user or create a new user.
* Resolves [GitHub Issue #1287](https://github.com/FusionAuth/fusionauth-issues/issues/1287)
* Allow the IdP Login API to optionally be passed a request parameter to indicate a link should not be established and a `404` should be returned instead. This is useful if you wish to identify if a link exists first before starting an auxiliary workflow such as a device grant with a linking token. See the [Login](/docs/apis/identity-providers/) API for additional details.
* Resolves [GitHub Issue #1288](https://github.com/FusionAuth/fusionauth-issues/issues/1288)
* Add additional configuration to the unique username configuration to support always appending a suffix even when the username is not in use. See the [Tenant](/docs/apis/tenants) API for additional details.
* Resolves [GitHub Issue #1290](https://github.com/FusionAuth/fusionauth-issues/issues/1290)
* Add an additional debug event log when for the SAML IdP to debug the `AuthN` request sent to the SAML IdP
* Resolves [GitHub Issue #1293](https://github.com/FusionAuth/fusionauth-issues/issues/1293)
* In version `1.28.0` the resolution of the value returned by the SAML v2 IdP in the `NameID` was modified. If the IdP returns a format of `unspecified` with a value of `email` then after upgrading to version `1.28.0` your SAML IdP will not function properly. Ideally you would ask your IdP to return you a NameID format of `emailAddress`, but if that is not possible this enhancement will allow FusionAuth to accept the value returned in the `NameID` if the format is returned as `unspecified`.
* Resolves [GitHub Issue #1294](https://github.com/FusionAuth/fusionauth-issues/issues/1294)
* Instead of logging FreeMarker exceptions to the system log and producing a stack trace that may end up in the UI, an event log will be produced. The message in the UI will be condensed based upon the runtime mode. When in `development` mode some details will be provided to assist in debugging your themed template. If in `production` runtime mode only a message indicating an error occurred will be displayed to the user.
* Resolves [GitHub Issue #1299](https://github.com/FusionAuth/fusionauth-issues/issues/1299)
### Internal
* Update HikariCP from `3.4.1` to `4.0.3`, and update PostgreSQL JDBC driver from `42.2.14` to `42.2.22`
* Resolves [GitHub Issue #1300](https://github.com/FusionAuth/fusionauth-issues/issues/1300)
### Fixed
* Allow self-consent form field on a self-service form.
* Resolves [GitHub Issue #1258](https://github.com/FusionAuth/fusionauth-issues/issues/1258)
* Correct validation of a consent form field on edit. Control type was failing validation on edit.
* Resolves [GitHub Issue #1260](https://github.com/FusionAuth/fusionauth-issues/issues/1260)
* An imported user requiring password change, and email verification may fail to verify email verification with an email verification gate.
* Resolves [GitHub Issue #1265](https://github.com/FusionAuth/fusionauth-issues/issues/1265)
* Better parsing of the `X-Fowarded-For` HTTP request header. This header may contain one to many IP addresses, and only the first value should be preserved for the login record. Prior to this fix, it would be possible to see a login record that contained multiple IP addresses separated by a comma.
* Resolves [GitHub Issue #1267](https://github.com/FusionAuth/fusionauth-issues/issues/1267)
* Correctly show the Verification URL in the OAuth2 configuration when the `Device` grant is selected. This issue was introduced in `1.28.0`.
* Resolves [GitHub Issue #1268](https://github.com/FusionAuth/fusionauth-issues/issues/1268)
* Use the correct FusionAuth redirect URL when using the Sony PlayStation Network IdP.
* Resolves [GitHub Issue #1269](https://github.com/FusionAuth/fusionauth-issues/issues/1269)
* Use the correct FusionAuth redirect URL when using the Steam IdP. This IdP uses an Implicit grant and should be using the `/oauth2/callback/implicit` callback URL.
* Resolves [GitHub Issue #1272](https://github.com/FusionAuth/fusionauth-issues/issues/1272)
* Allow the Epic Games IdP to function properly when omitting the `scope` configuration property.
* Resolves [GitHub Issue #1273](https://github.com/FusionAuth/fusionauth-issues/issues/1273)
### Tech Preview
* You may optionally start an account link when beginning a Device grant.
* Resolves [GitHub Issue #1274](https://github.com/FusionAuth/fusionauth-issues/issues/1274)
### Known Issues
* If you are using self-service registration there is a possibility that a user may be required to complete registration by adding additional fields to their account after they login. In this scenario it is possible that they will no longer be able to login and will be required to reset their password. The fix for this was added in `1.29.4`.
* Fixed in `1.29.4`, under [GitHub Issue #1344](https://github.com/FusionAuth/fusionauth-issues/issues/1344), thanks to [@flangfeldt](https://github.com/flangfeldt) for reporting the issue
* If you are using the [SAML v2 Populate Lambda](/docs/extend/code/lambdas/samlv2-response-populate) or the [SAML v2 Reconcile Lambda](/docs/extend/code/lambdas/samlv2-response-reconcile) the `NameID` field has been changed to an array. You will need to update your lambda code if you are using this field.
### Changed
* You may no longer build a synthetic email address using a lambda for an OpenID Connect identity provider. This has been removed because you may now link a user by username or create a link w/out a username or an email to an existing FusionAuth user. If you are using this feature, you may need to plan for a migration to this new behavior. If you have a support contract with FusionAuth, please reach out and ask for additional information.
* When using FusionAuth as a SAML IdP, FusionAuth will now accept `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` in addition to `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`. This should allow FusionAuth to work with SAML v2 service providers that only support the persistent NameID format.
* Tokens returned by IdPs are no longer stored on the User Registration object in the `tokens` field. Each token is now stored with the IdP link for the User and the IdP. See the [Link](/docs/apis/identity-providers/links) API for additional details.
### New
* Reindex API
* Resolves [GitHub Issue #1232](https://github.com/FusionAuth/fusionauth-issues/issues/1232)
* See the [Reindex](/docs/apis/system#rebuild-the-elasticsearch-index) API for usage.
* Account Link API
* This API will allow you to link and un-link users in 3rd party identity providers with a FusionAuth user.
* See the [Link](/docs/apis/identity-providers/links) API for usage.
* IdP Linking options
* Each Identity Provider may now be configured with a linking strategy. The strategies will include linking by email, username, anonymous or a link to an existing user.
* Linking by username is now supported. There is a higher risk of account takeover using this strategy, you should use caution when using this feature.
* Tokens from identity providers should now be retrieved from the link, rather than the registration. More information can be found under `identityProviderLink.token` response value [here](/docs/apis/identity-providers/links#retrieve-a-link)
* Email Send API allows an email address in the To field instead of only allowing FusionAuth userIds
* See the [Email Send](/docs/apis/emails#send-an-email) API for additional details.
* SAML Identity Provider can now be configured to use any NameID format. Previously only the Email NameID format was utilized.
* This should allow the SAML identity provider configuration to be more flexible and work with additional SAML identity providers.
### Enhanced
* When FusionAuth is acting as a SAML Identity Provider, you may now send a NameID format of Email or Persistent.
* This should allow FusionAuth to work with additional SAML service providers such as Slack.
* Resolves [GitHub Issue #522](https://github.com/FusionAuth/fusionauth-issues/issues/522)
* The [Email Send](/docs/apis/emails#send-an-email) API now allows you to send to a user that does not yet exist in FusionAuth by allowing you to specify an email address for the `To:` field.
* Resolves [GitHub Issue #743](https://github.com/FusionAuth/fusionauth-issues/issues/743)
* See the [Email Send](/docs/apis/login) API for additional details.
* The Facebook and Google Identity Providers will now default to using a redirect instead of a popup for login. All existing configurations will be migrated to use the popup dialog to remain consistent with the previous behavior. With this update you may now also use the `idp_hint` parameter to login with Facebook and Google.
* Resolves [GitHub Issue #909](https://github.com/FusionAuth/fusionauth-issues/issues/909)
* Additional PKCE and Client Authentication configuration
* You may now optionally configure PKCE as required, not required, or required when not using a confidential client. This offers better compatibility when multiple client types (a webapp and a mobile app, for example) are authenticating against a single FusionAuth application.
* Resolves [GitHub Issue #1152](https://github.com/FusionAuth/fusionauth-issues/issues/1152)
* Add the currently selected Two Factor method object to the Themed Two Factor page `/oauth2/two-factor`
* Resolves [GitHub Issue #1237](https://github.com/FusionAuth/fusionauth-issues/issues/1237), thanks to one of our MVPs - [@flangfeldt](https://github.com/flangfeldt) for the suggestion!
* Allow using IdP buttons on the Themed registration page
* Resolves [GitHub Issue #554](https://github.com/FusionAuth/fusionauth-issues/issues/554), thanks to [@gordody](https://github.com/gordody) for the request!
* When using email verification required with the gated configuration, optionally send the user another email before entering the gated page if the user does not have an existing verification email that is not expired.
* Resolves [GitHub Issue #1247](https://github.com/FusionAuth/fusionauth-issues/issues/1247), thanks to [@lliu-20200701](https://github.com/lliu-20200701) for the suggestion.
### Fixed
* Do not add the `NotBefore` assertion on the SAML AuthN response on the subject confirmation.
* Resolves [GitHub Issue #1215](https://github.com/FusionAuth/fusionauth-issues/issues/1215), thanks to [@pakomp](https://github.com/pakomp) for pointing out this issue!
* When importing users with `passwordChangeRequired=true` w/out specifying the change reason an exception may occur during login.
* Resolves [GitHub Issue #1245](https://github.com/FusionAuth/fusionauth-issues/issues/1245), thanks to [@lliu-20200701](https://github.com/lliu-20200701) for finding this bug.
* When using the email verification gate and self-service registration if a user requires their email to be verified and is forced through the complete registration flow they will not be correctly gated.
* Resolves [GitHub Issue #1246](https://github.com/FusionAuth/fusionauth-issues/issues/1246), thanks to [@lliu-20200701](https://github.com/lliu-20200701) for reporting!
* Fix a JavaScript bug that may cause some of the themed pages to render incorrectly in the view window.
* Resolves [GitHub Issue #1228](https://github.com/FusionAuth/fusionauth-issues/issues/1228), thanks to [@flangfeldt](https://github.com/flangfeldt) for reporting!
### Tech Preview
* New IdPs for EpicGames, Nintendo, Sony PlayStation Network, Steam, Twitch, Xbox - see [link](/docs/get-started/core-concepts/identity-providers) for more information
* Resolves [GitHub Issue #1205](https://github.com/FusionAuth/fusionauth-issues/issues/1205) - Sony PlayStation Network
* Resolves [GitHub Issue #1206](https://github.com/FusionAuth/fusionauth-issues/issues/1206) - Nintendo
** Note, the Nintendo IdP is not yet fully functional. This will be completed in a patch release.
* Resolves [GitHub Issue #1207](https://github.com/FusionAuth/fusionauth-issues/issues/1207) - Twitch
* Resolves [GitHub Issue #1208](https://github.com/FusionAuth/fusionauth-issues/issues/1208) - Steam
* Resolves [GitHub Issue #1209](https://github.com/FusionAuth/fusionauth-issues/issues/1209) - Epic Games
* Resolves [GitHub Issue #1210](https://github.com/FusionAuth/fusionauth-issues/issues/1210) - Xbox
* Development kickstart reset. When you are running in `development` runtime mode, you'll see a `Reset` menu item in the System navigation menu.
* See System -> Reset
* There is now a JWT populate lambda for the Client Credentials grant. See [link](/docs/extend/code/lambdas/client-credentials-jwt-populate) for more information.
* Resolves [GitHub Issue #1233](https://github.com/FusionAuth/fusionauth-issues/issues/1233)
### Changed
* In version `1.26.0` the ability to use `user.data.email` for Forgot Password and Passwordless login flows was removed. Support for this behavior has been restored in this patch.
* Resolves [GitHub Issue #1204](https://github.com/FusionAuth/fusionauth-issues/issues/1204), thanks to [@mcs](https://github.com/mcs) for letting us know how this change impacted his usage.
### Fixed
* When building a new theme starting with 1.27.0, you may encounter a JavaScript error during page render. This error should not cause any end user failures, but the login may not properly capture the browser type.
* Resolves [GitHub Issue #1216](https://github.com/FusionAuth/fusionauth-issues/issues/1216)
### Fixed
* When migrating from 1.26.0 or earlier to version 1.27.0 the initial render of the add Tenant panel in the admin UI may fail to render. If you encounter this issue, you may upgrade or edit the FusionAuth tenant first and then try the request again.
* Resolves [GitHub Issue #1196](https://github.com/FusionAuth/fusionauth-issues/issues/1196)
* Make the verification flow simpler when you enable both email and registration verification during self-service registration.
* Resolves [GitHub Issue #1198](https://github.com/FusionAuth/fusionauth-issues/issues/1198)
* The view dialog for the SAML v2 IdP Initiated configuration may not render correctly.
* Resolves [GitHub Issue #1200](https://github.com/FusionAuth/fusionauth-issues/issues/1200)
* When configuring the SAML v2 IdP Initiated Login configuration for an IdP that has a `issuer` that is not a URL the configuration will fail because we are expecting a URL for this field.
* Resolves [GitHub Issue #1203](https://github.com/FusionAuth/fusionauth-issues/issues/1203)
### Changed
* Login API now returns `213` for Registration Not Verified.
* See the [Login](/docs/apis/login) API response for additional details.
* The Login API and the User API may optionally return a `emailVerificationId` or `registrationVerificationId` to assist the developer in completing a verification workflow when the verification strategy has been configured to use a short code instead of a long "clickable" link.
* See the [Login](/docs/apis/login) API response for additional details.
* The Verify Email API now takes the `verificationId` in the request body instead of a URL segment. See the [Verify Email](/docs/apis/users#verify-a-users-email) API for additional details.
* This change is backwards compatible, but the deprecated use of the API may be removed in the future.
* The client libraries methods have also been preserved, but a new method has been added to accept a request body.
* The Verify Registration API now takes the `verificationId` in the request body instead of a URL segment.
* This change is backwards compatible, but the deprecated use of the API may be removed in the future.
* The client libraries methods have also been preserved, but a new method has been added to accept a request body.
* When calling `PUT` on the Login API (ping) the response may optionally return an `emailVerificationId` or `registrationVerificationId` to assist the developer in completing a verification workflow when the verification strategy has been configured to use a short code instead of a long "clickable" link.
* See the Login API response for additional details.
* The User API and Registration API may optionally return an `emailVerificationId` or a map of registration verification Ids to assist the developer in completing a verification workflow when the verification strategy has been configured to use a short code instead of a long "clickable" link.
* See the User and Registration API response examples for additional details.
### Fixed
* CleanSpeak username filtering may not always work when using advanced self-service registration forms with only one step.
* Resolves [GitHub Issue #1158](https://github.com/FusionAuth/fusionauth-issues/issues/1158)
* Link to SAML v2 IdP Initiated Add in the admin UI was missing. See GH issue for a work around.
* Resolves [GitHub Issue #1181](https://github.com/FusionAuth/fusionauth-issues/issues/1181)
* Fixes for the new API Key API - usages in the admin UI. Allow the admin UI to upgrade and downgrade API keys for Key Manager.
* Resolves [GitHub Issue #1174](https://github.com/FusionAuth/fusionauth-issues/issues/1174)
### Tech Preview
* Application Themes. You may optionally assign a theme per application which will then be utilize instead of the tenant configuration.
* [GitHub Issue #769](https://github.com/FusionAuth/fusionauth-issues/issues/769)
* Email verification gate. When using the FusionAuth themed pages, you may force a user to verify their email address before being redirected back to your application.
* [GitHub Issue #1191](https://github.com/FusionAuth/fusionauth-issues/issues/1191)
* Configurable verification strategies to use an interactive form instead of a clickable link.
* May require a change to your email template, see the updated Email Verification documentation for additional details.
* [GitHub Issue #1191](https://github.com/FusionAuth/fusionauth-issues/issues/1191)
* Unique usernames. Allow more than one user to select the same username and allow FusionAuth to manage a unique suffix.
* Resolves [GitHub Issue #1190](https://github.com/FusionAuth/fusionauth-issues/issues/1190)
### New
* Product Version API.
* Resolves [GitHub Issue #1193](https://github.com/FusionAuth/fusionauth-issues/issues/1193)
* Thanks to [@jegger](https://github.com/jegger) for the request!
* See [Version](/docs/apis/system#retrieve-system-version) API for additional details or find `retrieveVersion` in your FusionAuth client library.
### Enhancements
* Try to support Microsoft Outlook Safe Links
* Hopefully 🤞 resolves [GitHub Issue #629](https://github.com/FusionAuth/fusionauth-issues/issues/629)
* Support HTTP Basic Auth using an API key for the Prometheus Metrics endpoint added in 1.26.0.
* See Prometheus endpoint documentation for additional details on authenticating this endpoint.
* Resolves [GitHub Issue #1189](https://github.com/FusionAuth/fusionauth-issues/issues/1189)
### Fixed
* If you use a non default theme for the FusionAuth default tenant, you may see an error when trying to log in to the admin UI after upgrading to version 1.25.0. You can workaround this by appending `?&bypassTheme=true` to your login URL, or append `/admin/` to your base FusionAuth URL to log into the admin UI.
* Resolves [GitHub Issue #1175](https://github.com/FusionAuth/fusionauth-issues/issues/1175).
### Known Issues
* You cannot create a "SAML v2 IdP Initiated" Identity Provider in the admin UI; it isn't present in the "Add Identity Providers" dropdown. You can workaround this by entering the URL to add an Identity Provider manually: `\[GitHub Issue #1181](https://auth.example.com/admin/identity-provider/add/SAMLv2IdPInitiated` (append `/admin/identity-provider/add/SAMLv2IdPInitiated` to your FusionAuth base URL). Tracking in https://github.com/FusionAuth/fusionauth-issues/issues/1181).
Lots of changes ahead! Read carefully to see how this release may affect you.
**Two Factor APIs**
Breaking changes. If you use this functionality, please review the API changes and test before upgrading.
The Two-Factor API, two-factor fields on the User and Import User APIs and the Integrations API have changed and are not backwards compatible. If you use this functionality, please review the API changes and test before upgrading.
**Upgrading from < 1.7.0**
If you are upgrading from a version less than 1.7.0, you must do a two stage upgrade. Upgrade to a version greater than or equal to 1.7.0 but less than 1.26.0, then upgrade from that version to 1.26.0. There were internal migration changes which necessitate this two stage process.
**Accessing the admin Login after upgrading:**
The `/` path of FusionAuth no longer automatically forwards to the admin login. To access the admin UI to complete this configuration append `/admin/` to the URL. Once the theme configuration is complete, this root page will contain links to login and instructions on how to utilize this root landing page.
### Known Issues
* If you use a non default theme for the FusionAuth default tenant, you may see an error when trying to log in to the admin UI. You can workaround this by appending `?&bypassTheme=true` to your login URL.
* Resolved in `1.26.1`, see [GitHub Issue #1175](https://github.com/FusionAuth/fusionauth-issues/issues/1175) for additional details.
### Changed
* The Two-Factor API has changed which allows you to enable and disable Two-Factor methods as well as send codes.
* See the [Two-Factor](/docs/apis/two-factor) API for more details.
* The Two-Factor Login API now returns `409` for too many attempts. This allows the Two-Factor Login API to provide the same locking capability as the Login API when too many failed attempts occur.
* See the [Two-Factor Login](/docs/apis/login#complete-multi-factor-authentication) API for more details.
* The Import API has changed for enabling Two-Factor.
* See the [User Import](/docs/apis/users#import-users) API for changes.
* The User API has changed for enabling and disabling Two-Factor. See the [User](/docs/apis/users) API for changes.
* See the [User](/docs/apis/users) API for changes.
* Email and SMS Two-Factor methods will now require a paid FusionAuth plan. [Learn more about paid plans](/pricing).
* If you are only using Authenticator/TOTP for Two-Factor, this functionality will continue to work properly in the Community plan.
* If you are upgrading from a version less than 1.7.0, you must do a two stage upgrade. Upgrade to a version greater than or equal to 1.7.0 but less than 1.26.0, then upgrade from that version to 1.26.0. There were internal migration changes which necessitate this two stage process.
### Fixed
* You can now delete a user registration for an inactive application
* Resolves [GitHub Issue #1148](https://github.com/FusionAuth/fusionauth-issues/issues/1148)
* Spurious text `[object Object]` on FusionAuth admin UI screen when certain Chrome extensions present.
* Resolves [GitHub Issue #1151](https://github.com/FusionAuth/fusionauth-issues/issues/887). Thanks to [@NikolayMetchev](https://github.com/NikolayMetchev) for filing this.
### Tech Preview
* Entity Management
* Resolves [GitHub Issue #881](https://github.com/FusionAuth/fusionauth-issues/issues/881)
### New
* Prometheus Metrics endpoint
* Resolves [GitHub Issue #362](https://github.com/FusionAuth/fusionauth-issues/issues/362)
* IdP initiated SSO
* Resolves [GitHub Issue #566](https://github.com/FusionAuth/fusionauth-issues/issues/566)
* An API key to create API keys!
* Resolves [GitHub Issue #887](https://github.com/FusionAuth/fusionauth-issues/issues/887). Thanks to [@Tintwo](https://github.com/Tintwo) for filing this.
* Portions of [GitHub Issue #960](https://github.com/FusionAuth/fusionauth-issues/issues/960) were delivered, including features such as:
* Two-Factor step-up API
* SMS Two-Factor with configurable delivery methods
* Localized Message Templates which can be used for SMS Two-Factor messages
* Self service user profile page
* Resolves [GitHub Issue #682](https://github.com/FusionAuth/fusionauth-issues/issues/682)
* Themeable root page
* Resolves [GitHub Issue #378](https://github.com/FusionAuth/fusionauth-issues/issues/378)
* Messengers which are used to send SMS messages through Twilio, Kafka or a generic JSON REST API
* Licensing now supports air-gapped deployments
* Client Credentials grant
* Resolves [GitHub Issue #155](https://github.com/FusionAuth/fusionauth-issues/issues/155)
### Enhancements
* Add IP address to login success and failed events.
* Resolves [GitHub Issue #1162](https://github.com/FusionAuth/fusionauth-issues/issues/1162)
### Changed
* In support of the SAML v2 Logout feature, the following theme changes have been made.
* New themed template `SAMLv2 logout template`. This template will be rendered when you utilize the SAML v2 Logout feature, it is nearly identical to the existing OAuth2 logout themed page. If you are using themes, please review your theme to ensure your user experience is not interrupted.
### Fixed
* If you are using Elasticsearch version 6 you may encounter an error when using the Search API. This is due to a change in how we optionally request the document hit count in the search request to Elasticsearch. The change is not compatible with Elasticsearch version 6. As a work around, you can set `accurateTotal=true` in the API request. See the [User Search](/docs/apis/users#search-for-users) API for additional details on using this parameter.
* Resolves [GitHub Issue #1135](https://github.com/FusionAuth/fusionauth-issues/issues/1135)
* Using the HTTP `PATCH` method on the FusionAuth application may produce erroneous validation errors.
* Resolves [GitHub Issue #1110](https://github.com/FusionAuth/fusionauth-issues/issues/1110)
* Adding additional Java options in the configuration file when the value contains a space may not work correctly.
* Resolves [GitHub Issue #1065](https://github.com/FusionAuth/fusionauth-issues/issues/1065)
* A `NullPointerException` may occur when you have users registered for an application in a non default tenant and you create a login report for only that application. Thanks to [@NikolayMetchev](https://github.com/NikolayMetchev) for filing this.
* Resolves [GitHub Issue #1115](https://github.com/FusionAuth/fusionauth-issues/issues/1115)
* When you omit the `state` parameter on the Authorization request, you may receive a `state` parameter on the `redirect_uri` that you did not expect.
* Resolves [GitHub Issue #1113](https://github.com/FusionAuth/fusionauth-issues/issues/1113)
### New
* Add full support for SAML v2 Logout
* Resolves [GitHub Issue #1137](https://github.com/FusionAuth/fusionauth-issues/issues/1137)
### Enhancements
* Add a button to the Sessions tab in the FusionAuth admin UI to delete all user sessions at once, this action is also available from the drop down action list when managing a user.
* Resolves [GitHub Issue #1094](https://github.com/FusionAuth/fusionauth-issues/issues/1094)
* Add Debug to OAuth2 grants, this will primarily assist in debugging the Authorization Code grant auth code exchange with the Token endpoint.
* Resolves [GitHub Issue #781](https://github.com/FusionAuth/fusionauth-issues/issues/781)
* Add CORS Debug, this will assist you in debugging CORS related `403` HTTP status codes.
* Resolves [GitHub Issue #1126](https://github.com/FusionAuth/fusionauth-issues/issues/1126)
* Better SMTP debug for specific scenarios. This should assist with async connection issues and provide context to the tenant and template being rendered during the exception.
* Resolves [GitHub Issue #1064](https://github.com/FusionAuth/fusionauth-issues/issues/1064)
* Allow the Registration API to accept the `applicationId` as a URL segment
* Resolves [GitHub Issue #1127](https://github.com/FusionAuth/fusionauth-issues/issues/1127)
* Twitter IdP Login API can optionally accept an access token. When building your own login page, if you complete the initial step with Twitter and utilize the `oauth_verifier` to perform some initial processing of the Twitter user, you may now still send the access token in the form of `oauth_token` and `oauth_token_secret` to FusionAuth to complete the login. This is done by omitting the `oauth_verifier` on the Login request. See [Complete the Twitter Login](/docs/apis/identity-providers/twitter#complete-the-twitter-login) for additional information.
* Resolves [GitHub Issue #1073](https://github.com/FusionAuth/fusionauth-issues/issues/1073)
* When Key Master generates a `kid` because one is not provided on the request, if there is a public key, generate the `kid` as a JWK thumbprint instead of a randomly generated value.
* Resolves [GitHub Issue #1136](https://github.com/FusionAuth/fusionauth-issues/issues/1136)
* When using the Search feature in the FusionAuth admin UI, once you begin searching using a specific term or any of the advanced controls, the pagination result total will be an accurate representation of the number of matches returned by Elasticsearch. When no search criteria is provided, the number of matches will cap at the default value of 10,000 and the pagination results will indicate 10,000+ which means at least 10,000 users match the search criteria.
### Internal
* Upgrade Tomcat from version `8.5.57` to `8.5.63`.
* Resolves [GitHub Issue #1119](https://github.com/FusionAuth/fusionauth-issues/issues/1119)
### Known Issues
* If you are using Elasticsearch version 6 you may encounter an error when using the Search API. This is due to a change in how we optionally request the document hit count in the search request to Elasticsearch. The change is not compatible with Elasticsearch version 6. As a work around, you can set `accurateTotal=true` in the API request.
* Resolved in `1.25.0`, see [GitHub Issue #1135](https://github.com/FusionAuth/fusionauth-issues/issues/1135) for additional details.
### Security
* More consistent usage of the `Cache-Control` HTTP response header. The default for all pages will be `Cache-Control: no-cache`, and some pages that may contain potentially sensitive information such as the API key add, edit or index pages will use a `Cache-Control: no-store`. No known vulnerability exists with the previous behavior, this is just a proactive change to limit the possible mis-use of cached pages in the FusionAuth admin UI.
* Resolves [GitHub Issue #1103](https://github.com/FusionAuth/fusionauth-issues/issues/1103)
* A vulnerability in an underlying SAML v2 library was resolved. If you are using SAML please upgrade FusionAuth to 1.24.0 or later as soon as possible.
* [CVE-2021-27736](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27736)
* [CSNC-2021-004](https://www.compass-security.com/fileadmin/Research/Advisories/2021-03_CSNC-2021-004_FusionAuth_SAML_Library_XML_External_Entity.txt)
### Changed
* The `applicationId` and `roles` claims are no longer returned in the `id_token` issued when requesting the `openid` scope. The `id_token` should not be used for authorization, this change makes it less likely to mis-use this token. If you have a requirement for these claims (you shouldn't), you can add them back by using a JWT Populate lambda. See [Id Token claims](/docs/lifecycle/authenticate-users/oauth/tokens#id-token) for additional information.
* Resolves [GitHub Issue #1102](https://github.com/FusionAuth/fusionauth-issues/issues/1102)
### Fixed
* When using the Add or Edit Identity Provider forms in the admin UI, if you have ~2,000 or more applications it is possible for the form request to be truncated by the underlying application server. This error is caused by the maximum number of request parameters being exceeded. This form in particular, along with the Group Add/Edit and Webhook Add/Edit contains a number of fields that is a function of the number of applications configured. An informational error may be written to the system log indicating this truncation has occurred, but no hard error would have occurred. The symptom will be that depending upon your configuration, a portion of it may be lost during this form submit. The entry in the log will contain this message `org.apache.tomcat.util.http.Parameters.processParameters More than the maximum number of request parameters (GET plus POST) for a single request ([10,000]) were detected. Any parameters beyond this limit have been ignored.`.
* Resolves [GitHub Issue #1057](https://github.com/FusionAuth/fusionauth-issues/issues/1057)
* When you have registered a custom plugin for password hashing, using the View Tenant dialog may fail to render.
* Resolves [GitHub Issue #1063](https://github.com/FusionAuth/fusionauth-issues/issues/1063)
* Unable to remove a User from a Group using the admin UI dialog. This was a regression issue introduced in version 1.23.0.
* Resolves [GitHub Issue #1081](https://github.com/FusionAuth/fusionauth-issues/issues/1081)
* If a user was not currently in the Elasticsearch index, the user delete request may fail.
* Resolves [GitHub Issue #1088](https://github.com/FusionAuth/fusionauth-issues/issues/1088)
* The JWT returned from the Register API when you are creating a User and a Registration in one request may not contain the `roles` claim. This occurs when you do not assign the roles explicitly on the request, and instead are using default role assignment in the application configuration.
* Resolves [GitHub Issue #1106](https://github.com/FusionAuth/fusionauth-issues/issues/1106)
* Updating a User that has existing group memberships may no longer be searchable in Elasticsearch by their Group memberships until the next time the user logs into FusionAuth.
* Resolves [GitHub Issue #1087](https://github.com/FusionAuth/fusionauth-issues/issues/1087)
* A Kafka Producer configuration that contains an equals sign `=` in the property value will fail to parse. This was identified in attempting to configure credentials to connect to CloudKarafka.
* Resolves [GitHub Issue #1107](https://github.com/FusionAuth/fusionauth-issues/issues/1107), thanks to [@chris-bridges](/community/forum/user/chris-bridges) for letting us know!
### Enhancements
* Support a Kickstart file with only a `licenseId`. Previously at least one API key was required because the intent of Kickstart is to call one or more APIs. While there is not a very practical use case for only providing a `licenseId` and no API requests, this minimal configuration will no longer fail indicating an API key is required. See [Set your License Id](/docs/get-started/download-and-install/development/kickstart#set-your-license-id) in the [Kickstart](/docs/get-started/download-and-install/development/kickstart) documentation.
* Resolves [GitHub Issue #1080](https://github.com/FusionAuth/fusionauth-issues/issues/1080)
* You may now import an RSA certificate with a key bit length less than `2048` into Key Master. The minimum supported RSA key length for signing a JWT is `2048`, so this was previously the minimum requirement to import anything into Key Master. However, we have several configurations now that require a certificate that is only used to verify a signature from a third party. In these cases, we are not using the certificate to sign anything, and [@trevorr](https://github.com/trevorr) rightly pointed out that we should allow smaller keys to be imported to support these use cases. Thank you for the (now obvious) insight! We really appreciate our community members that provide us value for value.
* Resolves [GitHub Issue #1085](https://github.com/FusionAuth/fusionauth-issues/issues/1085) & [GitHub Issue #1091](https://github.com/FusionAuth/fusionauth-issues/issues/1091)
* Added an additional Search API parameter to allow you to obtain the actual hit count from Elasticsearch. For performance reasons, the default behavior of an Elasticsearch query is to limit the hit count to 10,000. This means that if your query matched more than 10,000 records, the API response will only indicate that at least 10,000 records matched. This is very adequate for pagination purposes, or general queries. There are times where you are building a very specific query and the intent is to identify an accurate number of matching records. You may now provide an additional parameter to the search request named `accurateTotal` which will then return an accurate hit count on the API response. See the [User Search](/docs/apis/users#search-for-users) API for additional details.
* Resolves [GitHub Issue #1086](https://github.com/FusionAuth/fusionauth-issues/issues/1086)
* Allow the user to click on the Enabled column in the Webhook event configuration in the Webhook and Tenant configurations to enable or disable all events at once. This is just a usability enhancement to save you from clicking over and over. You're welcome.
* Resolves [GitHub Issue #1093](https://github.com/FusionAuth/fusionauth-issues/issues/1093)
* For pages with potentially a lot of items such as Applications, Tenants, etc - that do not currently have pagination, add a count at the bottom of the panel. This allows you to look smart by knowing how many "things" you have without having to count them yourself.
* Resolves [GitHub Issue #1104](https://github.com/FusionAuth/fusionauth-issues/issues/1104)
### Internal
* Some enhancements to JavaScript event handlers to perform better on pages with 2-3k+ applications. Pretty boring.
* Resolves [GitHub Issue #1105](https://github.com/FusionAuth/fusionauth-issues/issues/1105)
### Fixed
* A tenant delete request may fail. See details in the linked GH issue for a work around. This issue was introduced in version 1.22.0.
* Resolves [GitHub Issue #1075](https://github.com/FusionAuth/fusionauth-issues/issues/1075)
### Fixed
* A bug in the PostgreSQL migration will cause you to lose your SAML v2 IdP configuration. If you are using MySQL or you are not using the SAML v2 IdP configuration, this bug will not affect you. The issue was introduced in version 1.21.0, so if you are upgrading from a version prior to 1.21.0 to 1.23.2 you will not be affected. If you have already upgraded to 1.21.0 or any version greater than 1.21.0 prior to this patch, you will have already encountered the issue. If you do encounter this issue, you will need to update the SAML v2 IdP configuration found in each affected Application configuration.
* Resolves [GitHub Issue #1074](https://github.com/FusionAuth/fusionauth-issues/issues/1074)
### Fixed
* When configured to sign the SAML v2 AuthN requests to the SAML v2 IdP, the SAML v2 SP metadata does not correctly reflect this settings. The attribute `AuthnRequestsSigned` should now reflect the signing configuration.
* When configured to sign requests, the SP metadata response will now also contain the KeyDescriptor element to describe the X.509 certificate used to verify the signature.
* Resolves [GitHub Issue #1067](https://github.com/FusionAuth/fusionauth-issues/issues/1067)
### Known Issues
* If you are upgrading to this version, are using PostgreSQL, and you intend to use the provided LinkedIn Reconcile lambda, you will need to make a small adjustment prior to using it.
* Navigate to Customizations -> Lambdas and edit the lambda named `Default LinkedIn Reconcile provided by FusionAuth` and click edit. You will see an error indicated by a red dot on line `23` of the function body. To fix this error, delete the two empty lines between the end of line `23` and `25`, once the error indicator is gone, save the lambda.
* Unable to remove a User from a group using the admin UI dialog.
* Fixed in version 1.24.0 via [GitHub Issue #1081](https://github.com/FusionAuth/fusionauth-issues/issues/1081)
### Fixed
* A validation error may not be visible when selecting self service registration options when the FusionAuth license has not been activated.
* Resolves [GitHub Issue #951](https://github.com/FusionAuth/fusionauth-issues/issues/951)
* The User Action API was returning a `200` status code instead of a `404` when requesting an action by Id that did not exist.
* Resolves [GitHub Issue #991](https://github.com/FusionAuth/fusionauth-issues/issues/991), thanks to [@hkolbeck-streem](https://github.com/hkolbeck-streem) for the report!
* The IP address shown on the About panel may be the same for each node when viewed on a multi-node FusionAuth instance. This address is shown for informational purposes and was only a cosmetic defect w/out any functional issues.
* Resolves [GitHub Issue #1030](https://github.com/FusionAuth/fusionauth-issues/issues/1030)
* The SAML Response XML was failing XSD validation for the `Signature` element location when the request was not successful, or FusionAuth was configured to sign the response instead of the assertion.
* Resolves [GitHub Issue #1047](https://github.com/FusionAuth/fusionauth-issues/issues/1047), thanks to [@MrChrisRodriguez](https://github.com/MrChrisRodriguez) for the excellent report!
* Fix a possible NPE when making an Update request to a group in a multi-tenant environment. With this fix, the correct API response will be returned.
* Resolves [GitHub Issue #1052](https://github.com/FusionAuth/fusionauth-issues/issues/1052), thanks to [@atrauzzi](https://github.com/atrauzzi) for the report!
* When creating an IdP from the API for Google, Facebook, Twitter, or HYPR - the API was allowing an Id to be provided. Each of these IdP types of which only one are allowed, have a fixed Id that is managed by FusionAuth. The API should ignore the requested Id and set the correct Id instead. If you encounter this issue, the work around is to omit the Id on the API request.
* Resolves [GitHub Issue #1058](https://github.com/FusionAuth/fusionauth-issues/issues/1058)
* Kickstart fails when using a variable in the `tenantId` field for an API key.
* Resolves [GitHub Issue #1060](https://github.com/FusionAuth/fusionauth-issues/issues/1060), thanks to [@rhofland](https://github.com/rhofland) for the report and the excellent recreate steps!
### New
* Sign in with LinkedIn. A new identity provider type is available for LinkedIn.
* Resolves [GitHub Issue #34](https://github.com/FusionAuth/fusionauth-issues/issues/34)
* New FusionAuth roles oriented for Level 1 support personnel. These new roles are named `user_support_viewer` and `user_support_manager`, see FusionAuth application roles for additional detail.
* Resolves [GitHub Issue #1027](https://github.com/FusionAuth/fusionauth-issues/issues/1027)
### Enhancements
* Updates to the User and Import API to provide validation on the length of an email address. This will provide a developer a better error when the provided email address is too long.
* Resolves [GitHub Issue #900](https://github.com/FusionAuth/fusionauth-issues/issues/900)
### Client libraries
* Enhancements to the .NET Core client library to better support requests in a multi-tenant environment and to use the `IDictionary` reference instead of `Dictionary`.
* Resolves [GitHub Issue #1049](https://github.com/FusionAuth/fusionauth-issues/issues/1049) and [GitHub Issue #1050](https://github.com/FusionAuth/fusionauth-issues/issues/1050), thanks to [@atrauzzi](https://github.com/atrauzzi) for sharing his .NET Core expertise!
### Fixed
* When using a connector, if the provided password does not meet the configured password constraints the login attempt will fail. This is by design, however because FusionAuth is not the Source of Record (SoR) it should not be required that the password to meet the configured password constraints. The current SoR should enforce their own password constraints. If the connector is configured to migrate the user, and the tenant policy is configured to validate password constraints on login, the password will be validated according to this policy.
* Resolves [GitHub Issue #1020](https://github.com/FusionAuth/fusionauth-issues/issues/1020), thanks to [@ckolbeck-streem](https://github.com/ckolbeck-streem) for the help!
* Using the Verify Email workflow on the FusionAuth themed pages when the email address has a plus sign (`+`) in the local part of the address may fail to send the user an email.
* Resolves [GitHub Issue #1034](https://github.com/FusionAuth/fusionauth-issues/issues/1034)
### Fixed
* When endpoint discovery is disabled, OpenID Connect endpoint validation errors may be hidden when editing the OpenID Connect IdP configuration in the UI.
* Resolves [GitHub Issue #794](https://github.com/FusionAuth/fusionauth-issues/issues/794)
* The Manage User page may fail to render when the user has an action or comment made by a user without an email address.
* Resolves [GitHub Issue #1012](https://github.com/FusionAuth/fusionauth-issues/issues/1012), nice catch by [@pamcpd](https://github.com/pamcpd)!
* The `tenantId` parameter may not be preserved correctly in a multi-tenant configuration during the Device authorization grant.
* Resolves [GitHub Issue #1016](https://github.com/FusionAuth/fusionauth-issues/issues/1016), thanks to [@JediSquirrel](https://github.com/JediSquirrel) and [@jerryhopper](https://github.com/jerryhopper) for reporting!
### Enhancements
* Limit the origin validation during OAuth2 grants that occur as a result of a redirect from FusionAuth.
* Resolves [GitHub Issue #1018](https://github.com/FusionAuth/fusionauth-issues/issues/1018), thanks to our Icelandic friend [@eirikur-grid](https://github.com/eirikur-grid) for reporting.
* Expose the default signing key Id as a Kickstart variable. See the [Kickstart installation guide](/docs/get-started/download-and-install/development/kickstart#reference) for additional detail.
* Resolves [GitHub Issue #1026](https://github.com/FusionAuth/fusionauth-issues/issues/1026), thanks to [@dan-barrett](https://github.com/dan-barrett) for the request!
### Changed
* The Application and Tenant domain objects now contain a `state` field that will be returned on the API response.
* This new `state` field replaces the `active` boolean on the Application object and API. The `active` field is now deprecated, and backwards compatibility will be preserved.
### Fixed
* When viewing a form in the UI, the required column value may not be correct.
* Resolves [GitHub Issue #975](https://github.com/FusionAuth/fusionauth-issues/issues/975)
* Unable to request a second 2FA code on the themed login page during a 2FA login request. See the linked GitHub isssue for a work around.
* Resolves [GitHub Issue #980](https://github.com/FusionAuth/fusionauth-issues/issues/980), thanks to [@DaviddH](https://github.com/DaviddH) for reporting the issue!
* A missing message may cause an exception during a login attempt when using an LDAP connector.
* Resolves [GitHub Issue #981](https://github.com/FusionAuth/fusionauth-issues/issues/981), thanks to [@ruckc](https://github.com/ruckc) for letting us know.
* Incorrect message shown on a registration form when no fields have been added, this is purely a cosmetic issue.
* Resolves [GitHub Issue #983](https://github.com/FusionAuth/fusionauth-issues/issues/983)
* The view dialog for an a Google IdP incorrectly shows the client secret for both the Client Id and the Client secret fields.
* Resolves [GitHub Issue #999](https://github.com/FusionAuth/fusionauth-issues/issues/999)
* Selecting a preferred language during login may append this value to the user's configuration allowing for possible duplicate locales.
* Resolves [GitHub Issue #1006](https://github.com/FusionAuth/fusionauth-issues/issues/1006), thanks to [@arni-inaba](https://github.com/arni-inaba) for reporting the issue.
* Using the Import API to import users to a tenant other than the default tenant when more than one tenant is configured may fail validation. This issue was introduced in version 1.20.0 under [GitHub Issue #915](https://github.com/FusionAuth/fusionauth-issues/issues/915).
* Resolves [GitHub Issue #1008](https://github.com/FusionAuth/fusionauth-issues/issues/1008)
* Logging out of FusionAuth SSO when you have a webhook configured to receive the Refresh Token Revoke event, may cause an exception that will be found in an event log.
* Resolves [GitHub Issue #1017](https://github.com/FusionAuth/fusionauth-issues/issues/1017)
### New
* The Elasticsearch index name can now be configured. This may be helpful if you wish to run multiple instances of FusionAuth on the same Elasticsearch cluster. See `fusionauth-app.user-search-index.name` in the FusionAuth configuration for additional details.
* Resolves [GitHub Issue #631](https://github.com/FusionAuth/fusionauth-issues/issues/631), thanks to [@chrishare08](https://github.com/chrishare08) for the suggestion.
* Add async support for the Delete Tenant API. Deleting a tenant can take a very long time, so when deleting a tenant from the UI, FusionAuth will use the new async option. If you are making an API request to delete a tenant with many users, you may wish to use the async option. See the Tenant API for additional details.
* Resolves [GitHub Issue #990](https://github.com/FusionAuth/fusionauth-issues/issues/990)
### Enhancements
* The Elasticsearch reindex operation is now much faster, especially when re-indexing more than 1 million users. On a reasonably fast system, 1 million users can be re-indexed in approximately 3 minutes, this time is linear as you increase the user count. In general there is no need to re-index in production, but in a development phase or as part of a database migration it may be necessary to re-index the FusionAuth users.
* Resolves [GitHub Issue #918](https://github.com/FusionAuth/fusionauth-issues/issues/918)
* When configuring an IdP that requires additional CORS configuration to operate properly, FusionAuth will display a warning message in the UI. This message has been updated to make it clearer that additional user action isn't required to complete the configuration.
* Resolves [GitHub Issue #998](https://github.com/FusionAuth/fusionauth-issues/issues/998)
* Increase the read timeout to third party identity providers. It has been reported that the Apple identity provider in particular may experience a read timeout for particular accounts.
* Resolves [GitHub Issue #1010](https://github.com/FusionAuth/fusionauth-issues/issues/1010), thanks to [@thekoding](https://github.com/thekoding) for the suggestion.
## Known Issues
* If you are using PostgreSQL and you are using FusionAuth as a SAML v2 IdP, upgrading to this version will break your SAML v2 IdP configuration. Resolved in 1.23.2.
* If you are running FusionAuth prior to this version, skip to 1.23.2 to avoid the issue. If you need to update to this version or any version after this version but prior to 1.23.2, you will want to record your existing SAML v2 IdP configuration for each application with SAML v2 IdP enabled so that you can re-configure after the upgrade has completed.
### Fixed
* Beginning in version 1.9.0, if you are using the SAML IdP configuration to connect to a third party SAML v2 IdP and you are not using the FusionAuth login pages, you must initiate this request with FusionAuth by using the [Start Login Request](/docs/apis/identity-providers/samlv2#start-a-saml-v2-login-request) API. When making this start request w/out any additional custom data on the API request, an exception may occur. Review the linked issue for a workaround if you are unable to update to this patch release.
* Resolves [GitHub Issue #963](https://github.com/FusionAuth/fusionauth-issues/issues/963)
* Using Bcrypt as the default hashing scheme may cause an exception to occur in some circumstances.
* [GitHub Issue #966](https://github.com/FusionAuth/fusionauth-issues/issues/966), thanks to [@wasdennnoch](https://github.com/wasdennnoch) for reporting the issue and providing great debug info.
* Add custom data on the Consent object to the view dialog in the UI, and fix some possible issues with editing Consent and other similar objects with custom data in the UI. In some cases, editing an object such as a Consent in the UI will cause you to lose any custom data you had previously stored.
* Resolves [GitHub Issue #970](https://github.com/FusionAuth/fusionauth-issues/issues/970), thanks to [@mgetka](https://github.com/mgetka) for opening this issue.
### Enhancements
* The location of the XML signature in the SAML response may be configured to be a child of the `Assertion` element, or the `Response`. The default location is `Assertion` which is the same as the previous behavior to ensure backwards compatibility. In most cases the default configuration is adequate, if you have a SAML v2 Service Provider that requires the signature as a child element of the Response use this configuration to satisify this requirement.
* Resolves [GitHub Issue #365](https://github.com/FusionAuth/fusionauth-issues/issues/365), thanks to [@mikerees](https://github.com/mikerees) for requesting this feature.
* The PKCE extension will now be used by the OpenID Connect IdP configuration that allows you to connect to third party OpenID Connect identity providers. This allows FusionAuth to be compatible with identity providers that may require PKCE. This change is compatible even if your identity provider does not require or does not support PKCE.
* [GitHub Issue #968](https://github.com/FusionAuth/fusionauth-issues/issues/968), thanks to [@jandillmann](https://github.com/jandillmann) for the request!
* Add the `application` domain object to email templates when available. This will allow you to use the Application name using `${application.name}` in your template.
* Resolves [GitHub Issue #976](https://github.com/FusionAuth/fusionauth-issues/issues/976)
### Fixed
* UI sorting preferences were not preserved after a page refresh
* Resolves [GitHub Issue #461](https://github.com/FusionAuth/fusionauth-issues/issues/461), thanks to [@mreschke](https://github.com/mreschke) (a fellow Coloradan) for letting us know!
* Update a tooltip to better describe the use of Require authentication in the OAuth settings
* Resolves [GitHub Issue #654](https://github.com/FusionAuth/fusionauth-issues/issues/654), thanks to [@JuliusPC](https://github.com/JuliusPC) for the suggestion.
* A exception may occur if you attempt to change your password immediately after installation before modifying the Tenant configuration to configure email, JWT settings etc.
* Resolves [GitHub Issue #758](https://github.com/FusionAuth/fusionauth-issues/issues/758), thanks to [@srothery](https://github.com/srothery) for the report and debug assistance!
* Providing duplicate connector policies on the Tenant API may cause an exception
* Resolves [GitHub Issue #917](https://github.com/FusionAuth/fusionauth-issues/issues/917)
* Set the Twitter tokens in the User Registration after logging in with Twitter
* Resolves [GitHub Issue #937](https://github.com/FusionAuth/fusionauth-issues/issues/937), thanks to [@LohithBlaze](https://github.com/LohithBlaze) for reporting the bug.
* Allow the Refresh Token meta data fields to be set during the Password Grant
* Resolves [GitHub Issue #947](https://github.com/FusionAuth/fusionauth-issues/issues/947), thanks to [@ShayMoshe](https://github.com/ShayMoshe) for letting us know about this limitation.
### Enhancements
* Add additional Kickstart settings to modify the default timeouts used to make API calls to FusionAuth.
* Resolves [GitHub Issue #803](https://github.com/FusionAuth/fusionauth-issues/issues/803), thanks to [@seanadkinson](https://github.com/seanadkinson) for the suggestion!
* Expose default Lambda and Form Ids to Kickstart so you can assign one of the default Lambdas to an identity provider configuration.
* Resolves [GitHub Issue #836](https://github.com/FusionAuth/fusionauth-issues/issues/836), thanks to [@LohithBlaze](https://github.com/LohithBlaze) for letting us know about this limitation.
* Return the `encryptionScheme` on the User API response when authenticated using an API key.
* Resolves [GitHub Issue #955](https://github.com/FusionAuth/fusionauth-issues/issues/955)
### Changed
- Updated base image for Docker from `alpine` to `ubuntu:focal`. This is a non-functional change, but please be aware of this change if you're building Docker images using ours as a base.
In order to run on `alpine` without including the GNU C Library (`glibc`) we had to use a custom build of OpenJDK compiled using the `musl` C library. Due to some possible performance concerns, we have moved to an official build of JDK provide by AdoptOpenJDK compiled using `glibc`. The `ubuntu:focal` base image added ~ 30 MB in size compared to our previous (compressed) image size, but until we can obtain builds from AdoptOpenJDK based upon the `musl` C library, we will not likely ship an official image on `alpine`.
* [`fusionauth-containers` / `docker` / `fusionauth` / `fusionauth-app` / `Dockerfile`](https://github.com/FusionAuth/fusionauth-containers/blob/main/docker/fusionauth/fusionauth-app/Dockerfile)
* [`hub.docker.com` / `fusionauth` / `fusionauth-app`](https://hub.docker.com/r/fusionauth/fusionauth-app/tags)
### Fixed
* Resolve a warning message about an upcoming deprecated use of reflection in a FusionAuth dependency. This warning message was not causing any failures, it was just noisy.
* Resolves [GitHub Issue #721](https://github.com/FusionAuth/fusionauth-issues/issues/721)
* A negative count may be displayed in the FusionAuth dashboard and other reports. This was primarily due to how the delete tenant was handled as it related to keeping track of total user counts. The delete tenant code path no longer utilizes the Elasticsearch index and takes a safer approach to deleting users and keeping track of total counts.
* Resolves [GitHub Issue #799](https://github.com/FusionAuth/fusionauth-issues/issues/799), thanks to [@gurupras](https://github.com/gurupras) for helping us out with this one!
* Better user experience for advanced self service forms once a license has been de-activated.
* Resolves [GitHub Issue #861](https://github.com/FusionAuth/fusionauth-issues/issues/861)
* Fix self service registration form validation when using custom options with a `select`, `radio` or `checkbox.`
* Resolves [GitHub Issue #863](https://github.com/FusionAuth/fusionauth-issues/issues/863)
* Resolves [GitHub Issue #865](https://github.com/FusionAuth/fusionauth-issues/issues/865)
* Resolves [GitHub Issue #867](https://github.com/FusionAuth/fusionauth-issues/issues/867)
* Fix UI form validation when adding and removing fields from an existing self service registration from.
* Resolves [GitHub Issue #866](https://github.com/FusionAuth/fusionauth-issues/issues/866)
* The `applicationId` was not validated on the Import User API, the import would still correctly fail, just not in a developer friendly way.
* Resolves [GitHub Issue #915](https://github.com/FusionAuth/fusionauth-issues/issues/915)
* Fix a typo the Activate Reactor page in the UI.
* Resolves [GitHub Issue #945](https://github.com/FusionAuth/fusionauth-issues/issues/945)
* When using self service registration, the `authenticationType` claim found in the resulting JWT was always `PASSWORD` even if the authentication was performed using Facebook, Google or other identity provider.
* Resolves [GitHub Issue #948](https://github.com/FusionAuth/fusionauth-issues/issues/948)
### New
- Support for SAML v2 POST bindings to a third party SAML v2 Identity Provider (IdP) when FusionAuth is acting as the SAML v2 Service Provider (SP).
* Resolves [GitHub Issue #845](https://github.com/FusionAuth/fusionauth-issues/issues/845)
- Add the SAML v2 `SessionIndex` in the SAML v2 AuthN request.
* Resolves [GitHub Issue #896](https://github.com/FusionAuth/fusionauth-issues/issues/896)
- You may now customize the Add and Edit form used to manage users in the FusionAuth admin UI. You may add or remove existing fields found on the User form, or add new fields to allow n admin to manage custom user data. This can be used with advanced self service registration, or as a standalone feature.
* This feature requires a paid FusionAuth plan.
* Resolves [GitHub Issue #753](https://github.com/FusionAuth/fusionauth-issues/issues/753)
- You may now customize the Add and Edit User Registration form used to manage user registration in the FusionAuth admin UI. You may add or remove existing fields found on the User Registration form, or add new fields to allow an admin to manage custom registration data. This can be used with advanced self service registration, or as a standalone feature.
* This feature requires a paid FusionAuth plan.
* Resolves [GitHub Issue #753](https://github.com/FusionAuth/fusionauth-issues/issues/753)
### Enhancements
* When configuring FusionAuth as the SAML v2 IdP, you may not configure one to many redirect URLs, also referred to as Assertion Consumer Service (ACS) URLs. This will allow you to support more than one redirect configuration per FusionAuth application.
* Resolves [GitHub Issue #502](https://github.com/FusionAuth/fusionauth-issues/issues/502)
* When using more then one tenant the `tenantId` is documented to be required when using the OAuth2 endpoints. However, in some cases it may not be provided, this enhancement allows the correct tenant to be identified during logout when only the `id_token_hint` is provided on the request to `/oauth2/logout` endpoint. This issue only affects FusionAuth versions `1.19.0` and greater due to the addition to multi-tenant SSO. Prior to version `1.19.0`, it was not possible to be logged into more than one tenant at once using FusionAuth SSO.
* Resolves [GitHub Issue #925](https://github.com/FusionAuth/fusionauth-issues/issues/925)
* Initial build support for multi-arch Docker images. FusionAuth is not yet publishing images for these additional arch types, but we are trying to better support these builds in our base image definition. This should help those running FusionAuth on IBM z(s390x), IBM Power(64 bit PowerPC) and various ARM platforms including AWS Graviton, Apple Bionic and embedded platforms such as Raspberry Pi.
Thanks to a bunch of our FusionAuth MVPs including, but not limited to [@jerryhopper](https://github.com/jerryhopper), [@arslanakhtar61](https://github.com/arslanakhtar61), and [@ceefour](https://github.com/ceefour), for helping with this work through code, advice and domain knowledge that we don't have!
* [`fusionauth-containers` / `docker` / `fusionauth` / `fusionauth-app` / Dockerfile](https://github.com/FusionAuth/fusionauth-containers/blob/main/docker/fusionauth/fusionauth-app/Dockerfile)
* [Multi-Architecture Builds](https://github.com/FusionAuth/fusionauth-containers#multi-architecture-builds)
* [GitHub \[fusionauth-containers\] Issue #49](https://github.com/FusionAuth/fusionauth-containers/issues/49)
### Fixed
* The documented configuration parameter `fusionauth-app.http.port` is not picked up by FusionAuth. If you were to override the default value of `9011`, the server will properly bind to the correct port, but FusionAuth will not use this local port to connect to itself.
* Resolves [GitHub Issue #891](https://github.com/FusionAuth/fusionauth-issues/issues/891)
* When importing users using the Import API on PostgreSQL, if you have a wide distribution of values for the `insertInstant` on the User object, you may encounter a PostgreSQL exception.
* Resolves [GitHub Issue #892](https://github.com/FusionAuth/fusionauth-issues/issues/892)
* Disable Elasticsearch Sniffer by default. The Elasticsearch Sniffer was enabled in version 1.19.0 to allow a single connection to Elasticsearch discover the other nodes in the cluster by the Elasticsearch REST client. This causes problems for cloud managed services or Elasticsearch running within a container service such as k8s. Turn this off by default, and allow it to be enabled if desired. See new configuration property `search.sniffer`.
* Resolves [GitHub Issue #893](https://github.com/FusionAuth/fusionauth-issues/issues/893)
### Enhancements
* Add a `referrer` meta tag to provide a default policy for the browser. Most browsers are now providing a decent default value, but this will ensure a secure default value is utilized. New Themes will default to `strict-origin` but this can be modified in the Helper template, and can also be added to existing themes.
* Resolves [GitHub Issue #894](https://github.com/FusionAuth/fusionauth-issues/issues/894)
### Fixed
* The default exception handling in the Elasticsearch REST client allows for some expected exceptions to go un-handled which may fail the search request. Add an exception handler to keep these underlying HTTP exceptions from causing failures.
* Resolves [GitHub Issue #868](https://github.com/FusionAuth/fusionauth-issues/issues/868), thanks to [@zbruhnke](https://github.com/zbruhnke) for reporting and helping us track this one down.
* Some LDAP exception messages will include an embedded `null` in the message body. PostgreSQL does not allow for embedded `null` characters in a text field, so this may cause FusionAuth to exception when using PostgreSQL.
* Resolves [GitHub Issue #879](https://github.com/FusionAuth/fusionauth-issues/issues/879)
* When selecting Re-validate password on login when also restricting usage of previous passwords, the user may end up in a loop of being required to change their during login.
* Resolves [GitHub Issue #880](https://github.com/FusionAuth/fusionauth-issues/issues/880)
* In the 1.19.0 MySQL migration script, if you have many refresh tokens, it is possible that a duplicate key will be generated due to a poor random Id generator.
* Resolves [GitHub Issue #890](https://github.com/FusionAuth/fusionauth-issues/issues/890)
### Enhancements
* Add a helper for Active Directory LDAP to handle conversion of a base64-encoded Microsoft `objectGuid` to a Java UUID. See the [LDAP Connector Reconcile Lambda](/docs/extend/code/lambdas/ldap-connector-reconcile) for more information.
* Resolves [GitHub Issue #822](https://github.com/FusionAuth/fusionauth-issues/issues/822), thanks to [@bradleykite](https://github.com/bradleykite) for the assistance on this one!
### Fixed
* Startup may fail on version 1.19.5 of the FusionAuth docker image with the following error on the console `setenv.sh: line 91: : invalid variable name`.
* Resolves [GitHub Issue #870](https://github.com/FusionAuth/fusionauth-issues/issues/870), thanks to [@virginijus-servicebridge](https://github.com/virginijus-servicebridge), [@arunmg007](https://github.com/arunmg007) and [@mao75](https://github.com/mao75) for reporting!
### Fixed
* When deleting an application role that is in use by a Group, an exception occurs.
* Resolves https://github.com/FusionAuth/fusionauth-issues/issues/831
* Fix possible errors when upgrading to version 1.19.0 on managed MySQL services such as Google Cloud SQL.
* Resolves https://github.com/FusionAuth/fusionauth-issues/issues/859
### Enhancements
* Be more forgiving and allow for un-escaped URL path and query characters.
* Resolves https://github.com/FusionAuth/fusionauth-issues/issues/635
### Fixed
* When using a JWT populate, the JWT returned during a combination User + Registration API request may not have the `registration` or `roles` arguments available in the lambda. This issue was introduced in version `1.16.0`.
* [GitHub Issue #856](https://github.com/FusionAuth/fusionauth-issues/issues/856), thanks to [@calebfreeman](https://github.com/calebfreeman) for reporting.
* When using MySQL and Silent Mode database configuration, you may encounter an error indicating `java.lang.IllegalStateException: Unable to capture database lock.` or `Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql://...`. This issue was introduced in version `1.19.0`, if you encounter this error, please upgrade. If you are unable to upgrade, attempt to startup w/out silent mode and go through maintenance mode interactively.
* Resolves [GitHub Issue #857](https://github.com/FusionAuth/fusionauth-issues/issues/857), thanks to [@ceefour](https://github.com/ceefour) for letting us know.
### Security
* Proactively upgrade third party dependency due to published CVEs.
* Upgrade Apache Commons File Upload to `1.4.0`
* https://www.cvedetails.com/cve/CVE-2016-1000031/
### Changes
* Upgraded Kafka client to `2.6.0`
* Upgrade MySQL connector to `8.0.21`
* If you are using MySQL, and are currently re-packaging the MySQL connector in a Docker image or similar strategy to keep this jar from being downloaded at runtime, you will need to update your version to match FusionAuth.
* Upgrade your MySQL connector to 8.0.21, the `mysql-connector-java-8.0.21.jar` will be expected to be found here ` /usr/local/fusionauth/fusionauth-app/apache-tomcat/lib`.
* Upgrade PostgreSQL connector to `42.2.14`
### Fixed
* The clock skew calculation used then verifying a SAML AuthN response from a SAML v2 IdP may incorrectly cause a validation error. If you encounter this error you may see something like this `Unable to verify the [audience] attribute. The attribute cannot be confirmed until [2020-09-01T16:01:31+0000].` in the Debug or Error Event Log associated with the SAML v2 login request.
### Enhancements
* Better email address validation to ensure the address will be deliverable.
### Fixed
* Using the External JWT Identity Provider with the Lookup API may fail to validate a JWT
* Resolves [GitHub Issue #850](https://github.com/FusionAuth/fusionauth-issues/issues/850)
### Fixed
* If you are using the database search engine, FusionAuth may fail to start up correctly.
* Resolves [GitHub Issue #846](https://github.com/FusionAuth/fusionauth-issues/issues/846), thanks to [@motzel](https://github.com/motzel) for reporting so quickly!
* The legacy environment variable named `FUSIONAUTH_SEARCH_SERVERS` is not honored ahead of the named configuration file property.
* Resolves [GitHub Issue #847](https://github.com/FusionAuth/fusionauth-issues/issues/847), thanks to [@soullivaneuh](https://github.com/soullivaneuh) for letting us know!
Our development team works so hard to bring you cool features and enhancements. Many of the features we build, or the enhancements we make come from the feedback and bug reports we receive from our community.
Thank you to each of you that has taken the time to open a GitHub issue, or raise a concern on our forum. All of this input and feedback is valued, and it makes FusionAuth better!
### Known Issues
* When running MySQL and it is possible you may encounter an issue logging into the FusionAuth admin console after updating to version 1.19.0. The symptom is that upon login you are redirected to an empty page that asks you to return to login.
* See [GitHub Issue #934](https://github.com/FusionAuth/fusionauth-issues/issues/934) for additional details and a work around.
### Changed
There a few changes in this release that you will need to be aware of, please read these carefully. If you have a support contract, please reach out if you have questions or concerns.
* If you using the [SAML v2 Identity Provider Login](/docs/apis/identity-providers/samlv2#complete-a-saml-v2-login) API directly you will need to update your integration. If you are using the SAML v2 Identity Provider configuration with the FusionAuth themed pages, there is no change required.
* The [Start Identity Provider](/docs/apis/identity-providers/samlv2#start-a-saml-v2-login-request) API must now be used prior to sending the SAML v2 AuthN request to the SAML IdP. You may optionally build your own Request Id, or use one generated by FusionAuth. See the Start API for additional details.
* The FusionAuth SSO and admin UI are now stateless and no longer require session pinning to maintain an HTTP session. Leaving existing session pinning in place should not cause any harm, but you may remove it at your earliest convenience.
* Silent Mode may be used while in `production` runtime mode. This allows you to leverage the FusionAuth maintenance mode to upgrade the database schema for `production` and `development` runtime modes.
* The Status API no longer returns a full JSON response unless the request is authenticated by an API key or a FusionAUth admin user.
* The API also now returns several status codes to provide additional insight into possible issues. See [Status](/docs/apis/system#retrieve-system-status) API documentation for additional information.
* When building customized field error messages for custom Registration forms, a field error such as `[missing]user.data.foo` may now be `[blank].user.data.foo`. Note the prefix may have changed from `[missing]` to `[blank]`. If you have created customized values for Registration Forms, please review your error messages and test your existing validation to ensure the correct text is displayed.
* The Linux Debian and RPM packages now ship with a `systemd` service definition instead of the legacy Sys V init scripts. If the distribution of Linux you are using does not support `systemd` you will need to plan to upgrade. In most cases this should not affect anyone running FusionAuth on Linux using the provided RPM or Debian packages as bridge scripts generally allow you to start and stop the commands using a Sys V wrapper. See the Starting and Stopping documentation for additional information.
* When using the python client library, the signature for the `exchange_o_auth_code_for_access_token` method which takes an authorization code has changed. The `client_id` and `redirect_uri` parameters flipped positions. This was done to make the signature consistent with the other client libraries. Instead of `exchange_o_auth_code_for_access_token(self, code, redirect_uri, client_id=None, client_secret=None)`, the method signature is now `exchange_o_auth_code_for_access_token(self, code, client_id, redirect_uri, client_secret=None)`. If you don't flip around the arguments, you'll receive a 401 error, similar to [this issue](https://github.com/FusionAuth/fusionauth-python-client/issues/7).
### Known Issues
* If you are using the database search engine, FusionAuth may fail to start up correctly. Resolved in 1.19.1.
* The legacy environment variable named `FUSIONAUTH_SEARCH_SERVERS` is not honored ahead of the named configuration file property. Resolved in 1.19.1.
### New
* FusionAuth admin UI and FusionAuth pages are now stateless. As of this version you will no longer need to provide session pinning in a multi-node configuration. If you currently have session pinning configured, it should be ok to leave it, but you should plan to remove it at your earliest convenience.
* Resolves [#GitHub #358](https://github.com/FusionAuth/fusionauth-issues/issues/358)
* Multi-tenant SSO. This was a limitation prior to this released due to the way we managed the HTTP session. This limitation has been removed... and there was much rejoicing. With multi-tenant SSO you may now optionally use the same browser and utilize SSO for users within different tenants, this is often only a dev time issue, but there are some production use cases for this behavior.
* Resolves [GitHub Issue #355](https://github.com/FusionAuth/fusionauth-issues/issues/355), thanks to [@unkis](https://github.com/unkis) for opening the issue to help us track this limitation.
* Expanded and improved configuration options. All config options are not consistent and can be set using `fusionauth.properties`, environment variables or Java `-D` system properties. This will make life much easier for those running in Docker or Kubernetes. All previously named configuration options will be backwards compatible and you will receive warnings on how you can correct your naming of configuration values or environment variables, because that's how we roll.
* IdP and Email hinting for the FusionAuth login pages. This feature will allow you to optionally bypass the login page and go directly to the third party IdP based upon the user's email address or a suggested Identity Provider Id. An Identity Provider Id may be provided on the URL using the `idp_hint` request parameter, and an email address or domain may be provided in the `login_hint` request parameter.
* Resolves [GitHub Issue #178](https://github.com/FusionAuth/fusionauth-issues/issues/178), thanks to one of our FusionAuth All-Stars [@davidmw](https://github.com/davidmw) for suggesting this feature.
* A new API to import Refresh Tokens. See [Import Refresh Tokens](/docs/apis/users#import-refresh-tokens) API for additional details.
* Resolves [GitHub Issue #835](https://github.com/FusionAuth/fusionauth-issues/issues/835)
* Application specific email templates for Passwordless, Email Verification, Setup Password, and Change Password. See updates to the [Application](/docs/apis/applications) API and the Application configuration in the FusionAuth admin.
* Resolves [GitHub Issue #834](https://github.com/FusionAuth/fusionauth-issues/issues/834)
* A new icon in cornflower blue.
* I am Jack's complete lack of surprise.
### Enhancements
* Enhanced Maintenance Mode support for initial DB schema setup on 3rd Party cloud managed database services such as Digital Ocean, Azure, etc.
* Resolves [GitHub Issue #95](https://github.com/FusionAuth/fusionauth-issues/issues/95)
* The FusionAuth log `fusionauth-app.log` now ships with a log rotation strategy. This will not affect those running FusionAuth in Docker.
* Resolves [GitHub Issue #575](https://github.com/FusionAuth/fusionauth-issues/issues/575), thanks to [@oottinger](https://github.com/oottinger) and others for reporting and voting on this issue.
* All configuration is not available in the `fusionauth.properties` file, environment variable or Java System Property to allow for additional flexibility in configuration regardless of your deployment model. See the Configuration reference for additional information.
* Resolves [GitHub Issue #752](https://github.com/FusionAuth/fusionauth-issues/issues/752)
* Restrict the response body on the Status API unless authenticated. Provide more granular HTTP response codes to provide insight into the issue.
* Resolves [GitHub Issue #473](https://github.com/FusionAuth/fusionauth-issues/issues/473)
### Fixed
* When using the View dialog for a custom form field in the FusionAuth admin UI, form `Control` type was not displayed.
* Resolves [GitHub Issue #828](https://github.com/FusionAuth/fusionauth-issues/issues/828)
* When submitting a custom Registration Form with non-required fields of type `number`, `date` or `bool`, you may receive a validation error indicating the value is invalid.
* Resolves [GitHub Issue #827](https://github.com/FusionAuth/fusionauth-issues/issues/827)
* Resolves [GitHub Issue #829](https://github.com/FusionAuth/fusionauth-issues/issues/829)
* Unable to configure `database.mysql.enforce-utf8mb4` through an environment variable for use in Docker.
* Resolves [GitHub Issue #798](https://github.com/FusionAuth/fusionauth-issues/issues/798)
* A `404` status code is returned from the Start Passwordless API when more than one tenant exists in FusionAuth.
* Resolves [GitHub Issue #833](https://github.com/FusionAuth/fusionauth-issues/issues/833), thanks to [@atrauzzi](https://github.com/atrauzzi) for reporting and helping us track this one down!
* Normalize the use of the `aud` claim between the OAuth2 grants, Login API and other APIs that may return a JWT. The `aud` claim should always be even when the User is not registered for the application.
* Resolves [GitHub Issue #832](https://github.com/FusionAuth/fusionauth-issues/issues/832), thanks to [@motzel](https://github.com/motzel) for the help!
* Also resolves related issue [GitHub Issue #713](https://github.com/FusionAuth/fusionauth-issues/issues/713)
* Custom Form validation errors and related fixes.
* Resolves [GitHub Issue #827](https://github.com/FusionAuth/fusionauth-issues/issues/827)
* [GitHub Issue #810](https://github.com/FusionAuth/fusionauth-issues/issues/810)
* [GitHub Issue #828](https://github.com/FusionAuth/fusionauth-issues/issues/828)
* [GitHub Issue #829](https://github.com/FusionAuth/fusionauth-issues/issues/829)
* Both the Login Success and Login Failed events are triggered during a failed login attempt. This bug was likely introduced in version 1.18.0.
* Resolves [GitHub Issue #838](https://github.com/FusionAuth/fusionauth-issues/issues/838)
### Security
* Improve SAML AuthN Response validation
### Fixed
* HYPR IdP related fixes.
* When the HYPR authentication workflow begins the provided `loginId` was not properly validated to exist in FusionAuth. All other IdP configurations allow this scenario, but because HYPR provides MFA and is not itself considered by FusionAuth to be a SoR (source or record) the user must first exist in FusionAuth.
* Because HYPR is not a traditional SoR and does not provide user claims to FusionAuth, a `username` or `email` address should behave exactly the same when used to initiate the HYPR MFA workflow.
* Resolves [GitHub Issue #808](https://github.com/FusionAuth/fusionauth-issues/issues/808)
* Resolves [GitHub Issue #809](https://github.com/FusionAuth/fusionauth-issues/issues/809)
### Fixed
* When using self service registration, a JWT populate lambda and the Implicit Grant, the `registration` parameter to the JWT Populate lambda will be `null`.
* Resolves [GitHub Issue #802](https://github.com/FusionAuth/fusionauth-issues/issues/802)
### Fixed
* A JavaScript bug may cause some of the reports not to render correctly in the admin UI.
* Resolves [GitHub Issue #783](https://github.com/FusionAuth/fusionauth-issues/issues/783)
* A poor performing SQL query was found when using MySQL. The query performance will largely be dependant upon your server configuration, but once you exceed 2M+ login records you may realize some performance issues when logging into the FusionAuth admin UI due to the charts displayed on the main dashboard.
* Resolves [GitHub Issue #786](https://github.com/FusionAuth/fusionauth-issues/issues/786)
### Enhancements
* Add localized number formatting on the y-axis of charts in the FusionAuth admin UI.
* Resolves [GitHub Issue #788](https://github.com/FusionAuth/fusionauth-issues/issues/788)
### Fixed
* An exception occurs when you attempt to use a refresh token from tenant A with tenant B.
* Resolves [GitHub Issue #716](https://github.com/FusionAuth/fusionauth-issues/issues/716), thanks to [@ulybu](https://github.com/ulybu) for reporting!
* An exception may occur when using self service registration that will disrupt the user registration workflow.
* Resolves [GitHub Issue #776](https://github.com/FusionAuth/fusionauth-issues/issues/776)
* The registration object is `null` in the JWT Populate function when used with self service registration.
* Resolves [GitHub Issue #780](https://github.com/FusionAuth/fusionauth-issues/issues/780)
* A SAML response that includes an attribute element with the attribute of `xsi:nil="true"` will cause an exception when we try to parse the XML document.
* Resolves [GitHub Issue SAML v2 #1](https://github.com/FusionAuth/fusionauth-samlv2/issues/1)
### Fixed
* When attempting to add a registration for an user in the admin UI, if there are no available registrations to assign after the form has been rendered an exception may occur when you submit the form.
* Resolves [GitHub Issue #630](https://github.com/FusionAuth/fusionauth-issues/issues/630)
* When you have enabled verify email on change and you update a user's email address that was previously undefined, a verification email is not sent.
* Resolves [GitHub Issue #749](https://github.com/FusionAuth/fusionauth-issues/issues/749), thanks to [@EddieWhi](https://github.com/EddieWhi) for letting us know!
* When removing a user's registration, the search index is not updated correctly until the next user index event.
* Resolves [GitHub Issue #750](https://github.com/FusionAuth/fusionauth-issues/issues/750), thanks to [@brennan-karrer](https://github.com/brennan-karrer) for reporting the issue!
* Fixes form field name validation to limit spaces and other special characters.
* Resolves [GitHub Issue #761](https://github.com/FusionAuth/fusionauth-issues/issues/761)
* Form and field fixes including some JavaScript errors and the complete registration workflow when a custom form is used.
* Resolves [GitHub Issue #762](https://github.com/FusionAuth/fusionauth-issues/issues/762)
* The use of `${tenant.issuer}` is failing validation when used in an email template.
* Resolves [GitHub Issue #770](https://github.com/FusionAuth/fusionauth-issues/issues/770), this to [@seanadkinson](https://github.com/seanadkinson) for reporting the bug.
* Email template validation has been relaxed to allow the Preview API and UI action to report errors and warnings but still allow the changes to be saved. Due to the complexity of validating the email template without the exact data to be used at runtime, validation has been relaxed to ensure we do not prohibit a valid template from being saved. When using the UI to manage your templates, you will now find a test button which will allow you to send a template to an end user to test the rendering and delivery with a real user.
### Fixed
* When running with PostgreSQL database and migrating from pre 1.18.0 with existing users, the table sequence may not be set correctly causing new users to fail to be created.
* Resolves [GitHub Issue #759](https://github.com/FusionAuth/fusionauth-issues/issues/759), see issue for details and workaround.
### Fixed
* An issue introduced in version 1.18.0 may cause the edit Application action in the admin UI to fail with a `500` message. Review the known issues of 1.18.0 for a workaround if you are unable to upgrade to version 1.18.1.
* Resolves [GitHub Issue #760](https://github.com/FusionAuth/fusionauth-issues/issues/760), see issue for details and workaround.
### Known Issues
* When editing an application in the admin UI you may encounter a `500 Internal Server Error` error message when attempting to save your changes. As a work around, you may use the API to modify the application. To resolve the issue, please upgrade to version 1.18.1.
* See [GitHub Issue #760](https://github.com/FusionAuth/fusionauth-issues/issues/760) for additional details and workaround.
* If running PostgreSQL database a database sequence may not be set correctly causing a `500` status code when creating new users.
* See [GitHub Issue #759](https://github.com/FusionAuth/fusionauth-issues/issues/759) for additional details and workaround.
* An exception may occur when using self service registration that will disrupt the user registration workflow.
* See [GitHub Issue #776](https://github.com/FusionAuth/fusionauth-issues/issues/776) for additional details.
* A JWT populate lambda that uses the `registration` parameter may fail when using self service registration.
* See [GitHub Issue #780](https://github.com/FusionAuth/fusionauth-issues/issues/780) for additional details.
### Changed
* In the FusionAuth admin UI, Email Templates and Themes are now found under the `Customizations` menu.
### New
* Advanced Forms. Self service registration just got a huge upgrade! Now custom forms may be configured with one to many steps, each step consisting of one to many fields. A registration form may then be assigned to an application in the Self service registration configuration found in the `Registration` tab. Assigning a custom form to an application will require a licensed plan of FusionAuth. More details and documentation coming soon.
* See [Form](/docs/apis/custom-forms/forms) API and [Form Field](/docs/apis/custom-forms/form-fields) API.
* Resolves [GitHub Issue #680](https://github.com/FusionAuth/fusionauth-issues/issues/680).
* Initial Tech Preview of Connectors. Connectors allow you to authenticate against external systems such as LDAP. A generic connector can also be configured to authenticate against any third party system. More details and documentation coming soon. When using a connector, you will utilize the Login API or OAuth frontend of FusionAuth as you normally would and the tenant may configure policies that would cause users to be authenticated against these external databases.
* See [Connector](/docs/apis/connectors/) API.
* Resolves [GitHub Issue #219](https://github.com/FusionAuth/fusionauth-issues/issues/219).
### Enhancement
* When viewing the Application view dialog, an additional property named `Registration URL` will be provided in the OAuth2 & OpenID Connect Integration details section. You may use this value to copy/paste a URL for testing a direct link to the registration page.
* Resolves [GitHub Issue #686](https://github.com/FusionAuth/fusionauth-issues/issues/686), thanks to [@ashokgelal](https://github.com/ashokgelal) for the suggestion!
* When viewing the About panel found in the administrative UI, the node IP address will be reported.
* Resolves [GitHub Issue #754](https://github.com/FusionAuth/fusionauth-issues/issues/754)
* The JSON Web Tokens issued by FusionAuth will now include the `jti` claim.
* Resolves [GitHub Issue #409](https://github.com/FusionAuth/fusionauth-issues/issues/409)
* All objects now have an `insertInstant` and a `lastUpdateInstant` property in the JSON API response.
* Resolves [GitHub Issue #755](https://github.com/FusionAuth/fusionauth-issues/issues/755)
* Public keys stored with a certificate will have the `x5t` property provided in the JSON Web Key Set response.
* Resolves [GitHub Issue #715](https://github.com/FusionAuth/fusionauth-issues/issues/715)
### Fixed
* The user registration event may be missing the `registration` property.
* Resolves [GitHub Issue #714](https://github.com/FusionAuth/fusionauth-issues/issues/714), thanks to [@joydeb28](https://github.com/joydeb28) for reporting the issue!
* A user with one or more consents granted fails to be deleted.
* Resolves [GitHub Issue #719](https://github.com/FusionAuth/fusionauth-issues/issues/719), thanks to one of our MVPs [@mgetka](https://github.com/mgetka) for reporting the issue!
* When using COPPA consent with Email+, the second email is not sent to the parent.
* Resolves [GitHub Issue #723](https://github.com/FusionAuth/fusionauth-issues/issues/724).
* The Refresh Token cookie is written without a `Max-Age` attribute on the JWT Refresh API response. This causes the cookie to be treated as a session cookie.
* Resolves [GitHub Issue #726](https://github.com/FusionAuth/fusionauth-issues/issues/726), thanks to [@satazor](https://github.com/satazor) for letting us know.
### Fixed
* API validation fails on the Audit Log API when a JSON body is omitted from the HTTP request.
* Resolves [GitHub Issue #605](https://github.com/FusionAuth/fusionauth-issues/issues/605)
* Fixing a bug that prevents the Kafka integration from working correctly.
* Resolves [GitHub Issue #649](https://github.com/FusionAuth/fusionauth-issues/issues/649), thanks to [@joydeb28](https://github.com/joydeb28) for reporting and for the persistence!
* When selecting an Application in the user search controls in the UI an invalid Elasticsearch query causes an error on Elasticsearch version 7.7.0. The query seems to be working on versions 6.3.1, 6.8.1, and 7.6.1, as far as we can tell it only fails on the most recent versions of Elasticsearch.
* Resolves [GitHub Issue #710](https://github.com/FusionAuth/fusionauth-issues/issues/710)
### Enhancement
* Add a return to login link to the default templates for Passwordless, Register, Forgot, and Password Sent.
* Resolves [GitHub Issue #666](https://github.com/FusionAuth/fusionauth-issues/issues/666), thanks to [@soullivaneuh](https://github.com/soullivaneuh) for the request!
### Fixed
* A JavaScript bug caused the device verification URL field to toggle to hidden when any grant was enabled or disabled in the UI. This is primarily a cosmetic issue, if you encounter it you may simply refresh the page.
* Resolves [GitHub Issue #692](https://github.com/FusionAuth/fusionauth-issues/issues/692)
* The Search API performs a validation step when using Elasticsearch, and if Elasticsearch returns `valid: false` we fail the request. We are now always including the explanation from the Elasticsearch response in our error message on the API to assist the developer to understand why the requested query is considered invalid.
* Resolves [GitHub Issue #697](https://github.com/FusionAuth/fusionauth-issues/issues/697)
* The Apple Service Id override that can be provided per application was not being used, instead the global value was utilized.
* Resolves [GitHub Issue #703](https://github.com/FusionAuth/fusionauth-issues/issues/703), thanks to [@ulybu](https://github.com/ulybu) for letting us know!
### Enhancement
* When configuring an OpenID Connect Identity Provider, the claim that contains the user's email address may now be modified. This allows the OpenID Connect Identity Provider to be more flexible when configured with non-standard OpenID Connect providers or other OAuth2 providers such as LinkedIn.
### Fixed
* When using `parent`, `child` and few other references in an email template, the validation step may fail unless you provide a null safe usage.
* Resolves [GitHub Issue #685](https://github.com/FusionAuth/fusionauth-issues/issues/685)
### Fixed
* In version 1.17.0 Key Master supports importing a standalone private key. If you attempt this request in the UI with an RSA private key an error will occur.
* Resolves [GitHub Issue #665](https://github.com/FusionAuth/fusionauth-issues/issues/665), thanks to [@mgetka](https://github.com/mgetka) who is quickly becoming one of our FusionAuth MVPs!
* When using an expired Forgot Password link if you have not added the `client_id` to the URL in the email template you will see an unexpected error when you attempt to begin the process again by entering your email address. You may also experience this error if you are sending users directly to `/oauth2/forgot` instead of the user clicking the link during an OAuth2 workflow.
* Resolves [GitHub Issue #671](https://github.com/FusionAuth/fusionauth-issues/issues/671), thanks to [@maurobennici](https://github.com/maurobennici) for reporting!
### Changed
* All Identity Provider configurations that did not have a lambda configured for User reconcile have been migrated to utilize a lambda to extract all optional user details from the IdP response. This allows you to have complete control over how these configurations work and what information is set or written to the user object during login. The business logic has not changed, but it has been moved from an internal FusionAuth service to a Lambda that can be modified. The following Identity Providers are affected:
* All Facebook, Google and Twitter Identity Provider configurations
* OpenID Connect and SAML v2 Identity Provider configurations without a configured lambda.
* OpenID Connect and SAML v2 Identity Providers that were already configured with a lambda may require some manual migration. The claims that were mapped into the User by FusionAuth prior to this version have been moved into a lambda so they may be modified. For each of your OpenID Connect or SAML v2 Identity Provider configurations that already had a Lambda configured for User reconcile, please review to ensure all of the claims you desire are handled by your lambda.
* For OpenID Connect Identity Provider configurations, review the new Lambda named `Default OpenID Connect Reconcile provided by FusionAuth`. Optionally copy any of the code you'd like to have executed into your configured Lambda and then test your integration. Specifically, the registered claims `given_name`, `middle_name`, `family_name`, `name`, `picture`, `phone_number`, `birthdate`, `locale` and `preferred_username` are now managed by the Lambda. If you would like these claims reconciled to the FusionAuth user, review the referenced Lambda function.
* For SAML v2 Identity Provider configurations, review the new Lambda named `Default SAML v2 Reconcile provided by FusionAuth`. Optionally copy any of the code you'd like to have executed into your configured Lambda and then test your integration. Specifically, the SAML claims for `dateofbirth`, `givenname`, `surname`, `name`, and `mobilephone` are now managed by the Lambda. If you would like these SAML claims reconciled to the FusionAuth user, review the referenced Lambda function.
### New
* Sign in with Apple. A new Identity Provider of type `Apple` is now available to enable Sign in with Apple support.
* Resolves [GitHub Issue #336](https://github.com/FusionAuth/fusionauth-issues/issues/336)
* See the [Apple Identity Provider](/docs/lifecycle/authenticate-users/identity-providers/social/apple) for additional details
* One time Use Refresh Tokens. A one time use refresh token means that each the time the refresh token is used to get a new access token (JWT) a new refresh token is returned. This feature must be enabled at the tenant level, and can optionally be overridden by the Application JWT configuration.
* Resolves [GitHub Issue #394](https://github.com/FusionAuth/fusionauth-issues/issues/394)
* Sliding Window Refresh Token Expiration. By default the expiration of a refresh token is calculated from the time it was originally issued. Beginning in this release you may optionally configure the refresh token expiration to be based upon a sliding window. A sliding window expiration means that the expiration is calculated from the last time the refresh token was used. This expiration policy means that if you are using refresh tokens to maintain a user session, the session can be maintained as long as the user remains active. This expiration policy must be enabled at the tenant level, and may optionally be overridden by the Application JWT configuration.
* Facebook, Google, HYPR and Twitter Identity Providers may be assigned a User Reconcile Lambda.
* Previously the user reconcile logic was built into FusionAuth. Now the User reconcile logic has been moved to a lambda to provide additional control over attributes are extracted from the Identity Provider response and set into the FusionAuth user.
### Enhancements
* Some development and possibly runtime errors that are used during external logins such as Facebook were not localized. These values may not be localized in your theme configuration.
* Resolves [GitHub Issue #535](https://github.com/FusionAuth/fusionauth-issues/issues/535), thanks to [@mgetka](https://github.com/mgetka) for raising the issue.
* Large cookies may cause the default maximum header size of 8k to be exceeded. When this occurs the request will fail and you may see an exception with a `400` status code indicating `java.lang.IllegalArgumentException: Request header is too large`.
* This value may now be modified via configuration. See the [Configuration](/docs/reference/configuration) reference or additional information.
* Resolves [GitHub Issue #608](https://github.com/FusionAuth/fusionauth-issues/issues/608), thanks to [@shortstack](https://github.com/shortstack) for letting us know, providing great debug and confirming the fix.
* When a user is registered, a refresh token will not be returned. This makes this API response consistent with the User Create API.
* Resolves [GitHub Issue #626](https://github.com/FusionAuth/fusionauth-issues/issues/626), thanks to [@LohithBlaze](https://github.com/LohithBlaze) for reporting and suggesting the change.
* When configuring a SAML v2 Identity Provider, a warning will be added to the Identity Provider index page if the CORS configuration is not adequate to allow the login request to complete. The configuration will generally require a `POST` request from a particular origin be allowed through the CORS filter.
* This should help reduce CORS configuration issues causing a `403` during integration testing.
* Resolves [GitHub Issue #641](https://github.com/FusionAuth/fusionauth-issues/issues/641)
### Fixed
* When importing a key using Key Master in the admin UI, when a key with an invalid length is imported the error was not being displayed.
* Resolves [GitHub Issue #587](https://github.com/FusionAuth/fusionauth-issues/issues/578)
* The hosted FusionAuth log page may fail to function properly after the user changes the locale using the locale selector on the themed page. Specifically, once you add more than one language to your theme, and the user continues past the first login panel to a subsequent themed page, if the user switches the locale the context will be lost and the user will see an OAuth error.
* Resolves [GitHub Issue #623](https://github.com/FusionAuth/fusionauth-issues/issues/623), thanks to [@flangfeldt](https://github.com/flangfeldt) and [@yrammos](https://github.com/yrammos) for reporting.
* A non POSIX compliant function definition in `setenv.sh` caused FusionAuth to fail to start on Ubuntu 18.04.4 and 20.04 (possibly others). This could be on any Linux distribution that sym-links `/bin/sh` to `dash` which is a POSIX compliant shell. This was introduced in version 1.16.0.
* Resolves [GitHub Issue #645](https://github.com/FusionAuth/fusionauth-issues/issues/645), thanks to [@s-vlade](https://github.com/s-vlade) and [@yrammos](https://github.com/yrammos) for letting us know.
* When using the Facebook IdP and specifying `picture` as one of the requested `fields` an error occurs during the User reconcile process which causes the login to fail. If you encounter this issue, the work around is to remove `picture` from the field configuration, even with this change you will still get the picture back from Facebook as FusionAuth makes a second call to the Me Picture API.
* Resolves [GitHub Issue #648](https://github.com/FusionAuth/fusionauth-issues/issues/648), thanks to [@thekoding](https://github.com/thekoding) for reporting and helping us track down the issue.
### Fixed
* When attempting to utilize a silent configuration to configure the database schema without using Elasticsearch, FusionAuth would enter maintenance mode.
* Resolves [GitHub Issue #618](https://github.com/FusionAuth/fusionauth-issues/issues/618), thanks to [@mgetka](https://github.com/mgetka) for reporting the issue!
### Security
* A vulnerability in an underlying SAML v2 library was resolved. If you are using SAML please upgrade FusionAuth to 1.16.0 or later as soon as possible.
* [CVE-2020-12676](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-12676)
* [CSNC-2020-002](https://compass-security.com/fileadmin/Research/Advisories/2020-06_CSNC-2020-002_FusionAuth_Signature_Exclusion_Attack.txt)
### Changed
* The favicon configuration in the default theme has been updated. If you have created your own theme and kept the default favicons using the FusionAuth logo you will want to either remove them or update them with the correct `href` paths. See the default theme for reference if you would like to use the FusionAuth favicons.
### New
* The Identity Provider Lookup API will return a list of `applicationIds` to represent the enabled FusionAuth applications for the identity provider.
* The Identity Provider Lookup API will return the SAML v2 `idpEndpoint` value configured in the SAML v2 IdP.
### Fixed
* Specifying an Elasticsearch URL containing basic auth credentials works properly. For example the URL `https://user:password@myelasticsearchservice.com` now functions as expected.
* Tested against https://bonsai.io and https://aiven.io.
* Resolves [GitHub Issue #531](https://github.com/FusionAuth/fusionauth-issues/issues/531), thanks to [@joshuaavalon](https://github.com/joshuaavalon) for reporting and [@nscarlson](https://github.com/nscarlson) for the additional details and assistance.
* Fixed a validation error when using the Import User API w/ an empty list of users. A `400` status code with a JSON response should have been returned.
* Resolves [GitHub Issue #520](https://github.com/FusionAuth/fusionauth-issues/issues/520), thanks to [@smcoll](https://github.com/smcoll) for reporting.
* Some JavaScript may fail on Internet Explorer version 11. Specifically the `Helper.js` which is used to handle the external login providers on the login page.
* Resolves [GitHub Issue #423](https://github.com/FusionAuth/fusionauth-issues/issues/423), thanks to [@downagain](https://github.com/downagain) for reporting this issue and for the excellent debug.
* A validation error in the OAuth2 Token endpoint returns a general error instead of the appropriate validation error.
* Resolves [GitHub Issue #546](https://github.com/FusionAuth/fusionauth-issues/issues/546), thanks to [@mgetka](https://github.com/mgetka) for reporting the issue.
* When using the Facebook login, it is possible that Facebook will send back an Image URL from the `/me/picture` API that will exceed `255` characters. If this occurs the login failed and an exception was logged.
* Resolves [GitHub Issue #583](https://github.com/FusionAuth/fusionauth-issues/issues/583), thanks to our friends at [famous.co](https://famous.co/) and [frontdoorhome.com](https://www.frontdoorhome.com/) for letting us know.
* Attempting to validate or save an Email template that contains a reference to a value stored in user data may cause an exception. For example `${user.data.company_name}` is a valid usage, but this would fail validation or cause an exception during validation.
* Resolves [GitHub Issue #598](https://github.com/FusionAuth/fusionauth-issues/issues/598)
* In some cases, when a webhook fails to respond and subsequently fails the request do to the configured transaction setting the Elasticsearch index will be out of sync.
* Resolves [GitHub Issue #600](https://github.com/FusionAuth/fusionauth-issues/issues/600), thanks to our Icelandic friend [@arni-inaba](https://github.com/arni-inaba) for letting us know and providing excellent recreate steps.
* An extra curly bracket caused the SQL migration to fail if you are running PostgreSQL and performed an upgrade without modifying the default tenant.
* Resolves [GitHub Issue #606](https://github.com/FusionAuth/fusionauth-issues/issues/606), thanks to [@nscarlson](https://github.com/nscarlson) for reporting the issue.
### Fixed from RC.1
The following issues were fixed that only affect those running version 1.16.0-RC.1.
* An unexpected request parameter may cause an exception due to the incorrect runtime mode.
* Resolves [GitHub Issue #595](https://github.com/FusionAuth/fusionauth-issues/issues/595), thanks to [@ceefour](https://github.com/ceefour)
### Changed
* Email Send API no longer requires a from email or a default from name, defaults may be taken from the tenant. See the [Emails API](/docs/apis/emails) documentation for reference.
* The OpenID Connect [JSON Web Key Set](/docs/lifecycle/authenticate-users/oauth/endpoints#json-web-key-set-jwks) API endpoint returns only public keys generated by FusionAuth. This endpoint previously also returned imported public keys, for which we do not hold the private key.
### Security
* Updated default CORS configuration for clean installs, see the [CORS Reference](/docs/operate/secure/cors#default-configuration) for details. It is highly recommended you modify your CORS configuration to match our new default values unless you have a technical requirement for your existing CORS configuration.
* Upgrade Handlebars to version `4.7.6` due to a known vulnerability. There is no known exploit of this vulnerability in FusionAuth, this is a pro-active upgrade. FusionAuth uses this JavaScript library in the administrative UI to build dynamic table roles.
* https://snyk.io/vuln/SNYK-JS-HANDLEBARS-534988
* Resolves [GitHub Issue #564](https://github.com/FusionAuth/fusionauth-issues/issues/564), thanks to [@michael-burt](https://github.com/michael-burt) for alerting us to this vulnerability.
### Enhancement
* The OpenID Connect and SAML v2 Reconcile Lambda may now modify the assigned user roles. Prior to this version any changes to the roles were intentionally not preserved. This restriction has been lifted.
* Resolves [GitHub Issue #536](https://github.com/FusionAuth/fusionauth-issues/issues/536), thanks to [@sedough](https://github.com/sedough) for opening the request.
* In some cases the `state` parameter returning from external SAML v2 & OpenID Connect identity providers is decoded incorrectly. We are now Base64 encoding this value to preserve it's integrity.
### New
* Support for Elasticsearch version 7
* FusionAuth maintains backward-compatibility with Elasticsearch 6.3.x clusters and indexes.
* `fusionauth-app.search-engine-type` configuration property and `FUSIONAUTH_SEARCH_ENGINE_TYPE` environment variable exposed for configuring the search engine, see the [Configuration](/docs/reference/configuration) documentation for reference.
* A reindex may be necessary depending on how you have upgraded your Elasticsearch cluster. You may issue a reindex in the FusionAuth admin UI under System -> Reindex.
* Resolves [GitHub Issue #199](https://github.com/FusionAuth/fusionauth-issues/issues/199)
* Support for using the database as the user search engine. This is now the default configuration. See the [Core Concepts - Users](/docs/get-started/core-concepts/users#user-search) documentation for details.
* Use of the database search engine provides limited search capabilities, and has limitations for the Users API, see the [Bulk Delete Users API](/docs/apis/users#bulk-delete-users) and [Search for Users API](/docs/apis/users#search-for-users) documentation for details.
* Resolves [GitHub Issue #427](https://github.com/FusionAuth/fusionauth-issues/issues/427)
* The Registration API returns an access token within the `token` field of responses to `POST` requests. See the [Registrations API](/docs/apis/registrations) documentation for reference.
* Application registration records a login and will be reflected in the Login, Daily Active User, and Monthly Active User reports within the FusionAuth admin UI.
* The `applicationId` is now optional for `PUT` requests (update login instants) to the Login API. See the [Login API](/docs/apis/login#update-login-instant) documentation for reference.
* `PUT` requests to the Login API records a login and will be reflected in the Login, Daily Active User, and Monthly Active User reports within the FusionAuth admin UI.
* The User API returns an access token within the `token` field of responses to `POST` requests creating a user. See the [User API](/docs/apis/users#create-a-user) documentation for reference.
* User creation records a login and will be reflected in the Login, Daily Active User, and Monthly Active User reports within the FusionAuth admin UI.
* System logs can be viewed from the Admin interface. Navigate to System -> Log to view and download the system logs.
* This feature is available in the UI and via a new API.
* Resolves [GitHub Issue #540](https://github.com/FusionAuth/fusionauth-issues/issues/540)
* System log export API has been added for retrieving a node's system logs as a compressed zip file. See the [System Logs API](/docs/apis/system) documentation for reference.
* There is a Test SMTP button that you can utilize during an Edit or Add Tenant operation to ensure the correct SMTP configuration.
* Resolves [GitHub Issue #539](https://github.com/FusionAuth/fusionauth-issues/issues/539)
* Production runtime mode disables maintenance mode, database migrations must be applied manually in this runtime mode. See the [FusionAuth App Installation Guide](/docs/get-started/download-and-install/fusionauth-app#runtime-modes) documentation for reference.
* Advanced configuration exposed for search engine type, runtime mode, and Same-Site cookie policy. See the [Configuration](/docs/reference/configuration) documentation for reference.
* JWT Refresh webhook event, issued when an access token is refreshed by refresh token, see the [Events](/docs/extend/events-and-webhooks/events/jwt-refresh) documentation for reference.
* Tenant email configuration provides a default from email and a default from name. See the [Tenants API](/docs/apis/tenants#create-a-tenant) documentation for reference.
* Resolves [GitHub Issue #262](https://github.com/FusionAuth/fusionauth-issues/issues/262), thanks to [@engineertdog](https://github.com/engineertdog) for the request!
### Docker
* Next time a release candidate is built, the `latest` tag will be preserved to always be the latest stable release. This way if you are always using the `latest` tag you will not automatically upgrade to a release candidate.
* Resolves [GitHub Issue #596](https://github.com/FusionAuth/fusionauth-issues/issues/596), thanks to [@ceefour](https://github.com/ceefour) for the request.
* The reference `docker-compose.yml` provided by the [fusionauth-containers](https://github.com/FusionAuth/fusionauth-containers) GitHub repo has been modified to install leveraging database as the User search engine. You will need to include the reference `docker-compose.override.yml` in order to install and configure Elasticsearch as the User search engine. See the [Docker installation guide](/docs/get-started/download-and-install/docker) for reference.
### Internal
* Java 14. Upgrade from Java 8. The FusionAuth Java runtime has been upgraded to version 14. All external Java packages such as the Java REST client and the Plugin interface are all still compiled against Java 8 so this upgrade should not impact any users.
* Resolves [GitHub Issue #481](https://github.com/FusionAuth/fusionauth-issues/issues/481)
* Upgrade Apache Tomcat to the latest patch version `8.5.53`.
* Much smaller Docker images based upon Alpine Linux! Compressed size changed from ~ 150 MB to 76 MB. More features, less size? Yeah, that's right.
* Check it out for yourself. See the [fusionauth/fusionauth-app](https://hub.docker.com/repository/docker/fusionauth/fusionauth-app/tags?page=1) repo.
### Fixed
* When more than one tenant is defined, the redirect to `/oauth2/callback` which is used for 3rd Party SAML v2 or OpenID Connect identity providers will fail unless the corresponding application is in the default tenant. This issue was introduced in `1.15.6` which means it only affects version `1.15.6`. If you encounter this issue you may be shown an error on the login page indicating `A validation error occurred during the login attempt. An event log was created for the administrator to review.`.
* Resolves [GitHub Issue #548](https://github.com/FusionAuth/fusionauth-issues/issues/548), thanks so much to [@lamuertepeluda](https://github.com/lamuertepeluda) for reporting and providing excellent technical details to assist in tracking down the bug.
* A callback from a Social IdP configuration may fail to complete the login workflow. This issue was introduced in `1.15.6` which means it only affects version `1.15.6` and `1.15.7`.
* Resolves [GitHub Issue #553](https://github.com/FusionAuth/fusionauth-issues/issues/553), thanks to [@ulybu](https://github.com/ulybu) for reporting the issue!
### Enhancements
* When a user attempts to utilize an expired Passwordless or Forgot Password link, FusionAuth will now still be able to allow the user to restart the login workflow.
* Resolves [GitHub Issue #468](https://github.com/FusionAuth/fusionauth-issues/issues/468), thanks to [@davidmw](https://github.com/davidmw) for suggesting this enhancement.
* In order to take advantage of this enhancement, you will need to upgrade your email template for one or both of these workflows. See the [Email Templates](/docs/customize/email-and-messages/email-templates) documentation for a reference usage.
### Fixed
* Due to a change in how FusionAuth encodes the `RelayState` value when redirecting to a 3rd party SAML v2 identity providers, the authentication request will fail with an OAuth2 error. This issue was introduced in `1.15.6` which means it only affects version `1.15.6`.
### Fixed
* Handle tabs and other control characters in an included text file when parsing the Kickstart configuration files.
* Resolves [GitHub Issue #524](https://github.com/FusionAuth/fusionauth-issues/issues/524), thanks to [@mgetka](https://github.com/mgetka) for reporting.
* When the FusionAuth Reactor is enabled, a breach detection is incorrectly requested during a user update when the password is not being modified. You may see errors in the Event Log indicating Reactor returned a status code of `400`, this error is just noise and it did not affect the requested action.
* Resolves [GitHub Issue #533](https://github.com/FusionAuth/fusionauth-issues/issues/533).
* When running FusionAuth on an un-secured connection during development, newer versions of the Chrome browser will reject the `Set-Cookie` request in the HTTP response because the `SameSite` attribute is not set.
* Resolves [GitHub Issue #537](https://github.com/FusionAuth/fusionauth-issues/issues/537).
### Enhancement
* When integrating with 3rd Party Identity Providers FusionAuth will build a `state` parameter in order to complete the FusionAuth OAuth2 or SAML v2 request on the callback from the 3rd Party IdP. There are times when a 3rd Party IdP may un-intentionally modify the `state` parameter by decoding the value. When the `state` parameter is not returned to FusionAuth the way it was sent the integration breaks. FusionAuth will now Bas64 encode the `state` value to better defend against 3rd Party IdP integrations.
* Resolves [GitHub Issue #538](https://github.com/FusionAuth/fusionauth-issues/issues/538).
### Fixed
* Adding a Consent to a User that does not have a First or Last Name. This was causing an error in the UI where the Add Consent dialog was not rendering and instead displaying a stack trace.
* Resolves [GitHub Issue #512](https://github.com/FusionAuth/fusionauth-issues/issues/512), thanks to [@mgetka](https://github.com/mgetka) for reporting.
* When Reactor is enabled and more than one user requires action due to a breached password the Reactor index page will fail to render.
* Resolves [GitHub Issue #514](https://github.com/FusionAuth/fusionauth-issues/issues/514), thanks to our friends at Frontdoor for reporting the issue.
* When adding a new Tenant in the UI you may encounter a `500` status code with a `FusionAuth encountered an unexpected error.` message. If you encounter this error, edit the default tenant, click save and then retry the add operation.
* Resolves [GitHub Issue #517](https://github.com/FusionAuth/fusionauth-issues/issues/517), thanks to [@vburghelea](https://github.com/vburghelea) for reporting.
* A JavaScript exception was causing the ExternalJWT identity mapping dialog to fail. A work around is to use the API to add these claim mappings. This bug was introduced in version 1.15.3.
* Resolves [GitHub Issue #518](https://github.com/FusionAuth/fusionauth-issues/issues/518), thanks to [@irzhywau](https://github.com/irzhywau) for reporting.
### Fixed
* When using PostgreSQL and using the Import User API with a large amount of roles assigned to user FusionAuth may exceed the maximum allowed parameterized values in a prepared statement causing a SQL exception. If you encounter this issue you may work around the issue by reducing the size of your import request to 200-500 users per request.
* Resolves [GitHub Issue #505](https://github.com/FusionAuth/fusionauth-issues/issues/505), thanks to [@leafknode](https://github.com/leafknode) for reporting and helping debug!
* When creating a user through Kickstart with `passwordChangeRequired` set to `true` and exception will occur during the next login request. This issue was introduced in version 1.15.0.
* Resolves [GitHub Issue #509](https://github.com/FusionAuth/fusionauth-issues/issues/509), thanks to [@mgetka](https://github.com/mgetka) for reporting!
* When a Kickstart file contains multi-byte characters the string value may not be encoded properly if the default file encoding is not UTF-8. This has now been resolved by explicitly requesting UTF-8 encoding during file I/O.
* Resolves [GitHub Issue #510](https://github.com/FusionAuth/fusionauth-issues/issues/510), thanks to [@mgetka](https://github.com/mgetka) for reporting!
* When using the SAML IdP configuration where FusionAuth is the SAML service provider if the base64 encoded SAML response from the IdP contains line returns FusionAuth will fail to parse the request and the login request will fail.
* Resolves [GitHub Issue #511](https://github.com/FusionAuth/fusionauth-issues/issues/511)
### Changed
* The External JWT Identity Provider now manages keys used for token verification in the Key Master. All keys have been migrated to Key Master, and going forward all keys can be managed through the Key Master.
* Prior to this version the OpenID Connect IdP would send the client secret using the `client_secret_basic` and the `client_secret_post` method. This was done for compatibility with providers that did not utilize the `client_secret_basic` method. Now this configuration is now provided and only the configured client authentication method will be used.
### Fixed
* Using the JWT Refresh API with a JWT issued from one tenant for a user in another tenant. This error was causing an exception instead of the proper validation error being returned to the caller. A `404` will now properly be returned when this scenario occurs.
* Resolves [GitHub Issue #399](https://github.com/FusionAuth/fusionauth-issues/issues/399), thanks to [@johnmaia](https://github.com/johnmaia) for helping us track it down.
* Missing API validation on the `/oauth2/passwordless` endpoint. A `500` was returned instead of the correct validation errors.
* Resolves [GitHub Issue #450](https://github.com/FusionAuth/fusionauth-issues/issues/450), thanks to [@GraafG](https://github.com/GraafG) for reporting.
* On systems running MySQL, the SQL migration for `1.15.0` on the `DELIMITER` command and causes the instance table to have a null `license_id`. If you have previously connected your support contract Id with your instance and upgraded to a previous `1.15.x` version, you will need to reconnect your license Id in the Reactor tab. This issue was introduced in version 1.15.0.
* Resolves [GitHub Issue #482](https://github.com/FusionAuth/fusionauth-issues/issues/482), thanks to [@nulian](https://github.com/nulian) for reporting!
* The `CancelAction` method in the .NET Core client returning field error due to incorrect method definition.
* Resolves [GitHub Issue #11](https://github.com/FusionAuth/fusionauth-netcore-client/issues/11), thanks to [@minjup](https://github.com/minjup) for reporting.
* The OpenID Connect IdP client authentication method is now configurable as `client_secret_basic`, `client_secret_post`, or `none` and will authenticate solely with the configured method. See the [OIDC spec concerning Client Authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication) for more information.
* The `1.15.3` database migration configures the client authentication method to `client_secret_basic` for identity provider configurations with a client secret defined, and `none` for those without a client secret defined. If your OpenID Connect provider requires `client_secret_post` you will need to update your configuration to ensure the integration continues to function properly. Discord is one of the known IdPs that requires the `client_secret_post` client authentication method.
* See the [OpenID Connect Identity Providers](/docs/apis/identity-providers/openid-connect) APIs, the [OpenID Connect Identity Provider Overview](/docs/lifecycle/authenticate-users/identity-providers/) and the [Discord OIDC integration tutorial](/docs/lifecycle/authenticate-users/identity-providers/gaming/discord) for more detail.
* Resolves [GitHub Issue #445](https://github.com/FusionAuth/fusionauth-issues/issues/445), thanks to [@ovrdoz](https://github.com/ovrdoz) for reporting.
* When you have enabled Self Service Registration and Registration Verification FusionAuth will fail to send the email to the end user during this workflow.
* Resolves [GitHub Issue #496](https://github.com/FusionAuth/fusionauth-issues/issues/496), thanks to our great Slack community for letting us know and assisting with debug.
* If a Two Factor Trust has been established with a particular browser through the user of a cookie, it was not being honored during the Passwordless Email workflow and the user would be prompted for the Two Factor challenge during each login attempt.
* Resolves [GitHub Issue #495](https://github.com/FusionAuth/fusionauth-issues/issues/495), thanks to our great Slack community for reporting!
* When using managed domains with the OpenID Connect or SAML v2 Identity Provider configurations the callback to FusionAuth may fail with an error.
* Resolves [GitHub Issue #488](https://github.com/FusionAuth/fusionauth-issues/issues/488), thanks to [@sedough](https://github.com/sedough) for reporting.
* When a stylesheet in your theme contains `>` the new HTML escaping strategy introduced in version X causes this value in the CSS to be incorrectly escaped. If you encounter this problem in your current them, update the usage of the stylesheet to `${theme.stylesheet()?no_esc}` instead of the previous usage of `${theme.stylesheet()}`.
* Resolves [GitHub Issue #489](https://github.com/FusionAuth/fusionauth-issues/issues/489), thanks to [@snmed](https://github.com/snmed) for reporting.
* Fix a Kickstart bug, when a variable is used in the very first API key the replacement was not honored.
* Resolves [GitHub Issue #493](https://github.com/FusionAuth/fusionauth-issues/issues/493), thanks to [@tst-dhudlow](https://github.com/tst-dhudlow) for reporting!
### Enhancements
* When the External JWT Identity Provider does not have any managed domains defined, allow a JWT from any domain to be reconciled. This change makes this IdP configuration more consistent with our IdP configurations that allow for managed domains.
* Resolves [GitHub Issue #491](https://github.com/FusionAuth/fusionauth-issues/issues/491)
### Known Issues
* Fixed in 1.15.3, on systems running MySQL, the `1.15.0` migration fails on a `DELIMITER` command and causes the instance table to have a null `license_id`. If you upgraded to `1.15.2`, have connected our instance to a support contract, and ran the `1.15.0` migration using maintenance mode, you will need to reconnect your license Id in the Reactor tab.
* A workaround for this issue is to download the `fusionauth-database-schema-1.15.0.zip` from [our direct download page](/direct-download), unzip and manually apply the `migrations/mysql/1.15.0.sql` migration. You may also wait to upgrade until `1.15.3` is available and allow maintenance mode to run the fixed migration.
### Fixed
* Password breached fixes. On some systems running PostgreSQL a portion of the breach detections features may not function properly. If you are running MySQL this will not affect you, and only certain PostgreSQL versions are affected. If you are not using FusionAuth Reactor this issue will not affect you.
### Known Issues
* Fixed in 1.15.3, on systems running MySQL, the `1.15.0` migration fails on a `DELIMITER` command and causes the instance table to have a null `license_id`. If you upgraded to `1.15.1`, have connected our instance to a support contract, and ran the `1.15.0` migration using maintenance mode, you will need to reconnect your license Id in the Reactor tab.
* A workaround for this issue is to download the `fusionauth-database-schema-1.15.0.zip` from [our direct download page](/direct-download), unzip and manually apply the `migrations/mysql/1.15.0.sql` migration. You may also wait to upgrade until `1.15.3` is available and allow maintenance mode to run the fixed migration.
### Fixed
* A SQL statement in PostgreSQL may cause some 9.x versions to fail to store breach metrics once FusionAuth Reactor has been enabled. If you are running MySQL this will not affect you, and only certain PostgreSQL versions are affected. If you are not using FusionAuth Reactor this issue will not affect you.
### Known Issues
* Fixed in 1.15.1, some versions of PostgreSQL may cause an exception when storing breach metrics after enabling FusionAuth Reactor. If you are not using FusionAuth Reactor or you are using MySQL instead of PostgreSQL this issue will not affect you.
* Fixed in 1.15.3, on systems running MySQL, the `1.15.0` migration fails on a `DELIMITER` command and causes the instance table to have a null `license_id`. If you upgraded to `1.15.0`, have connected our instance to a support contract, and ran the `1.15.0` migration using maintenance mode, you will need to reconnect your license Id in the Reactor tab.
* A workaround for this issue is to download the `fusionauth-database-schema-1.15.0.zip` from [our direct download page](/direct-download), unzip and manually apply the `migrations/mysql/1.15.0.sql` migration. You may also wait to upgrade until `1.15.3` is available and allow maintenance mode to run the fixed migration.
### Changed
* In the FusionAuth admin UI you will notice that User, Groups, Applications and Tenants are all now at the top level of the left navigation sidebar. This change has been done to provide quicker access to these frequently accessed menus.
### New
* FusionAuth Reactor ™. FusionAuth Reactor is available with all paid plans of FusionAuth. The first feature in the Reactor suite will be breached password detection. All passwords will be checked against a breached list during all password change events, and optionally during login based upon your configuration.
* New webhook event for use with FusionAuth Reactor breached password detection. This event when enabled will be fired during login if the user is using a vulnerable password.
* User Password Breach (`user.password.breach`), see [Webhook Events](/docs/extend/events-and-webhooks/events/) for additional information.
* New Tenant configuration in support of FusionAuth Reactor and additional password validation rules. This configuration can be found in the Password tab of the Tenant configuration on the [Tenant](/docs/apis/tenants) API.
* `tenant.passwordValidationRules.validateOnLogin` - When enabled the user's password will be validated during login. If the password does not meet the currently configured validation rules the user will be required to change their password. Prior to this release password validation was only ever performed during a change event, you may now optionally enforce your password policy during login.
* `tenant.passwordValidationRules.breachDetection` - A new object to provide configuration per tenant for password breach detection.
* During login, if the user is required to change their password, the Login API, Authorization Code Grant, Implicit Grant and Password Grant will now also return a change reason. This additional value in the response will indicate why the user is being required to change their password.
* See the [Login](/docs/apis/login) API, and corresponding [OAuth endpoints](/docs/lifecycle/authenticate-users/oauth/endpoints) for more detail.
### Security
* A small window exists after a Refresh Token has expired when this token can still be used under specific circumstances. This symptom only occurs when using the `/api/jwt/refresh` API, and not when using the Refresh Grant using the `/oauth/token` endpoint. In a worst case scenario the Refresh Token may be honored up to 5 hours after the expiration date, in most circumstances it will be much less. This only applies to expired Refresh Tokens, revoking a Refresh Token is not affected.
* Resolves [GitHub Issue #454](https://github.com/FusionAuth/fusionauth-issues/issues/454), thanks to [@johnmaia](https://github.com/johnmaia) one of our FusionAuth MVPs!
### Fixed
* Editing a Group in a Tenant that does not yet have any Applications created causes and exception when you attempt to save the edit form in the FusionAuth admin UI.
* Resolves [GitHub Issue #471](https://github.com/FusionAuth/fusionauth-issues/issues/471), thanks to [@dhait](https://github.com/dhait) for letting us know, we appreciate you!
* When Self Service Registration, if Registration Verification is enabled and Email Verification is disabled the user will not receive a Registration Verification email.
* Resolves [GitHub Issue #472](https://github.com/FusionAuth/fusionauth-issues/issues/472)
* An exception may occur when using the Import User API if you are missing the `applicationId` property in a User Registration. This error should have been found as a validation error and instead an exception occurred.
* Resolves [GitHub Issue #479](https://github.com/FusionAuth/fusionauth-issues/issues/479), thanks to our friends at Integra Financial Services for reporting the error.
### Enhancements
* Allow Kickstart to better handle varying startup times and delays. A few users reported scenarios where Kickstart would begin before FusionAuth was ready causing Kickstart to fail.
* Resolves [GitHub Issue #477](https://github.com/FusionAuth/fusionauth-issues/issues/477)
This change may affect you if you are performing advanced HTML escaping in your themed templates. During upgrade, any usage of `?html` in a themed template will removed because it is now handled automatically and it is no longer valid to use the FreeMarker built-in `?html`. \
If any of your translated messages include an HTML entity such as `\…` and you are including this message using the theme message helper `theme.message` you may need to make a small adjustment in order for the entity to render properly. For example, on the Logout template the default text is `Logging out…` but if you see it rendered as `Logging out\…` you will need to add an the FreeMarker suffix `?no_esc` so that the usage looks like this `theme.message('logging-out')?no_esc`. \
It is recommended that you audit your theme for any usage of `?html` and ensure you test your theme after migration. In the FusionAuth UI if you navigate to Settings -> Themes you can use the View action to render each template and ensure they render properly.]
### Changed
* A JWT Populate Lambda now has fewer reserved claims. All claims can now be removed or modified except for `exp`, `iat` and the `sub` claims by the JWT Populate Lambda. You remove or modify claims added by FusionAuth at your own peril.
* See [JWT Populate](/docs/extend/code/lambdas/jwt-populate) for additional details.
* Resolves [GitHub Issue #387](https://github.com/FusionAuth/fusionauth-issues/issues/387)
* Add additional fields that can be merged by the `PATCH` HTTP method. The following fields were not being merge, but replaced. The limitation of this change is that it is difficult to remove fields from values from arrays. A future enhancement may be to support the [JSON Patch](https://github.com/FusionAuth/fusionauth-issues/issues/441) specification which provides semantics for add, replace and remove.
* `User.preferredLanguages`
* `User.memberships`
* `User.registrations`
* `User.data`
* `UserRegistration.data`
* `UserRegistration.preferredLanguages`
* `UserRegistration.roles`
* `Application.data`
* Resolves [GitHub Issue #424](https://github.com/FusionAuth/fusionauth-issues/issues/424)
### New
* [Kickstart](/docs/get-started/download-and-install/development/kickstart)™ allows you bypass the Setup Wizard in order to FusionAuth up and running quickly. Deploy development or production instances of FusionAuth using a pre-defined configuration of Users, Groups, Applications, Tenants, Templates, API keys, etc.
* Resolves [GitHub Issue #170](https://github.com/FusionAuth/fusionauth-issues/issues/170) 🤘
* This feature is in *Tech Preview * which means if we find shortcomings with the design as we gather feedback from end users it is possible we will make breaking changes to the feature to correct or enhance the functionality. Any such changes will be documented in future release notes as appropriate.
* The Tenant API can optionally take a new `sourceTenantId` parameter to allow you to create a new Tenant using the values from an existing Tenant. Using the `sourceTenantId` limits the required parameters to the Tenant name.
* Resolves [GitHub Issue #311](https://github.com/FusionAuth/fusionauth-issues/issues/311)
* Add a View action to a Group Membership in the Membership tab of the Manage User panel in the UI.
* Resolves [GitHub Issue #413](https://github.com/FusionAuth/fusionauth-issues/issues/413)
### Fixed
* A memory leak in the Nashorn JavaScript engine used to execute FusionAuth Lambdas has been resolved.
* The OAuth2 Authorization Code grant was required to complete a SAMLv2 login, this grant is no longer required to be enabled.
* Resolves [GitHub Issue #432](https://github.com/FusionAuth/fusionauth-issues/issues/432)
* Added missing `theme_manager` role to the FusionAuth application
### Fixed
* During a reindex operation the status will properly be displayed on every node when viewing the User Search or the Reindex pages in the UI.
* Improve Kafka configuration validation when using the Test button in the UI.
* Resolves [GitHub Issue #318](https://github.com/FusionAuth/fusionauth-issues/issues/318), thanks to [@nikos](https://github.com/nikos) for reporting the issue!
* An exception may occur when using ReactNative with FusionAuth when an HTTP Origin header is sent to FusionAuth with a value of `file://`. The exception is caused because `file://` without a value after the double slash is not a valid URI and cannot be parsed by `java.net.URI`. However the HTTP specification indicates that an origin header with a scheme of `file://` is allowed and when used anything following the prefix is allowed. This fix follows a similar decision made by Apache Tomcat in their CORS filter, see [Bugzilla #60008](https://bz.apache.org/bugzilla/show_bug.cgi?id=60008).
* Resolves [GitHub Issue #414](https://github.com/FusionAuth/fusionauth-issues/issues/414), thanks to [@karice](https://github.com/karice) for reporting the issue and helping us debug!
* When an invalid code or expired code is used on a Passwordless login request an exception may occur.
* Resolves [GitHub Issue #416](https://github.com/FusionAuth/fusionauth-issues/issues/416), thanks to [@downagain](https://github.com/downagain) for reporting the issue!
* When a user email is verified implicitly due to a change password action that originated via an email request the `user.verified` event is now sent.
* Resolves [GitHub Issue #418](https://github.com/FusionAuth/fusionauth-issues/issues/418), thanks to [@JonasDoe](https://github.com/JonasDoe) for asking via [StackOverflow](https://stackoverflow.com/questions/59502335/fusionauth-webhook-user-email-verified-not-triggered-when-confirmation-happend) and then opening an issue to help us resolve the issue.
### Fixed
* The Elasticsearch migration required to complete the upgrade to 1.13.0 may not always run as intended. Upgrading to this release will kick off an Elasticsearch reindex operation to correct the search index state.
### Known Issues
* A search index rebuild is required to complete this upgrade, this operation may not automatically be started during upgrade. If you have already upgraded to this release you can either upgrade to the 1.13.1, or manually initiate a reindex request by navigating in the UI to System -> Reindex.
### New
* Delete users who have not verified their email address after a specified duration
* See [Tenant](/docs/get-started/core-concepts/tenants) configuration or the [Tenant](/docs/apis/tenants) API for additional information.
* Resolves [GitHub Issue #360](https://github.com/FusionAuth/fusionauth-issues/issues/360)
* Delete application registrations of users who have not verified their registration after a specified duration
* See [Application](/docs/get-started/core-concepts/applications) configuration or the [Application](/docs/apis/applications) API for additional information.
* Resolves [GitHub Issue #360](https://github.com/FusionAuth/fusionauth-issues/issues/360)
* Delete Users by Search Query
* Resolves [GitHub Issue #361](https://github.com/FusionAuth/fusionauth-issues/issues/361)
* See [Bulk Delete Users](/docs/apis/users#bulk-delete-users) API.
### Fixed
* The newly supported `PATCH` HTTP method cannot be selected from the API key endpoint security settings. This means that you need to allow all methods in order to utilize the `PATCH` method. This has been resolved.
* Resolves [GitHub Issue #402](https://github.com/FusionAuth/fusionauth-issues/issues/402), thanks to [@radicaljohan](https://github.com/radicaljohan) for reporting!
* The newly supported `PATCH` HTTP method is not configurable in the CORS filter.
* An empty salt value is recommended in an error message but this was failing validation during Import using the User Import API.
* Resolves [GitHub Issue #410](https://github.com/FusionAuth/fusionauth-issues/issues/410), thanks to [@TanguyGiton](https://github.com/TanguyGiton) for reporting!
* An exception may occur when using the PATCH method on the User API when more than one tenant exists.
* Resolves [GitHub Issue #400](https://github.com/FusionAuth/fusionauth-issues/issues/400), thanks to [@JesperWe](https://github.com/JesperWe) for reporting!
### Enhancement
* `DELETE /api/user/bulk` takes `queryString` and `query` parameters to search for users to delete by Elasticsearch query string and raw JSON query, and a `dryRun` parameter to preview the affected users. See the [User Bulk Delete API documentation](/docs/apis/users#bulk-delete-users).
* Addresses [GitHub Issue #361](https://github.com/FusionAuth/fusionauth-issues/issues/361)
* `POST /api/user/search` and `GET /api/user/search` take a `query` parameter to search for users by an Elasticsearch raw JSON query. See the [User Search API documentation](/docs/apis/users#search-for-users).
* Addresses [GitHub Issue #361](https://github.com/FusionAuth/fusionauth-issues/issues/361)
* `/api/user/search` takes new `sortFields` for sorting search results. See the [User Search API documentation](/docs/apis/users#search-for-users).
* The Webhook URL is no longer constrained to 191 characters. Prior to this version, this URL was considered unique and the length was constrained due to indexing limitations. The URL is no longer required to be unique and it is up to the user to limit duplicate webhooks.
* Resolves [GitHub Issue #386](https://github.com/FusionAuth/fusionauth-issues/issues/386), and thanks to [@davidmw](https://github.com/davidmw) for bringing this issue to our attention. Long URLs for everyone!
### Changed
* In support of the OAuth Device Grant feature released in 1.11.0, a second template was added to separate the completion state.
* New themed template `OAuth device complete`. Starting with version 1.12.0, templates will no longer be automatically migrated into an existing theme. We believe this is a safer choice overall. Instead your theme will be marked as requiring upgrade when viewed in the UI. You will be prompted to complete the missing templates when you edit and you will be provided with the option to copy in the default template as a starting point.
* If FusionAuth attempts to render the missing template you will be prompted with a message indicating your theme needs to be upgraded. In generally this should happen when you are using a new feature and thus should occur at development time. Whenever a new template is added, it is recommended to edit and verify your theme right away after upgrade to ensure a smooth migration.
* In support of the HYPR integration, a new template was added that will be used when waiting for the external HYPR authentication to complete.
* New themed template `OAuth2 wait`. Starting with version 1.12.0, templates will no longer be automatically migrated into an existing theme. We believe this is a safer choice overall. Instead your theme will be marked as requiring upgrade when viewed in the UI. You will be prompted to complete the missing templates when you edit and you will be provided with the option to copy in the default template as a starting point.
* The following theme messages were added. Until these values have been translated they will be rendered in English. At your earliest convenience you will want to add these new keys to your existing themes. You may wish to review the community provided translations which may already contain these new messages. https://github.com/FusionAuth/fusionauth-localization
```
wait-title=Complete login on your external device
waiting=Waiting
[ExternalAuthenticationExpired]=Your external authentication request has expired, please re-attempt authentication.
```
* A change has been made to how an event is sent to Webhooks when the Transaction configuration does not require any webhooks to succeed. Prior to this version each webhook would be called in order and once the status was collected from each webhook a decision was made to return to the caller or fail the request. In order to increase the performance of webhooks, when the Transaction configuration does not require any webhooks to succeed each webhook will be called in a separate thread (asynchronously) and the request will return immediately. In this scenario any failed requests will not be retried. See Webhooks for more information.
### New
* Support HYPR IdP native integration. HYPR brings passwordless and biometric options to FusionAuth.
* See the [HYPR Identity Provider](/docs/lifecycle/authenticate-users/identity-providers/enterprise/hypr) for additional details
* Administrative actions added to Users -> Manage panel.
* Send password reset
* always available from the drop down menu.
* Resolves [GitHub Issue #351](https://github.com/FusionAuth/fusionauth-issues/issues/351), thanks to [@nicholasbutlin](https://github.com/nicholasbutlin) for the suggestion!
* Resend email verification
* available when the user's email is not yet verified from the drop down menu.
* Resend verification
* available as a new row button in the *Registrations* tab when a registration is not verified.
### Fixed
* Modifying user actions with multi tenants returns a missing tenant error.
* Resolves [GitHub Issue #328](https://github.com/FusionAuth/fusionauth-issues/issues/328), thanks to [@AlvMF1](https://github.com/AlvMF1) for reporting the issue!
* The [JWT Validate](/docs/apis/jwt#validate-a-jwt) endpoint returns the wrong precision for `iat` and `exp` claims.
* Resolves [GitHub Issue #347](https://github.com/FusionAuth/fusionauth-issues/issues/347), thanks to [@uncledent](https://github.com/uncledent) for reporting and providing detailed information.
* When using the one time password returned from the Change Password API when a Refresh Token was provided during the change request a Refresh Token is not returned from the Login API.
* Resolves [GitHub Issue #382](https://github.com/FusionAuth/fusionauth-issues/issues/382), thanks to [@colingm](https://github.com/colingm) for reporting the issue.
* A "null" Origin header is allowed in the w3 spec, and when this occurs it may cause an exception when validating authorized origins.
* Resolves [GitHub Issue #379](https://github.com/FusionAuth/fusionauth-issues/issues/379), thanks to [@karice](https://github.com/karice) for reporting and excellent assist!
* Better handling on the Start Passwordless API when a user does not exist
* Resolves [GitHub Issue #377](https://github.com/FusionAuth/fusionauth-issues/issues/377), thanks to [@smoorsausje](https://github.com/smoorsausje) for reporting!
### Enhancement
* The User Delete API will no longer delete User Actions taken by the user. Instead the API will now disassociate any UserActions created by the deleted user by removing them from the Actioning User. In this scenario, a user will remain in an Action taken by a user that has now been deleted.
* A User Action may be applied to a user in a different tenant than the User taking the action. Prior to this release, using the admin UI to take an action on a user in a different tenant may fail.
* The following APIs now support the `PATCH` HTTP method. This enhancement completes [GitHub Issue #121](https://github.com/FusionAuth/fusionauth-issues/issues/121).
* `/api/application`
* `/api/application/role`
* `/api/consents`
* `/api/email/template`
* `/api/group`
* `/api/identity-provider`
* `/api/integration`
* `/api/lambda`
* `/api/system-configuration`
* `/api/tenant`
* `/api/theme`
* `/api/user`
* `/api/user-action`
* `/api/user-action-reason`
* `/api/user/consent`
* `/api/user/registration`
* `/api/webhook`
* The FusionAuth client libraries now also support the PATCH method.
* When an encoded JWT is accepted in the Authorization header, FusionAuth will now accept the token in the `Bearer` or the `JWT` schema.
* When you begin an external login such as Facebook, Google or Twitter an in progress indicator will be added to the login panel to indicate to the user that a request is in progress.
* Resolves [GitHub Issue #331](https://github.com/FusionAuth/fusionauth-issues/issues/331), thanks to [@davidmw](https://github.com/davidmw) for the suggestion!
* If you are using a theme and want to take advantage of this indicator, you can compare the stock OAuth2 Authorize template, look for the note in the top JavaScript section.
### Security
* A change was made to the FreeMarker template engine to remove the possibility of malicious code execution through a FreeMarker template. To exploit this vulnerability, one of two scenarios must occur. The first scenario is a user with an API key capable of adding or editing Email or Theme templates, the second scenario is a user with access to the FusionAuth admin UI that has the necessary authority to add or edit Email or Theme templates. In these two scenarios the user would need to add code to the template with the intention of executing a malicious system command. There is a low probably of this exploitation to occur if you have trusted applications and administrative users.
* [CVE-2020-7799](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7799)
### Changed
* Remove the `sid` and the `iss` request parameters on the URL provided by `post_logout_redirect_uri`. This feature was added in version `1.10.0` and because the redirect URL may be a previously configured Logout URL or a URL provided by the `post_logout_redirect_uri` we were always adding these additional request parameters to the URL. This change will remove them from the redirect URL and they will only be added to the URLs used to build the iframes in the logout template.
* Resolves [GitHub Issue #332](https://github.com/FusionAuth/fusionauth-issues/issues/332), thanks to [@davidmw](https://github.com/davidmw) for the feedback!
* In support of the OAuth Device Grant feature, the following theme changes have been made.
* New themed template `OAuth device`. This template has been added to each of your existing themes. As part of your migration please review this template to ensure it matches your intended style.
* The following theme messages were added. Until these values have been translated they will be rendered in English. At your earliest convenience you will want to add these new keys to your existing themes. You may wish to review the community provided translations which may already contain these new messages. https://github.com/FusionAuth/fusionauth-localization
```
device-form-title=Device login
device-login-complete=Successfully connected device
device-title=Connect Your Device
userCode=Enter your user code
[blank]user_code=Required
[invalid]user_code=Invalid user code
```
* The following hidden fields were added and you will need to update your `[#macro oauthHiddenFields]` in the theme "Helpers" of existing Themes if you intend to utilize the Device Grant or `response_mode` in the Authorization grant:
```
[@hidden name="response_mode"/]
[@hidden name="user_code"/]
```
* An update has been made to the `[@link]` macro in the Helpers template. If you intend to utilize the Device Grant you will need to add the missing parameters to your macro or copy the updated macro and usage from the default FusionAuth theme. The `user_code` request parameter has been added to this macro.
### New
* [Device Authorization Grant](/docs/lifecycle/authenticate-users/oauth/endpoints#device)
* This satisfies [GitHub Issue #320](https://github.com/FusionAuth/fusionauth-issues/issues/320) - OAuth2 Device Authorization Grant
* This grant type is commonly used to connect a set top box application to a user account. For example when you connect your HBO NOW Roku application to your account you are prompted with a 6 digit code on the TV screen and instructed to open a web browser to [hbonow.com/tvcode](https://hbonow.com/tvcode) to complete the sign-in process. This process is using the OAuth Device Grant or a variation of this workflow.
* Support for the `response_mode` request parameter during the Authorization Code grant and the Implicit grant workflows.
* This will provide support for `response_mode=form_post`
* Resolves [GitHub Issue #159](https://github.com/FusionAuth/fusionauth-issues/issues/159), thanks to [@bertiehub](https://github.com/bertiehub) for requesting.
* An additional API is available in support of Passwordless Login to allow additional flexibility with third party integrations.
* See [GitHub Issue #175](https://github.com/FusionAuth/fusionauth-issues/issues/175)
* This feature will be available in 3 steps, Start, Send and Complete. Currently the Send API generates a code and sends it to the user, and then a Login API completes the request. The change is backwards compatible, but a Start action will be provided so you may skip the Send and collect the code and send it to the user using a third party system.
* See the [Passwordless API documentation](/docs/apis/passwordless) for additional information.
### Preview
* The `PATCH` HTTP method is available on some APIs in a developer preview. This is not yet documented and should only be used in development. The following APIs support the `PATCH` method, more to come.
* `/api/application`
* `/api/user`
* `/api/user/registration`
* This is in support of [GitHub Issue #121 - Support HTTP method PATCH](https://github.com/FusionAuth/fusionauth-issues/issues/121).
### Fixed
* Return a `400` status code with a JSON response body on the Import API when a foreign key constraint causes the import to fail
* Resolves [GitHub Issue #317](https://github.com/FusionAuth/fusionauth-issues/issues/317), thanks to [@AlvMF1](https://github.com/AlvMF1) for reporting the issue!
* Return a `401` status code on the `Userinfo` endpoint for invalid tokens
* Resolves [GitHub Issue #321](https://github.com/FusionAuth/fusionauth-issues/issues/321)
* The Passwordless login external identifier complexity settings are not working
* Resolves [GitHub Issue #322](https://github.com/FusionAuth/fusionauth-issues/issues/322), thanks to [@pawpro](https://github.com/pawpro) for letting us know!
* An error is incorrectly displayed on the Forgot Password form even when the code is valid
* Resolves [GitHub Issue #330](https://github.com/FusionAuth/fusionauth-issues/issues/330), thanks to [@JesperWe](https://github.com/JesperWe) for reporting the issue!
* When a large number of tenants exist such as 3-5k, an exception may be thrown during a key cache reload request
* Resolves [GitHub Issue #326](https://github.com/FusionAuth/fusionauth-issues/issues/326), thanks to [@johnmaia](https://github.com/johnmaia) for reporting!
* When using the `id_token_hint` on the Logout endpoint, if the token was issued to a user that is not registered for the application it will not contain the `applicationId` claim. This claim was being used to resolve the `client_id` required to complete logout. An alternative strategy is now used so that an `id_token` issued to a user that is registered, or not registered will work as expected when provided on the Logout endpoint.
* Resolves [GitHub Issue #350](https://github.com/FusionAuth/fusionauth-issues/issues/350), thanks to [@paulspencerwilliams](https://github.com/paulspencerwilliams) for taking the time to let us know!
* Support a SAML SP that does not send the `` constraint in the AuthN request, in this case we will default to `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`.
### Enhancement
* Front-channel logout was made more flexible
* Resolves [GitHub Issue #324](https://github.com/FusionAuth/fusionauth-issues/issues/324)
* A new attribute `Logout behavior` was added to the Application -> OAuth configuration
* `Redirect only` - legacy behavior of only logging out of SSO and redirecting to either the registered logout URL in the application or the `post_logout_redirect_uri`.
* `All applications` - performs a front channel logout of all registered applications in the tenant. Optionally, the themeable `Oauth logout` page can be modified to only logout of those applications the user is registered for.
* In some cases the Facebook IdP configuration requires a permission of `email` to be configured in order for the `email` claim to be returned from the Facebook Me API even when `email` is also specified in the `field` parameter. FusionAuth will default both the `fields` and the `permissions` parameters to `email` on create if not provided to make the Facebook IdP work out of the box for more users. Defaults will not be applied if these fields are left blank or omitted on an update.
* The [Passwordless Send API](/docs/apis/passwordless#send-passwordless-login) now takes an optional `code` parameter which will be used as the Passwordless code sent in the email. This `code` can be generated by the new Passwordless Start API.
### Fixed
* When logging into Google or other external Identity Provider for an Application outside of the default tenant the login may not complete successfully. This issue was introduced in version 1.9.0. A work around is to use an application in the default tenant.
* A status code of `500` may occur during the processing of the SAML v2 response from an SAML v2 IdP.
* Resolves [GitHub Issue #314](https://github.com/FusionAuth/fusionauth-issues/issues/314), thanks to [@Raghavsalotra](https://github.com/Raghavsalotra) for all his help verifying a fix for this issue.
### Changed
* In support of the OpenID Connect Front Channel logout feature, the following theme changes have been made.
* New themed template `OAuth logout`. This template has been added to each of your existing themes. As part of your migration please review this template to ensure it matches your intended style.
* The following theme messages were added. Until these values have been translated they will be rendered in English. At your earliest convenience you will want to add these new keys to your existing themes. You may wish to review the community provided translations which may already contain these new messages. https://github.com/FusionAuth/fusionauth-localization
```
logging-out=Logging out&hellip;
logout-title=Logging out
or=Or
[ExternalAuthenticationException]=%1$s The login request failed.
```
### New
* Support for the OpenID Connect Front Channel logout
* This updates the existing OAuth2 Logout endpoint to be compliant with the [OpenID Connect Front-Channel Logout 1.0 - draft 02](https://openid.net/specs/openid-connect-frontchannel-1_0.html) specification
* TL;DR The `/oauth2/logout` endpoint will call logout URLs of all tenant applications. A redirect URL can be requested on the URL via `post_logout_redirect_uri`.
* Resolves [GitHub Issue #256](https://github.com/FusionAuth/fusionauth-issues/issues/256), thanks to all who up voted and provided valuable feedback.
* The [OpenID Connect discovery endpoint](/docs/lifecycle/authenticate-users/oauth/endpoints#openid-configuration) now returns the following attributes:
* `end_session_endpoint`
* `frontchannel_logout_supported`
* `backchannel_logout_supported`
### Fixed
* Send email API may fail with a `500`. This issue was introduced in version `1.9.0`.
* SAML v2 Invalid Redirect. This resolves [GitHub Issue #287](https://github.com/FusionAuth/fusionauth-issues/issues/287), thanks to [@prasanna10021991](https://github.com/prasanna10021991) for reporting and helping!
### Enhancement
* Allow request parameters to be provided on the Authorization endpoint in the OpenID Connect relaying party configuration. This allows FusionAuth to integrate with the [Twitch OpenID Authorization Grant implementation](https://dev.twitch.tv/docs/authentication/getting-tokens-oidc/#oidc-authorization-code-flow).
* This resolves [GitHub Issue #309](https://github.com/FusionAuth/fusionauth-issues/issues/309), thanks to [@tauinger-de](https://github.com/tauinger-de) for reporting and helping out!
* This is a partial fix to work around not supporting the `claims` parameter on the Authorize request. See [GitHub Issue #308](https://github.com/FusionAuth/fusionauth-issues/issues/308) for additional information.
### Fixed
* If you have one or more themes defined prior to upgrade you may be unable to login.
* Resolves [GitHub Issue #306](https://github.com/FusionAuth/fusionauth-issues/issues/306), thanks to [@flangfeldt](https://github.com/flangfeldt) and [@jerryhopper](https://github.com/jerryhopper) for the assist!
* See workaround in the linked GitHub issue.
* Resolves [Internal Server Error after Fusion Auth Upgrade to v 1.9.1](https://stackoverflow.com/questions/58083668/internal-server-error-after-fusion-auth-upgrade-to-v-1-9-1), thanks to [Tom Bean](https://stackoverflow.com/users/7205239/tom-bean) for reporting!
### Fixed
* Unable to modify the name of the default FusionAuth theme. If you attempt to edit the theme and save the form a validation error occurs that is not expected and will cause an exception. If you encounter this problem you can simply not edit the FusionAuth theme since you are not able to modify the templates anyway. Instead just duplicate the theme if you would like to view any of the default messages.
### New
* Full theme localization support for errors and all other text
* If you're interested in helping us crowd source additional languages check out this Git repo and open an issue or submit a PR.
* https://github.com/FusionAuth/fusionauth-localization
### Fixed
* When editing a new email template that contained `${user.tenantId}` the template validation may fail.
* Resolves [GitHub Issue #294](https://github.com/FusionAuth/fusionauth-issues/issues/294), thanks to [@tauinger-de](https://github.com/tauinger-de) for reporting the issue.
* A locked account may still be able to login via Google or other external identity provider.
* Resolves [GitHub Issue #301](https://github.com/FusionAuth/fusionauth-issues/issues/301), thanks to [@jerryhopper](https://github.com/jerryhopper) (a FusionAuth MVP) for the bug report!
* Previous to this change when using the OAuth2 login or the Login API, a locked account was treated as a "soft" lock and a `404` would be returned from the Login API which in turn displayed an Invalid credentials error. The account locked (soft delete) state will not return a `423` status code instead of a `404` which will result in a different message to the OAuth2 login.
### Fixed
* The SQL issue described below in the warning message has been resolved.
* Performing a clean install of `1.8.0-RC.1` may fail in some cases
* When `user.passwordChangeRequired` is `true` and you login via an external identity provider you will be redirected to `/password/change` with an invalid code so you will not be able to complete the change password workflow. You may work around this change by navigating back to the login page and clicking the forgot password link.
*Known Issues:* \
Any rows in the `user_external_ids` table with a `null` value in the `applications_id` column may cause the migration to fail. Prior to upgrading run the following SQL command: \
`DELETE from user_external_ids WHERE applications_id IS NULL;` This issue will be resolved in the final release of `1.8.0`. \
]
### Community MVPs
Thanks to all of our community members who take the time to open features, report bugs, assist others and help us improve FusionAuth! For this release we would like to thank the following GitHub users who helped us out!
* [@AlvMF1](https://github.com/AlvMF1)
* [@colundrum](https://github.com/colundrum)
* [@damienherve](https://github.com/damienherve)
* [@davidmw](https://github.com/davidmw)
* [@fabiojvalente](https://github.com/fabiojvalente)
* [@flangfeldt](https://github.com/flangfeldt)
* [@johnmaia](https://github.com/johnmaia)
* [@petechungtuyco](https://github.com/petechungtuyco)
* [@prabhakarreddy1234](https://github.com/prabhakarreddy1234)
* [@snmed](https://github.com/snmed)
* [@tombeany](https://github.com/tombeany)
* [@unkis](https://github.com/unkis)
* [@whiskerch](https://github.com/whiskerch)
* [@zbruhnke](https://github.com/zbruhnke)
### Changed
* Most of the configuration previously available in the System Settings has been moved to the Tenant configuration to allow for additional flexibility. This is important if you will be utilizing more than one tenant, you may now configure password policies, email configuration, etc per tenant. If you are using the System Configuration or Tenant APIs, please be aware of this change and plan accordingly. If you were manually synchronizing these configurations between systems, you will need to update these processes.
* SMTP configuration
* Event configuration
* Password configuration
* Failed Authentication configuration
* Password configuration
* JWT configuration
* Theme
* When using a theme, whenever possible provide the `tenantId` on the request using an HTTP request parameter. This will help ensure FusionAuth will render the page using your chosen theme. In most cases FusionAuth can identify the correct tenant and theme based upon other parameters in the request, but in some circumstances there is not enough information and FusionAuth will default to the stock theme if the `tenantId` is not explicitly provided.
* For example in each of the shipped email templates the following has been added to the generated URL `?tenantId=${tenantId}`. You may wish to add this to your email templates if you're using themes.
* If you were previously accessing a themed stylesheet in your template as `${loginTheme.stylesheet}` it is now accessed like this `${theme.stylesheet()}`.
### New
* Top level theme menu in FusionAuth UI. Settings -> Themes.
* Create, delete, edit and update themes
* Assign a named theme to a tenant
* Theme preview
* User modifiable [CORS configuration](/docs/operate/secure/cors)
* [GitHub Feature #180 : Expose a CORS configuration to the end user](https://github.com/FusionAuth/fusionauth-issues/issues/180)
* A public key may also be retrieved by `kid` in addition to the `applicationId` when using the [Public Key API](/docs/apis/jwt#retrieve-public-keys). This resolves [GitHub Issue #227](https://github.com/FusionAuth/fusionauth-issues/issues/227).
* PKCE support for use during the Implicit Grant
* New [User Email Verified](/docs/extend/events-and-webhooks/events/user-email-verified) and [User Registration Verified](/docs/extend/events-and-webhooks/events/user-registration-verified) events. Resolves [GitHub Issue #163](https://github.com/FusionAuth/fusionauth-issues/issues/163), thanks to [@unkis](https://github.com/unkis), [@prabhakarreddy1234](https://github.com/prabhakarreddy1234) and [@davidmw](https://github.com/davidmw) for the great feedback!
* Email Verification, Registration Verification, Change Password, Setup Password and Passwordless Login can be optionally configured to use codes made up of digits instead of long strings. This may be helpful if you wish the user to type in a code during an interactive workflow.
* Resolves [GitHub Issue #269](https://github.com/FusionAuth/fusionauth-issues/issues/269), thanks to [@zbruhnke](https://github.com/zbruhnke) for helping us get this one delivered.
### Fixed
* Tenant scoped SMTP configuration, password rules, event transactions, JWT signing configuration, etc.
* When viewing Refresh token expiration in the Manage User panel under the Sessions tab, the expiration may be displayed incorrectly if the Refresh Token Time to Live has been set at the Application level. The actual time to live was still correctly enforced, but this display may have been incorrect.
* In some cases an Id Token signed by FusionAuth may not be able to be verified if it is sent back to FusionAuth. This issue was introduced in version `1.6.0`.
* If the host operating system is not configured for `UTF-8` and you specify multi-byte characters in an email template subject, the subject text may not be rendered correctly when viewed by the recipient.
* Resolves [GitHub Issue #231](https://github.com/FusionAuth/fusionauth-issues/issues/231), thanks to [@Lechu67](https://stackoverflow.com/users/8266623/lechu67) for reporting via [Stack Overflow](https://stackoverflow.com/questions/57146832/) and helping to diagnose the issue.
* Toggle rendering issue in Firefox. Resolves [GitHub issue #260](https://github.com/FusionAuth/fusionauth-issues/issues/260), thanks to [@snmed](https://github.com/snmed) for the assist!
* When creating users and applications programatically, due to a timing issue, you may receive an unexpected error indicating the Application does not exist. Resolves [GitHub Issue $252](https://github.com/FusionAuth/fusionauth-issues/issues/252), thanks to [@johnmaia](https://github.com/johnmaia) for reporting the issue.
* An exception may occur when using the Login with Google feature if the `picture` claim returned is not a valid URI. Resolves [GitHub Issue #249](https://github.com/FusionAuth/fusionauth-issues/issues/249), thanks to [@damienherve](https://github.com/damienherve) for reporting the issue.
* A tenant may fail to be deleted. Resolves [GitHub Issue #221](https://github.com/FusionAuth/fusionauth-issues/issues/221), thanks to [@johnmaia](https://github.com/johnmaia) for the assist! If you encounter this issue, ensure the search index is updated, generally this will only happen if you programatically create users and then immediately attempt to delete a tenant.
* The relative link on the Change Password themed template to restart the Forgot Password workflow when the code has expired is broken. Resolves [GitHub Issue #280](https://github.com/FusionAuth/fusionauth-issues/issues/280), thanks to [@flangfeldt](https://github.com/flangfeldt) for letting us know!
* The Import API may fail due to a false positive during password salt validation. Resolves [GitHub Issue #272](https://github.com/FusionAuth/fusionauth-issues/issues/272), thanks to [@tombeany](https://github.com/tombeany) for reporting the issue.
* Modifying an Identity Provider configuration when an Application has been disabled may cause an error in the UI. Resolves [GitHub Issue #245](https://github.com/FusionAuth/fusionauth-issues/issues/245), thanks to [@fabiojvalente](https://github.com/fabiojvalente) for reporting the issue.
* When the FusionAuth schema exists in the database and you reconnect FusionAuth using the database maintenance mode, depending upon the version of PostgreSQL we may not properly detect that the schema exists and return an error instead of continuing. Resolves [GitHub Issue #237](https://github.com/FusionAuth/fusionauth-issues/issues/237), thanks to [@whiskerch](https://github.com/whiskerch) for reporting the issue.
* A typo in the Java FusionAuth client causes the to fail the `generateEmailVerificationId` request. Resolves [GitHub Issue #282](https://github.com/FusionAuth/fusionauth-issues/issues/282), thanks to [@petechungtuyco](https://github.com/petechungtuyco) for reporting the issue and pointing out the solution!
### Enhancement
* [JWT Refresh Token Revoke](/docs/extend/events-and-webhooks/events/jwt-refresh-token-revoke) event will contain a User object when available
* Resolves [GitHub Issue #255](https://github.com/FusionAuth/fusionauth-issues/issues/255), thanks to [@AlvMF1](https://github.com/AlvMF1) for the great suggestion!
* In a themed template that may have the `passwordValidationRules` available after a password validation field error will now always have the `passwordValidationRules` available if you choose to display them. Resolves [GitHub Issue #263](https://github.com/FusionAuth/fusionauth-issues/issues/263), thanks to [@AlvMF1](https://github.com/AlvMF1) for the suggestion!
* Updated PostgresSQL connector to support `SCRAM-SHA-256`. Thanks to [@colundrum](https://github.com/colundrum) for letting us know and assisting in testing. Resolves [GitHub Issue #209](https://github.com/FusionAuth/fusionauth-issues/issues/209)
* The [OpenID Connect discovery endpoint](/docs/lifecycle/authenticate-users/oauth/endpoints#openid-configuration) now accepts optional `tenantId` request parameter.
* A [User](/docs/apis/users) object is returned in the `jwt.refresh-token.revoke` event JSON.
* The field `tenantId` is returned in event JSON.
### Fixed
* When configuring a SAML v2 IdP relying party using the FusionAuth SP metadata, the configured ACS may not work properly. If you encounter this issue you may manually modify the relying party configuration to change the ACS endpoint to `/oauth2/callback`.
* Resolves [Stack Overflow : FusionAuth ADFS integration issue](https://stackoverflow.com/questions/57607810/fusionauth-adfs-integration-issue), thanks to [@johan](https://stackoverflow.com/users/3702939/johan) for reporting the issue.
### New
* SAML v2, OpenID Connect, Google, Facebook, Twitter and External JWT Identity Provider configurations now have a debug flag. When enabled a debug Event Log will be created during each request to the Identity Provider to assist in debugging integration issues that may occur. In addition, error cases will be logged in the Event log instead of to the product log.
* SAML v2 Service Provider (Relaying Party) Metadata URL
### Fixed
* In some cases when running FusionAuth behind a proxy without setting the `X-Forwarded-Port` header the URLs returned in the OpenID Configuration discovery document may contain an `https` URL that is suffixed with port `80`. If this is encountered prior to this version you may simply add the `X-Forwarded-Port` header in your proxy configuration.
* SAML v2 fix when using `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` or `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` Name Id formats.
* Resolves [GitHub Issue #205](https://github.com/FusionAuth/fusionauth-issues/issues/205), thanks to [@mikerees](https://github.com/mikerees) for reporting the issue and helping us test a fix.
* SAML v2 fix in the IdP Metadata. The `IDPSSODescriptor` was missing the `protocolSupportEnumeration` which may cause some SAML metadata parsers to fail processing.
* Resolves [GitHub Issue #235](https://github.com/FusionAuth/fusionauth-issues/issues/235), thanks to [@user1970869 ](https://github.com/user1970869 ) for reporting the issue and helping us test a fix.
* SAML v2 fix in the IdP Metadata. The value returned in the `issuer` attribute was not the same as the `entityId` provided in the metadata which may cause some SAML metadata parsers to fail processing.
* Resolves [GitHub Issue #240](https://github.com/FusionAuth/fusionauth-issues/issues/240), thanks to [@user1970869 ](https://github.com/user1970869 ) for reporting the issue and helping us test a fix.
* And audit log entry may not be created for a FusionAuth admin that does not have an email address when modifying configuration with the FusionAuth UI.
* Resolves [GitHub Issue #268](https://github.com/FusionAuth/fusionauth-issues/issues/268)
### Enhancement
* Integration details have been moved to a view dialog for each Identity Provider configuration. Previously these values were provided as read only fields on the edit panel in the UI.
* See the View action for your Identity Provider configurations by navigating to Settings -> Identity Providers.
### Fixed
* Deleting a user that has recently had a failed login may fail when FusionAuth is tracking failed login attempts to lock user accounts.
* Resolves [GitHub Issue #184 : Cannot delete user with too many login attempts](https://github.com/FusionAuth/fusionauth-issues/issues/184), thanks to [@gmpreussner](https://github.com/gmpreussner) for reporting the issue.
* Login to a 3rd party SAML IdP may fail
* Resolves [GitHub Issue #181 : Trouble with SAML and OpenID logins](https://github.com/FusionAuth/fusionauth-issues/issues/181), thanks to [@davidmw](https://github.com/davidmw) for reporting the issue.
* Fix the uptime calculation for nodes when viewed in the About panel. System -> About
### Fixed
* Possible migration error for PostgreSQL users
### Changed
* The `timezone` field in the User and UserRegistration must be a [IANA](https://www.iana.org/time-zones) time zone. This was previously assumed, but not always enforced. If a timezone is set for a User or UserRegistration that is not a valid IANA timezone, `null` will be returned when retrieving the User or UserRegistration timezone.
### New
* Family and relationship modeling. Yeah, everyone has users, but does your IdP manage family relationships?
* Family concepts
* [Family APIs](/docs/apis/families)
* Consent management. Need to record parental consent, or track opt-in for your users? Look no further.
* Consent concepts
* [Consent APIs](/docs/apis/consents)
* We will ship FusionAuth with COPPA VPC, and COPPA Email+ consents, additional consents may be added through the Consent management interface and through the Consent APIs.
* Export of Audit Logs to a zipped CSV in the UI and via the [Export API](/docs/apis/audit-logs#export-audit-logs)
* Export of Login Records to a zipped CSV in the UI and via the [Export API](/docs/apis/login#export-login-records)
* Login Record view that contains limited search and pagination capability. In the UI see System -> Login Records
* Retention policy for Audit Logs. This feature is disabled by default and may be enabled to retain a configured number of days worth of Audit Logs.
* Retention policy for Login Records. This feature is disabled by default and may be enabled to retain a configured number of days worth of Login Records.
### Fixed
* Some timezones may not be correctly discovered during login. When this occurs an `undefined` value is set which may cause an error during login to the FusionAuth UI.
* Support importing Bcrypt hashes that contain a `.` (dot). The Bcrypt Base64 encoding uses a non standard character set which includes a `.` (dot) instead of a `+` (plus) as in the standard character set. Thank you to Diego Souza Rodrigues for discovering this issue and letting us know!.
* Better support for third party 2FA devices such as an RSA key fob. When providing FusionAuth with a secret to enable Two Factor authentication we will accept a string in a Bas32 or Base64 encoded format. The documentation has been updated to further clarify this behavior. Previously if you brought your own secret to FusionAuth to enable 2FA, depending upon the format of the key, you may not have been successful in enabling 2FA for a user.
* Managed domains were not being returned properly for a SAML v2 IdP configuration. This means that you could not limit the SAML v2 IdP configuration to users with a specific email domain.
### Enhancement
* The User Registration object is now available as a top level object in the Verify Registration email template. The registration was previously available in the `user` object, but it will now also be a top level object `registration`.
* Support arbitrary URIs for OAuth redirects.
* Resolves [GitHub Issue #58 : Support OAuth2 redirect to an arbitrary scheme in support of native applications](https://github.com/FusionAuth/fusionauth-issues/issues/58)
* Add `user.mobilePhone` to the search index. For an existing installation, to take advantage of this field for existing users, you may need to rebuild the search index. See System -> Reindex
* Resolves [GitHub Issue #165 : Add mobilePhone in User Search](https://github.com/FusionAuth/fusionauth-issues/issues/165)
* Thanks to [@petechungtuyco](https://github.com/petechungtuyco) for letting us know and suggesting the addition.
### Fixed
* Using OpenID Connect with Microsoft Azure AD may fail
* Thanks to [@stevenrombauts](https://github.com/FusionAuth/fusionauth-issues/issues/153) and [@plunkettscott](https://github.com/plunkettscott) for reporting the issue. [OpenID connect fails with Azure AD #153](https://github.com/FusionAuth/fusionauth-issues/issues/153).
### Changed
* Deprecated the following properties `SystemConfiguration` and `Application` domain. This is all now managed through Key Master, and existing keys have been migrated into Key Master.
* `jwtConfiguration.issuer`
* `jwtConfiguration.algorithm`
* `jwtConfiguration.secret`
* `jwtConfiguration.publicKey`
* `jwtConfiguration.privateKey`
* Deprecated the following property `SystemConfiguration.jwtConfiguration.issuer`, it has moved to `SystemConfiguration.issuer`.
* A new macro was added to the `_helpers.ftl` that may be managed by your theme. If you have modified the `_helpers.ftl` template as part of your theme, you will either need to reset that template and merge your changes back in, or add the following code to your `_helpers.ftl` managed by your theme. If you encounter an issue with this, you will still likely be able to login to correct the issue, if you do get stuck you may disable your theme to login. See [Troubleshooting themes](/docs/customize/look-and-feel/#troubleshooting).
```html
[#macro link url text extraParameters=""]
${text?html}
[/#macro]
```
____
### New
* Support for SAMLv2 IdP. This satisfies [GitHub Issue #3](https://github.com/FusionAuth/fusionauth-issues/issues/3)
* Support for SAMLv2 Service Provider to support federated authentication to a SAMLv2 Identity Provider. This satisfies [GitHub Issue #104](https://github.com/FusionAuth/fusionauth-issues/issues/104)
* Lambda support. Lambdas are user defined JavaScript functions that may be executed at runtime to perform various functions. In the initial release of Lambda support they can be used to customize the claims returned in a JWT, reconcile a SAML v2 response or an OpenID Connect response when using these Identity Providers.
* See the Lambda API and the new Lambda settings in the UI Settings -> Lambdas.
* Event Log. The event log will assist developers during integration to debug integrations. The event log will be found in the UI under System -> Event Log.
* SMTP Transport errors
* Lambda execution exceptions
* Lambda debug output
* SAML IdP integration errors and debug
* Runtime exceptions due to email template rendering issues
* And more!
* Key Master, manage HMAC, Elliptic and RSA keys, import, download, generate, we do it all here at Key Master.
* [Key APIs](/docs/apis/keys)
* New events
* `user.login.failed`
* `user.login.success`
* `user.registration.create`
* `user.registration.update`
* `user.registration.delete`
* Easily duplicate email templates using the Duplicate action.
* https://github.com/FusionAuth/fusionauth-issues/issues/142
* Manage Access Token and Id Token signing separately
### Enhancement
* Insert instant provided on the Import API for Users and Registrations will be reflected in the historical registration reports
* https://github.com/FusionAuth/fusionauth-issues/issues/144
* Additional node information will be available on the About panel when running multiple FusionAuth nodes in a cluster. See System -> About.
### Fixed
* If Passwordless login is disabled because no email template has been configured the button will not be displayed on the login panel. If a user attempts to use the passwordless login and the feature has been disabled or the user does not have an email address a error will be displayed to alert the user.
* If you are using the Implicit Grant and you have Self Service Registration enabled for the same application, the redirect after the registration check will assume you are using the Authorization Code grant. To work around this issue prior to this release, disable Self Service Registration. Thanks to [@whiskerch](https://github.com/whiskerch) for reporting this issue in [GitHub Issue #102](https://github.com/FusionAuth/fusionauth-issues/issues/102).
* Fixed OpenID Connect federated login. Our JavaScript code was throwing an exception due to the removal of the `device` field from OAuth. This code wasn't updated and therefore would not perform the redirect to the third-party Open ID Connect IdP. To fix this issue in 1.5.0 or below, you can remove this line from OpenIDConnect.js on or near line 48: `+ '&device=' + Prime.Document.queryFirst('input[name=device]').getValue()`.
* When you use the Refresh Grant with a Refresh Token that was obtained using the Authorization Code grant using the `openid` scope, the response will not contain an `id_token` as you would expect. This fixes [GitHub Issue #110 - OIDC and Refresh Tokens](https://github.com/FusionAuth/fusionauth-issues/issues/110). Thanks to [@fabiosimeoni](https://github.com/fabiosimeoni) for reporting this issue
* When using the OpenID Connect Identity Provider that requires client authentication may fail even when you provide a client secret in your OpenID Connect configuration.
* https://github.com/FusionAuth/fusionauth-issues/issues/118
* https://github.com/FusionAuth/fusionauth-issues/issues/119
* https://github.com/FusionAuth/fusionauth-issues/issues/122
### Changed
* Removed `/oauth2/token` from the CORS configuration. This change will cause the CORS filter to reject a `POST` request to the `/oauth2/token` endpoint when the request originates in JavaScript from a different domain. This will effectively prohibit the use of the OAuth2 Password grant from JavaScript.
* The `device` parameter is no longer required on the [Login API](/docs/apis/login) or the [Authorized](/docs/lifecycle/authenticate-users/oauth/endpoints#authorize) endpoint in order to receive a Refresh Token. If the `device` parameter is provided it will be ignored.
* Correct the [Refresh API](/docs/apis/jwt#refresh-a-jwt) response body to match the documentation. If you are currently consuming the JSON body of this API using the `POST` method, you will need to update your integration to match the documented response body.
### New
* Support for Passwordless login via email. See [Passwordless API](/docs/apis/passwordless) if you'll be integrating with this API to build your own login form.
* To use this feature using the provided FusionAuth login form, enable Passwordless by navigating to your FusionAuth Application and selecting the `Security` tab.
* Support for the OAuth2 Implicit Grant. See the [OAuth 2.0 & OpenID Connect Overview](/docs/lifecycle/authenticate-users/oauth/) and [OAuth 2.0 Endpoints](/docs/lifecycle/authenticate-users/oauth/endpoints) for additional information.
* The `Authorization Code`, `Password`, `Implicit` and `Refresh Token` grants maybe enabled or disabled per application. See `oauthConfiguration.enabledGrants` property in the [Application API](/docs/apis/applications), or the `OAuth` tab in the Application configuration in the FusionAuth UI.
* The [Change Password API](/docs/apis/users) can be called using a JWT. This provides additional support for the Change Password workflow in a single page web application. See the Change Password API for additional details.
* The [Change Password API](/docs/apis/users) in some cases will return a One Time password (OTP). This password may then be exchanged for a new JWT and a Refresh Token on the Login API. This allows for a more seamless user experience when performing a change password workflow. See the Change Password and Login API for additional details.
* The [Login API](/docs/apis/login) can now be restricted to require an API key. The default for new applications will require authentication which can be disabled. Existing applications will not require authentication via API to preserve the existing behavior. The Login API may also be restricted from return Refresh Tokens are allowing an existing Refresh Token be used to refresh an Access Token. These settings will be configurable per Application, see the Application API for additional details, or the `Security` tab in the Application configuration in the UI. If using the [Application API](/docs/apis/applications), see the `application.loginConfiguration` parameters.
* The `c_hash`, `at_hash` and `nonce` claims will be added to the `id_token` payload for the appropriate grants.
* Add support for `client_secret_post` to the already provided `client_secret_basic` Client Authentication method. This means that in addition to using HTTP Basic Authentication, you may also provide the `client_id` and `client_secret` in the request body.
### Enhancement
* Better ECDSA private and public key validation to ensure the algorithm selected by the user matches the provided key.
* When using the Change Password workflow in the OAuth2 Implicit or Authorization Code grants, the user will be automatically logged in upon completing a change password that is required during login.
* The Two Factor Login API will return the `twoFactorTrustId` as an HTTP Only secure cookie in addition to being returned in the JSON response body. This provides additional support and ease of use when making use of this API in a single page web application. See the Two Factor Login API for additional details.
### Fixed
* When using the Login Report in the UI and searching by user, if you have more than one tenant you will encounter an error.
* Validation errors are not displayed in the Add Claim dialog when configuring claim mapping for an External JWT Identity Provider
* Calling the Tenant API with the `POST` or `PUT` methods w/out a request body will result in a `500` instead of a `400` with an error message.
* When a locale preference has not been set for a FusionAuth admin and the English locale is used the user may see dates displayed in `d/M/yyyy` instead of `M/d/yyyy`.
* Fix some form validation errors during self-registration.
* The Action user action on the Manage User panel was opening the Comment dialog instead of the Action user dialog
* When a user has 2FA enabled and a password change is required during login, the 2FA will now occur before the change password workflow
* When more than one tenant exists, the Forgot Password link on the FusionAuth login page will not function properly.
* The Logout API may not always delete the `access_token` and `refresh_token` cookies if they exist on the browser.
* The `id_token` will be signed with the `client_secret` when `HS256`, `HS384` or `HS512` is selected as the signing algorithm. This is necessary for compliance with [OpenID Connect Core 3.1.3.7 ID Token Validation](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation). This fixes GitHub issue [GitHub Issue #57](https://github.com/FusionAuth/fusionauth-issues/issues/57), thanks to [@anbraten](https://github.com/anbraten) for reporting this issue. If you encounter this issue prior to this version, copy the Client Secret found in the UI on the `OAuth` tab of your Application configuration into the HMAC secret on the `JWT` configuration tab.
* The [Login API](/docs/apis/login) will now return a `400` with an error JSON response body if the `applicationId` parameter does not belong to any configured applications. Previous to this release, this was treated the same as if the User was not registered to the requested application.
* A change to the Docker build for permissions reduced the overall `fusionauth-app` image by ~ 200 MB.
### Changed
* Renamed `Type` enum in `DeviceInfo` class to `DeviceType`. This will only affect you if you are using the Java or C# client and reference this enum directly. If you are using this class directly, you may need to update an import in your client code.
* More than one authorization code may exist for a single user at a given time. This will allow multiple asynchronous requests to begin an OAuth2 Authorization Grant workflow and succeed regardless of order.
### New
* Self service registration. You may optionally enable this feature per application and allow users to create a new account or register for new applications without building your own registration forms.
* JSON Web Key set support. This endpoint will be exposed at `/.well-known/jwks.json` and will be published in the [OpenID Configuration](/docs/lifecycle/authenticate-users/oauth/endpoints#openid-configuration) metadata endpoint as well. Prior to this release the public keys used to sign JSON Web Tokens were only available in PEM format using the [Public Key API](/docs/apis/jwt#retrieve-public-keys), this endpoint will still be available and supported.
* See [JSON Web Key Set (JWKS)](/docs/lifecycle/authenticate-users/oauth/endpoints#json-web-key-set-jwks) for more information.
* Added Elliptic Curve signature support for JSON Web Tokens, ES256, ES384 and ES512.
* Added Typescript client library https://github.com/FusionAuth/fusionauth-typescript-client
* The Login Report may now be optionally filtered to a particular User in the UI, and the [Login Report](/docs/apis/reports#retrieve-login-report) API will now take `loginId` or `userId`.
### Fixed
* When using Docker compose, if you start up with `--pull` to update to the latest version of FusionAuth and there happens to be a database schema update, the silent configuration mode may fail. This occurs because the silent configuration was not performing the database schema update automatically. If you encounter this issue, you will need to manually update the schema.
* This will only occur if you are running a version of FusionAuth prior to `1.1.0` and upgrade using `--pull` during `docker compose up`.
* When you have multiple tenants created, a tenant may be deleted with an API key that is not assigned to the tenant. This has been corrected and a tenant may only be deleted using an API key that is not assigned to any tenant. This issue will only affect you if you have more than one tenant.
* Updated Maintenance Mode (setup wizard) to work with MySQL version 8.0.13 and above. MySQL has changed their SSL/TLS handling and our connections were not correctly handling public keys. This has been fixed by allowing FusionAuth to perform a secondary request to MySQL to fetch the public key.
* Logging in with a Social Login provider such as Google for an existing FusionAuth user may cause them to be unable to login to FusionAuth directly using their original credentials.
* When using the OpenID Connect Identity Provider, the incoming claim `given_name` was being saved in the `fullName` field instead of the `firstName`.
* When a user is soft deleted, actioned to prevent login, expired, or they have changed their password since their last login, their SSO session will be invalidated instead of waiting for the session to expire.
* Resolves [GitHub Issue #59 :Using a access token for a lock account](https://github.com/FusionAuth/fusionauth-issues/issues/59)
### Internal
* Upgrade to fusionauth-jwt 3.0.1 in support of Elliptic Curve crypto support.
### Changed
* API key will take precedence for API authentication if both a JWT and an API key are provided on the request. For example, when making a GET request to the User API, if a JWT is provided in a cookie, and a valid API key is also provided in the `Authorization` HTTP header, the previous design was to prefer the JWT. This design point meant that even when an API key was provided, even when providing a valid API key, you would be unable to retrieve any user but the one represented by the JWT.
* Resolves [GitHub Issue #43 : Id is ignored on Retrieve User when JWT is present](https://github.com/FusionAuth/fusionauth-issues/issues/43)
* The `client_id` is no longer required on the OAuth Token endpoint when client authentication is configured as required, in this scenario the client Id is provided in the HTTP Basic Authorization header.
* Resolves [GitHub Issue #54 :Token request returning 500 when client_id is omitted](https://github.com/FusionAuth/fusionauth-issues/issues/54)
### Fixed
* When editing the JWT settings in the FusionAuth application the UI a JavaScript error may cause some of the settings to not render properly. This error was introduced in version `1.3.0`.
* Added missing properties to the Application view dialog in the FusionAuth UI.
* The `openid` scope may not be honored during login when a user has Two Factor authentication enabled. The symptom of this issue is that the response from the Token endpoint will not contain an `id_token` even when the `openid` scope was requested.
* Resolves [GitHub Issue #53 : Authorization with scope openid fails when 2FA is enabled](https://github.com/FusionAuth/fusionauth-issues/issues/53)
* Validation for the OAuth2 Token endpoint may fail when the `client_id` request body parameter is omitted and return a `500` instead of a `400` status code.
* Resolves [GitHub Issue #54 : Token request returning 500 when client_id is omitted](https://github.com/FusionAuth/fusionauth-issues/issues/54)
* When a OAuth2 redirect URI is registered with a query parameter, the resulting redirect URI will not be built correctly.
* Resolves [GitHub Issue #55 : Adding a query parameter to the redirect_uri causes an invalid URI to be returned](https://github.com/FusionAuth/fusionauth-issues/issues/55)
* When trying to configure Elasticsearch engine during maintenance mode the index may get created but fail to leave maintenance mode. FusionAuth makes a `HEAD` request to Elasticsearch to check if the required indexes exist during startup and prior to leaving maintenance mode. When connected to an AWS Elasticsearch cluster this request does not behave as expected which causes FusionAuth to stay in maintenance mode. This issue has been resolved and should allow FusionAuth to properly connect to and utilize Elasticsearch running in an AWS cluster.
### New
* An Application may disable the issue of refresh tokens through configuration. See `oauthConfiguration.generateRefreshTokens` in the [Application API](/docs/apis/applications) or the `Generate refresh tokens` toggle in the FusionAuth UI when editing an application.
* The OAuth2 client secret may be optionally regenerated using the FusionAuth UI during Application edit.
* Support for OAuth2 confidential clients, this is supported by optionally requiring client authentication via configuration. See `oauthConfiguration.requireClientAuthentication` in the [Application API](/docs/apis/applications) or the `Require authentication` toggle in the FusionAuth UI when editing an application.
### Fixed
* Calling the [Introspect](/docs/lifecycle/authenticate-users/oauth/endpoints#introspect) endpoint with a JWT returned from the Issue API may fail due to the missing `aud` claim.
* The MySQL schema previously was using `random_bytes` which is not available in MariaDB. These usages have been replaced with an equivalent that will function the same in MySQL and MariaDB.
* Thanks to [@anbraten](https://github.com/anbraten) for bringing this to our attention and suggesting and verifying a solution via [GitHub Issue #48 : Support for MariaDB](https://github.com/FusionAuth/fusionauth-issues/issues/48)
* When editing or adding a new user in the FusionAuth UI, the `Birthdate` field may get set automatically before the date selector is utilized. A JavaScript error was causing this condition and it has been fixed.
* Resolves [GitHub Issue #41 : Birthday is autofilled when adding or editing a user](https://github.com/FusionAuth/fusionauth-issues/issues/41)
### Fixed
* Add `X-FusionAuth-TenantId` to allowed CORS headers.
* Resolves [GitHub Issue #44 : CORS blocks API request containing X-FusionAuth-TenantId](https://github.com/FusionAuth/fusionauth-issues/issues/44)
* When FusionAuth is running behind a proxy such as an AWS ALB / ELB the redirect URI required to complete login may not be resolved correctly. This may cause the redirect back to the FusionAuth UI login to fail with a CSRF exception. If you encounter this issue you may see an error message that says `Something doesn't seem right. You have been logged out of FusionAuth`. The work-around for this issue if you encounter it will be to perform the redirect from HTTP to HTTPS in your load balancer.
* Some minor usability issues in the Identity Provider configuration UI.
### Enhancement
* Better error handling when an API caller sends invalid JSON messages. Prior to this enhancement if FusionAuth did not provide a specific error message for a particular field a `500` HTTP status code was returned if the JSON could not be parsed properly. This enhancement will ensure that sending a FusionAuth API invalid JSON will consistently result in a `400` status code with a JSON body describing the error.
* Resolves [GitHub Issue #17 : Malformed or invalid JSON causes 500 error](https://github.com/FusionAuth/fusionauth-issues/issues/17)
* Allow an Identity Provider to be enabled and disabled from the UI. You may still choose to enable or disable a specific Application for use with an Identity Provider, but with this enhancement you may not turn off an Identity Provider for all Applications with one switch.
### Fixed
* Preserve Application Identity Provider configuration for disabled Applications when editing a Identity Provider from the UI.
### New
* Add TTL configuration for Refresh Tokens to the Application configuration. When you enable JWT configuration per Application this value will override the global setting.
### Fixed
* An error in the Twitter OAuth v1 workflow has been resolved.
### Fixed
* If you were to have an Identity Provider for federated third party JSON Web Tokens configured prior to upgrading to `1.1.0` FusionAuth may fail during the database migration to version `1.1.0`.
### New
* Social login support
* [Facebook](/docs/apis/identity-providers/facebook) Identity Provider
* [Google](/docs/apis/identity-providers/google) Identity Provider
* [Twitter](/docs/apis/identity-providers/twitter) Identity Provider
* [OpenID Connect](/docs/apis/identity-providers/openid-connect) Identity Provider
* Full theme support for login. See the [Login Theme](/docs/customize/look-and-feel/) tutorial for additional information and examples.
* Better localization support in the FusionAuth UI. You now have the option to set or modify your preferred language for use in the FusionAuth UI.
Providing a preferred language will cause dates to be formatted based upon your preference. For example, the default data format is `M/D/YYYY`, but
if you are not in the United States this may not be the way you expect a date to be formatted. If you set your locale to `French` you will now
see a more appropriate format of `D/M/YYYY`. This value is stored on the User Registration for FusionAuth in the `preferredLanguages` field.
### Enhancement
* When viewing sessions (refresh tokens) on the Manage User panel, the start and expiration times will be displayed.
### Fixed
* If FusionAuth starts up in maintenance mode and stays there for an extended period of time without the User completing the configuration from the web browser, FusionAuth may get stuck in maintenance mode. If you encounter this issue, where you seemingly are entering the correct credentials on the Database configuration page and are unable to continue, restart FusionAuth and the issue will be resolved.
### Fixed
* When running in Docker Compose, FusionAuth cannot connect to the search service when trying to exit the setup wizard.
* https://github.com/FusionAuth/fusionauth-containers/issues/2
### Enhancement
* Better support for running in Docker. Enhanced silent configuration capability for database and search engine boot strap configuration in Docker Compose to be more resilient.
### Fixed
* If custom data is added to an Application, Group or Tenant before editing the corresponding object in the UI, the custom data may be lost.
### New
* Better support for running in Docker. Configuration can be override using environment variables. See [Docker Install](/docs/get-started/download-and-install/docker) for additional information.
### Fixed
* The first time a user reached the failed login threshold and a `409` response code was returned the response body was empty. Subsequent login requests correctly returned the JSON response body with the `409`, now the JSON response body is correctly returned the first time the user reaches the failed login threshold.
### Fixed
* When using PostgreSQL an exception may occur during an internal cache reload request. If you encounter this issue you will see a stack trace in the `fusionauth-app.log`. If you see this error and need assistance, please open an issue in the FusionAuth [Issues](https://github.com/FusionAuth/fusionauth-issues) GitHub project.
```
Unexpected error. We're missing an internal API key to notify distributed caches.
```
### New
* General availability release
{/*
*/}
# 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).
# Login Pages Cookies
import Aside from 'src/components/Aside.astro';
import CookieList from 'src/content/docs/reference/_cookie-list.astro';
## Overview
Cookies are a critical part of web applications.
When you call certain APIs, such as the Login API, cookies may be set. Such cookies are specified in the [API documentation](/docs/apis/).
When you use the [hosted login pages](/docs/get-started/core-concepts/integration-points#hosted-login-pages), the [hosted backend](/docs/apis/hosted-backend) or [interact with the APIs](/docs/apis/), FusionAuth uses cookies to enable functionality.
## Domains
The domain of all cookies is the domain on which the FusionAuth instance is running. You can control the domain FusionAuth uses by [setting up a proxy](/docs/operate/deploy/proxy-setup).
In other words, if FusionAuth serves requests at `auth.piedpiper.com`, it will only set cookies for this value: `auth.piedpiper.com`. It will never set cookies for `.piedpiper.com`. The ability to control the domain of the cookie set is an [open feature request](https://github.com/FusionAuth/fusionauth-issues/issues/1991).
Additionally, most cookies set by FusionAuth will use the [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) value of `Strict` or `Lax`. This is to protect against [Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf). Practically, it means a browser will block those cookies on a cross-site request unless the browser is navigating to the origin site from an external site, which is something to consider if you intend to access FusionAuth from a different domain using something like an IFRAME.
## Cookie List
# FusionAuth Release Notes - What's New in FusionAuth
import Aside from 'src/components/Aside.astro';
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 KnownIssue from 'src/components/docs/release-notes/ReleaseNotesKnownIssue.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 makes changes to API key requirements for the `/api/identity-provider` endpoint.
Tenant-scoped API keys can only be used to configure identity providers belonging to the same tenant. A global API key is required to configure global identity providers.
If you are upgrading from a version prior to FusionAuth 1.61.2 and you have customized your theme, upgrade to 1.61.2 first, add missing templates to your theme, and then upgrade to 1.62.0.
### New
*
FusionAuth now provides an MFA Lambda that you can use to dynamically decide whether a user should receive an MFA challenge, even if trust has already been established. This can be used to implement adaptive MFA capability and enable additional step-up workflows.
*
FusionAuth can now run in a mode that allows the use of FIPS-compliant verified cryptographic modules. See [Compliance Frameworks](docs/operate/secure/compliance) for more details.
*
FusionAuth now supports pre-verification of user identities! When creating a user, either through self-service registration or with the API, you can now force an email address or phone number to be verified before the user is created. This prevents a user record from tying up an identity in an unverified state.
### Fixed
*
The dashboard for the FusionAuth admin UI displays a few reports to provide a glimpse at system usage. A large number of applications or high user traffic may degrade load times for these reports, causing the dashboard page to load slowly or even time out.
*
IdP (federated) logins do not work for Universal Apps. Instead, the error message `Invalid_Request. Missing_tenant_id` is displayed.
*
When family settings are enabled, including requiring a parent email, the parent email is not persisted during self-service registration by a child. This prevents an email from being sent to the parent email.
*
When creating a new lambda, the lambda code in the code editor doesn't update when changing the lambda type. The code needs to update to display the default lambda body for the given type.
### Enhancements
*
You can now create tenant-scoped instances of identity providers. Tenant-scoped identity providers can only be used for authentication workflows within that tenant and are only configurable for applications belonging to that tenant, as well as universal applications. Managed domains also be reused on identity providers belonging to different tenants. Managed domains on global identity providers remain globally unique.
Tenant-scoped identity provider configurations can be managed by tenant-scoped API keys and requests.
Tenant-scoped identity providers are especially useful if you want to restrict identity provider availability to users belonging to a specific tenant.
*
FusionAuth now supports EdDSA key pairs using the Ed25519 algorithm. Keys of this type can be used to sign and validate JWTs.
*
Version `1.62.0` has a new look! We've updated the styling of the admin app while keeping the functionality the same. Not that this update will not affect any custom themes you've created, however the default theme has changed.
### Internal
*
Update dependencies.
* Upgrade `io.fusionauth:fusionauth-jwt` `5.3.3` -> `6.0.0`
* Upgrade `org.primeframework:prime-mvc` `5.6.1` -> `5.7.0`
* Add `org.bouncycastle:bc-fips` `2.1.2`
* Add `org.bouncycastle:bctls-fips` `2.1.22`
### Security
*
Improvements have been made to how FusionAuth processes signatures for encrypted SAML assertions to mitigate an identified vulnerability. If you are using using a SAML IdP, especially when allowing IdP initiated login, please plan to upgrade at your earliest convenience.
### Internal
*
Update dependencies.
* Upgrade `io.fusionauth:fusionauth-samlv2` `1.1.1` -> `1.1.3`
### Fixed
*
When testing Email Templates in the FusionAuth admin UI, rendering some template types resulted in an error. All template types can now be tested in the admin UI.
*
When a Minimum Password Age is configured for the tenant, creating a user without a password resulted in an exception. Users can now be created without a password in tenants with a minimum password age requirement, and password age rules are enforced after the user sets a password.
*
Providing an expired Id Token to the `/oauth2/logout` endpoint using the `id_token_hint` parameter resulted in an OAuth error. The `/oauth2/logout` endpoint once again accepts expired Id Tokens in accordance with the specification.
Several changes are required to support multiple configurations of various identity provider types that were previously restricted to a single configuration per FusionAuth instance. References to the legacy sign with Google JavaScript library, [deprecated by Google in 2023](https://developers.google.com/identity/sign-in/web/deprecation-and-sunset), have been removed from FusionAuth. Please migrate to the updated [Sign in with Google](https://developers.google.com/identity/gsi/web/guides/overview) integration to continue using the Google identity provider.
**Identity Provider API**
For `/api/identity-provider` PUT/PATCH/DELETE:
The variant of these APIs that resolve the identity provider by a `type` query string parameter are deprecated. Use the variant that provides the `identityProviderId` via a URL path segment instead.
### Fixed
*
In version `1.59.0` we started indexing the new `user.phoneNumber` field for searches. `IndexUser` had a new field added, but the doc annotation was missing the version.
*
The `GET /api/user/change-password` endpoint does not allow a `loginId` type of `phoneNumber`. Additionally, client libraries are incorrectly passing a `username` parameter instead of a `loginId` parameter in `checkChangePasswordUsingLoginId` calls. This API endpoint is also lacking documentation.
*
When federating with a Google IdP, there are situations where a user can be re-prompted for authentication when already having valid FusionAuth and Google IdP sessions. SSO should now be honored correctly in these cases.
*
After establishing MFA trust on a device, a user is being re-challenged during a voluntary password reset, even during the trust period. The user should be able to change their password without completing another MFA challenge.
*
During startup, FusionAuth can output duplicate log entries. This was especially present with silent mode enabled. Logging should now be more efficient.
*
When a user first logs into a tenant configured with a connector, they will see an error when MFA is required and/or an updated and stronger password policy is in place. Subsequent logins behave normally.
*
Searches for users using nested searches involving registration fields may return incomplete results in some cases.
*
When using SCIM PATCH to add a user field, exiting fields are being removed. PATCH should now be handled as expected.
*
Performing a user reindex intermittently results in an `email`, `username`, or `phoneNumber` being omitted from Elastic/OpenSearch and not being searchable.
*
Some unwanted JavaScript errors are reported in the browser console on some pages, including the maintenance mode page and the application scope management page. These errors should now be handled more gracefully.
*
SCIM group searches are not properly honoring the `eq` operator. This operator should be doing an exact (but case-insensitive) search, but instead is doing a wildcard search.
*
Webhook `user.delete` events were not populating `email`, `username`, or `phoneNumber` fields when users were deleted under certain circumstances.
### Enhancements
*
You can now create multiple instances of any identity provider type, each with its own distinct configuration and reconcile lambda. This is especially useful if you have users mapped to different tenants, and want the ability to have an identity provider of the same type in each tenant, each having its own distinct config.
*
We've added the ability to set maximum sizes on both the HTTP request header and body. These can be useful for blocking invalid requests before they are processed by FusionAuth's HTTP server.
*
FusionAuth now supports the SAML v2.0 ForceAuthn attribute. When using FusionAuth as an IdP, this attribute will force re-authentication of the user, regardless of their SSO session state. This also resolves [GitHub Issue #1736](https://github.com/FusionAuth/fusionauth-issues/issues/1736)
### Internal
*
Update dependencies.
* Upgrade `io.fusionauth:fusionauth-jwt` `5.3.2` -> `5.3.3`
* Upgrade `io.fusionauth:java-http` `0.3.7` -> `1.4.0`
* Upgrade `org.freemarker:freemarker` `2.3.33` -> `2.3.34`
* Upgrade `org.primeframework:prime-email` `0.21.1` -> `0.22.0`
* Upgrade `org.primeframework:prime-js` `1.7.0` -> `1.8.0`
* Upgrade `org.primeframework:prime-mvc` `4.36.0` -> `5.6.1`
* Upgrade `ch.qos.logback` `1.5.16` -> `1.5.19`
* Upgrade `org.mybatis:mybatis` `3.5.16` -> `3.5.19`
* Upgrade `com.fasterxml.jackson.*` `2.17.2` -> `2.19.2`
* Upgrade `org.slf4j:slf4j-api` `2.0.13` -> `2.0.17`
* Upgrade `org.postgresql:postgresql` `42.7.3` -> `42.7.7`
* Upgrade `io.fusionauth:fusionauth-samlv2` `1.0.0` -> `1.1.1`
### Fixed
*
When using FusionAuth as a SAML Service Provider (SP), receiving a SAML Response containing an Assertion with an attribute value of `null` or of an unsupported type will result in a failure to parse the Response.
This issue was introduced in version `1.60.0` and has been corrected.
### Fixed
*
When using FusionAuth as a SAML IdP with a SAML Populate lambda that reads or modifies the SAML assertion will fail causing the login request to fail.
This issue was introduced in version `1.60.0` and has been corrected.
### Known Issues
*
When using FusionAuth as a SAML IdP with a SAML Populate lambda that reads or modifies the SAML assertion will fail causing the login request to fail. If you have encountered this issue, please upgrade to `1.60.1` if possible, or click on the linked GitHub issue to review the temporary workaround.
* Performing a user reindex occasionally results in an email, username, or phoneNumber, for a small fraction of users, to not be searchable via Elasticsearch/OpenSearch.
*
When using FusionAuth as a SAML Service Provider (SP), receiving a SAML Response containing an Assertion with an attribute value of `null` or of an unsupported type will result in a failure to parse the Response. If you have encountered this issue, please upgrade to `1.60.2` if possible.
* Providing an expired Id Token to the `/oauth2/logout` endpoint using the `id_token_hint` parameter results in an OAuth error.
### Security
*
FusionAuth accepts access tokens to authenticate requests and to initiate user authentication workflows.
Improvements have been made to how tokens are accepted, processed and validated to ensure they are suitable to authenticate the request. This will improve security now and will be necessary to support access tokens more extensively for authenticating requests.
*
Improvements have been made to how FusionAuth processes signed SAML assertions to mitigate an identified vulnerability. If you are using using a SAML IdP, especially when allowing IdP initiated login, please plan to upgrade at your earliest convenience.
### Changed
*
Some changes have been made to the way JWTs are produced and validated. Please read the following carefully to understand if any of these changes could impact you.
**Moved claims**
* The `gty` claim has been moved from the JWT header to the body.
* This claim is present in an access token or id token produced by an OAuth grant.
* The `use` claim has been moved from the JWT header to the body.
* This claim is present in an access token produced by an OAuth client credentials grant to authenticate a FusionAuth SCIM server.
**New and reserved claims**
The following claims are now reserved.
- `auth_time` - Reserved for all user tokens, excludes client credentials
- `gty` - Reserved for all tokens
- `tty` - Reserved for all tokens
- `use` - Reserved for the client credentials grant
We do not expect this change to impact our customers. If you are adding, removing or modifying these claims using a lambda function, you will need to plan to modify your integration.
These claims are not considered reserved for the Vend API.
**Token validation**
It is possible that an existing access token or id token that has not yet expired will no longer be considered valid by FusionAuth. If you are using a short lived access token with a refresh token, refreshing the access token will correct itself. These changes will not have any affect on your use of the JWTs produced by FusionAuth.
**Client credentials**
The `aud` claim will always be returned as an array.
Previously this claim may be returned as an string or an array depending upon the request. Here are examples of different `scope` values and their prior affect on the `aud` claim.
* `scope=target-entity:1:read` -> `aud: 1`
* `scope=target-entity:1:read target-entity:2:read` -> `aud: [1, 2]`
To simplify integration requiring an integrator to only account for a single data type this claim will now always be returned as an array. If you have only ever used a single entity in the scope parameter, it is possible your integration is not expecting an array. Please be sure to account for this change prior to upgrade.
**SCIM client integrations**
If you are using FusionAuth as a SCIM server and you have integrated with a third-party SCIM client by manually performing a client credentials grant please be aware that you will need to adjust your integration.
The preferred integration with a SCIM client is to use the client credentials grant. By using a single long lived token you have functionally created an API key that cannot be revoked.
If your SCIM clients authentication configuration does not offer a way to configure the `scope` parameter you may add this to the Token endpoint as a query string. For example the Microsoft configuration does not offer a separate `scope` field so you will need to append `?scope={scope}` to the Token endpoint where the value of `{scope}` is the scope you are using to obtain an access token.
If your SCIM client authentication only allows for a token and does not directly support the client credentials grant, we would recommend that you programatically generate and rotate the access token by using an API to ensure that you are not creating very long lived access tokens for a SCIM client.
**Deprecated features removed**
The User API JWT authentication method which was deprecated in version `1.50.0` has now been removed.
**OAuth Logout**
Now that we are identifying an `id_token` using the newly added `tty` claim, the OAuth2 Logout endpoint will now correctly reject an `access_token` when sent as the `id_token_hint` parameter according to spec. If you have any integrations that are sending an `access_token` in the `id_token_hint` parameter instead of the `id_token` you will need to correct your integration prior to upgrading.
### New
*
FusionAuth supports the OIDC _prompt_ parameter! This enables various use cases, such as silent authentication, as well requesting re-authentication and consent prompting.
Thanks to all of the community members that have helped us define this requirement, and waited patiently for it! 🎉
See [prompt](/docs/lifecycle/authenticate-users/oauth/prompt) for more information.
### Fixed
*
When decommissioning a license in a FusionAuth cluster, the change may not be reflected in all cluster nodes immediately. This can provide intermittent and inconsistent access to licensed features, depending on which node is handling a request.
*
A user can be shown a rendering error while attempting to complete an email based MFA login.
The error occurs when send rate limiting has been enabled as part of Advanced Threat Detection. When the user reached the rate limit threshold for requesting emails to be sent to complete login, the intended error was not shown an instead a page rendering error was displayed.
*
When a user completes a forgot password workflow, the failed login count will be reset.
This should reduce frustration for a user that changed their password after exceeding the configured failed login count. In this scenario, if the user had entered the the incorrect password again they would be required to wait for the configured time period before attempting login again. This could be quite frustrating.
Now that the failed count has been reset, the user will at least be allowed to enter the wrong password a few more times before we thwart their efforts. 😅
*
When running in dark mode, or using a dark theme with a FusionAuth simple theme, some QR code scanners are unable to read the QR code for setting up MFA. We have added a light border to ensure that the QR code is still readable on a dark background. The QR code should have a high-contrast border to allow these readers to work.
*
When previewing the `Phone verification required`, `Complete registration`, and `Passwordless` theme templates in an advanced theme preview window, a FreeMarker exception is displayed to the user.
This was introduced in version `1.59.0`.
*
A race condition exists, when attempting to activate FusionAuth using an air-gapped license without any outbound network access that may cause the the request to fail and not correctly persist the license.
When this issue is encountered the system becomes un-licensed.
*
When regenerating Reactor's encryption key, the _Breached Password Detection_ status may take longer than expected to return to _Active_.
If you were to encounter this issue, deactivating and reactivating your license will also correct the state. You can also reach out to support if you see something like this as well.
*
Improved MFA configuration workflow during self-service registration when configured as required.
*
In version `1.59.0`, changes were introduced that made it impossible to set webhooks for a handful of event types as transactional.
See release notes for `1.59.1` below for additional information.
### Enhancements
*
General improvements to how we handle and proces JWTs in the form of access tokens and refresh tokens.
* Adding `tty` claim to all tokens produced to easily differentiate between an access token and id token.
* Moving the `gty` claim from the header to the body for tokens produced by an OAuth grant.
* Moving the `use` claim from the header to the body for tokens produced by the client credentials grant for a SCIM server.
* Better support of the `token_type_hint` on the Introspect endpoint.
* Allow the use of refresh tokens on the Introspect endpoint with a `token_type_hint` of `refresh_token`
*
Move the `gty` and `use` claims from the JWT header to the body. This should improve interoperability with various identity providers such as AWS and Microsoft.
The `gty` claim will be present for all tokens produced by an OAuth grant. The `use` claim will be present in an access token produced to authenticate the SCIM server.
*
Significantly improved performance for the bulk User Import API.
Performance will particularly be improved when you have thousands of configured applications.
*
Our release process now auto-updates the the example JSON payload for usage data on collected metrics.
This documentation will remain up to date going forward.
The example data can be found on the [Collected Metrics](/docs/get-started/download-and-install/collected-metrics#detailed-metrics) page, look for Demo Data under the Detailed Metrics.
*
In version `1.59.0` the password is now optional when creating or updating a user.
When returning from a third-party login, a user may be prompted to complete registration by entering a password when self-service is enabled and is configured to require a password.
This was unintended and has been corrected.
*
During a password reset workflow, for a user that has MFA configured, the user will be prompted to complete the MFA challenge.
When the user completes the challenge, the remember this device checkbox even when checked may not be honored.
The result is that once the user completes the change password workflow by completing an MFA challenge, the user will be prompt again on next login. This can be frustrating, and has been corrected.
*
When performing the initial setup of FusionAuth outside of FusionAuth Cloud maintenance mode assists you with configuring the connecting to the database and search service.
When we cannot connect to the database, or you have not provided enough information to make these connections an error page is displayed.
This page has been enhanced to provide better messaging and links to documentation to help you out if you need to troubleshooting the setup process.
*
FusionAuth now supports multiple assertions in the SAML AuthN response.
If the AuthN response contains multiple assertions, all will be made available to the SAML reconcile lambda function.
*
We significantly improved performance of User API searches returning expanded user records, and user reindex actions as well!
### Internal
*
Update dependencies.
* Upgrade `io.fusionauth:fusionauth-usage-stats:fusionauth-usage-stats-common` `0.6.0` -> `0.6.1`
* Upgrade `org.primeframework:prime-mvc` `4.34.0` -> `4.35.1`
* Upgrade `io.fusionauth:fusionauth-samlv2` `0.11.1` -> `1.0.0`
### Known Issues
*
Admins control whether users must have passwords for an application by modifying the application's advanced registration form. Basic registration forms always have a password field, so a password is always required. IdP logins (such as Login with Google) create users without passwords. If the users are using an IdP to log in to an application with a required password field, the user is forced to set a password.
*
Updating the tenant will cause the following webhook events when enabled to be configured as non-transactional. This will only affect you if you have configured one or more of these event types as transactional.
- `user.identity.update`
- `user.identity.verified`
- `user.registration.create`
- `user.registration.delete`
- `user.registration.update`
- `user.registration.verified`
- `user.update`
* IdP logins do not work for Universal Apps. Instead, the error message `Invalid_Request. Missing_tenant_id` is displayed.
* Performing a user reindex occasionally results in an email, username, or phoneNumber, for a small fraction of users, to not be searchable via Elasticsearch/OpenSearch.
### Fixed
*
An upgrade to FusionAuth version `1.58.2` or `1.59.0` fails if the `Default Admin Registration provided by FusionAuth` form (shipped in `1.20.0`) is renamed or deleted prior to the upgrade.
Several changes are required to support users without passwords.
Registration verification is deprecated and will be removed in a future version of FusionAuth.
**User API**
For `/api/user` GET:
`user.verified` is now a deprecated field that only indicates whether or not the User’s primary email identity has been verified. This does NOT indicate whether phone number identity types are verified. Use `user.identities[x].verified` and `user.identities[x].verifiedReason` instead.
For `/api/user` POST:
`sendSetPasswordEmail` is deprecated. Use `sendSetPasswordIdentityType` instead.
For `/api/user/forgot-password` POST:
`sendForgotPasswordEmail` is deprecated. Use `sendForgotPasswordMessage` instead.
**User Registration API**
`sendSetPasswordEmail` is deprecated. Use `sendSetPasswordIdentityType` instead.
### Known Issues
* An upgrade to FusionAuth version `1.58.2` or `1.59.0` fails if the `Default Admin Registration provided by FusionAuth` form (shipped in `1.20.0`) is renamed or deleted prior to the upgrade. If you are planning an upgrade to version `1.59.0`, it is recommended that you upgrade to version `1.59.1`. If upgrading to `1.59.1` does not resolve this, please contact support.
* Performing a user reindex occasionally results in an email, username, or phoneNumber, for a small fraction of users, to not be searchable via Elasticsearch/OpenSearch.
*
Previewing the phone verification required, complete registration, passwordless theme templates shows a template error.
* When a Minimum Password Age is configured for the tenant, creating a user without a password results in an exception.
### Security
*
Improvements to better defend against cross-site scripting attacks.
*
A potential vulnerability was identified that could lead to unwanted access to protected resources via an injection attack. Addition protections were added to prevent this.
### Changed
*
Additional usage stats are collected for the use of grace periods with application refresh tokens, and for non-retrievable and expiring api keys.
### New
*
This release adds support for phone number as a first-class identity type. A user can now have phone number as their sole identifier, use SMS-based passwordless login, and much more. Read on for more information on related features!
*
With support for phone number as a first-class identity type, phone number can now be used as the sole identity type for a user, allowing phone-only registration.
*
FusionAuth now supports Passwordless Authentication through SMS. Previously, a user was only able to use an email address for passwordless authentication.
*
This release adds support for phone number verification.
### Fixed
*
When using a generic messenger in interactive workflows, no error is shown to the user if the message delivery attempt returns a non-200 response code. The user should be alerted to the fact that something went wrong.
*
During the slow migration of a user using a generic or LDAP connector, the known device cookie is not created. If the new device email or a new device webhook is configured, FusionAuth sends a second new device email and/or new device webhook the next time the user logs in.
*
There are cases where we are not returning appropriate errors for invalid inputs to APIs. Errors with appropriate and descriptive messages should be returned.
### Enhancements
*
When a messenger fails to deliver a message, FusionAuth now adds an event log for the error. This enhancements should help with troubleshooting message delivery issues.
*
Importing a password hash longer than 255 characters no longer fails. This limit was increased to 2048 characters.
*
Update copy for the first `Enable SMS` step. It's using the word `two` instead of `too`.
*
The `exp` claim in the FusionAuth JWT can now be modified in a JWT Populate lambda, but only to a smaller value. This means you cannot extend the default lifetime of a JWT, however you can choose to shorten it. This allows for stricter JWT expirations to be applied dynamically based on user data or other information.
Additionally, `scope` is now available to JWT Populate lambdas.
*
Passwords are now optional on users. This allows for passwordless-only and/or federated-only authentication, and simplifies the importing of users that don't currently have passwords.
### Internal
*
Update dependencies.
* Upgrade `com.inversoft:inversoft-api-authentication` `0.30.0` -> `0.30.2`
* Upgrade `com.inversoft:inversoft-config` `0.9.13` -> `0.10.0`
* Upgrade `com.inversoft:inversoft-database` `0.10.2` -> `0.10.3`
* Upgrade `com.inversoft:inversoft-license` `4.8.0` -> `4.8.1`
* Upgrade `com.inversoft:inversoft-maintenance-mode` `0.23.1` -> `0.23.3`
* Upgrade `com.inversoft:inversoft-support` `0.14.1` -> `0.14.2`
* Upgrade `jakarta.mail:jakarta.mail-api` `2.1.2` -> `2.1.3`
* Upgrade `jakarta.activation:jakarta.activation-api` `2.1.2` -> `2.1.3`
* Upgrade `org.primeframework:prime-email` `0.21.0` -> `0.21.1`
### Fixed
*
An upgrade to FusionAuth version `1.58.2` or `1.59.0` fails if the `Default Admin Registration provided by FusionAuth` form (shipped in `1.20.0`) is renamed or deleted prior to the upgrade.
### Fixed
*
The `Add Webhook` page and the `Login Records` report can show errors in some circumstances. These error conditions should be handled more gracefully.
### Known Issues
* An upgrade to FusionAuth version `1.58.2` or `1.59.0` fails if the `Default Admin Registration provided by FusionAuth` form (shipped in `1.20.0`) is renamed or deleted prior to the upgrade. If you are planning an upgrade to version `1.58.2`, it is recommended that you upgrade to version `1.58.3`. If upgrading to `1.58.3` does not resolve this, please contact support.
### Known Issues
* An upgrade to FusionAuth version `1.58.2` or `1.59.0` fails if the `Default Admin Registration provided by FusionAuth` form (shipped in `1.20.0`) is renamed or deleted prior to the upgrade. If you are planning an upgrade to version `1.58.1`, it is recommended that you upgrade to version `1.58.3`. If upgrading to `1.58.3` does not resolve this, please contact support.
### Fixed
*
A race condition was identified in the `1.58.0` release that could affect a cluster of FusionAuth instances during the upgrade, preventing the upgrade from completing. This race condition has been addressed.
### Known Issues
* After releasing FusionAuth version `1.58.0` we identified a race condition that could prevent an upgrade to version `1.58.0` from successfully completing in a clustered environment. We removed this release from distribution. If you happened to install version `1.58.0` during the brief time that it was available, it is recommended that you upgrade to version `1.58.3`.
* An upgrade to FusionAuth version `1.58.2` or `1.59.0` fails if the `Default Admin Registration provided by FusionAuth` form (shipped in `1.20.0`) is renamed or deleted prior to the upgrade. If you are planning an upgrade to version `1.58.0`, it is recommended that you upgrade to version `1.58.3`. If upgrading to `1.58.3` does not resolve this, please contact support.
### Security
*
Enhance developer feedback when rejecting unexpected multipart/* encoded requests containing files. Added additional file management configuration to allow for a per request persistence policy.
### New
*
FusionAuth now includes a [Tenant manager application](/docs/lifecycle/manage-users/tenant-manager). The Tenant Manager application is used for managing users within a single FusionAuth tenant, and you can grant access to this application to ordinary users (i.e. not FusionAuth admins). This is useful for delegating user administration to users in your, or your customers' organizations.
*
FusionAuth introduces [Universal Applications](/docs/get-started/core-concepts/applications#universal-applications)! Formerly, in FusionAuth an application belonged to one and only one tenant. This can be cumbersome when you want to expose your application in many tenants, as you need to create an application record in each tenant. With universal applications, a single application entry in FusionAuth can be used in all tenants.
### Fixed
*
Searching for entities using the [Entity Search API](http://localhost:3000/docs/apis/entities/entities#search-for-entities) can produce results that have duplicate or missing items on response pages when a sort field isn't specified. Results should have an implicit ordering when no sort field is specified.
*
In certain circumstances, the FusionAuth admin UI and self-service account applications can fail to refresh an expired access token, causing a user to be logged out.
*
Calling the [Search Reindex API](/docs/apis/system#rebuild-the-elasticsearch-index) while a reindex is in progress yields a 500 error. This API now returns a 400 status if a reindex operation is already running.
*
Using PATCH calls from HTTPConnect in a lambda fails in some cases. PATCH should be generally supported.
*
Interacting with a date picker can generate errors in the broswer's console. FusionAuth should handle these errors more gracefully.
*
A few forms in the FusionAuth admin UI are setting the input focus in nonstandard ways. These include the setup wizard, the add API key view, and the edit API key view.
*
### Enhancements
*
FusionAuth was not handling a malformed Set-Cookie response header from another identity provider gracefully. The parsing done by FusionAuth was updated to handle this scenario better.
### Fixed
*
In version `1.56.0`, a bug was introduced that caused FusionAuth to fail to start after being installed using RPM and Debian packages.
The following only applies if you have manually installed fusionauth using the RPM or Debian packages. When upgrading from releases prior to `1.57.1`, you must ensure that both the `fusionauth-app` and `fusionauth-search` services are stopped. This is typically done by running the following command:
```bash
sudo systemctl stop fusionauth-app fusionauth-search
```
The upgrade will run a `usermod` command to modify the `fusionauth` user account so both processes must be stopped in order for the upgrade to succeed.
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 `
` in the macro named `alternativeLogins` in `helpers` and add `id="login-button-container"` and `data-federated-csrf="${federatedCSRFToken}"` attributes.
```html
[#-- Updated div in alternativeLogins macro. Line breaks added for readability. --]
```
### Fixed
* Ensure a signed AuthN request always has the `Signature` element as the next sibling after the `Issuer` element. This bug may cause some SAML v2 services provides to reject the signature of an AuthN request sent from FusionAuth.
* Resolves [GitHub Issue #2348](https://github.com/FusionAuth/fusionauth-issues/issues/2348)
* Upgrade our phone number validation to include the Kosovo country code of `+383`. This upgrade will add support for various other country codes as well. See linked GitHub issue for more detail.
* Resolves [GitHub Issue #2355](https://github.com/FusionAuth/fusionauth-issues/issues/2355)
* Defend against corporate link "checkers" such as Outlook Safe Links and Google Workspace during the Change Password email workflow. This fix resolves a specific symptom that may occur when a link sent to a user during a change password workflow and the user has multi-factor authentication enabled. The symptom the end user may encounter is that multiple codes may be sent to the user during this workflow. When the two-factor method is email, multiple emails may be received, and when two-factor method is SMS, multiple SMS messages may be received. The cause of this symptom is that the link is being inspected by an intermediate party prior to the user's browser loading the link which functionally means the request is made more than once.
* Resolves [GitHub Issue #2360](https://github.com/FusionAuth/fusionauth-issues/issues/2360)
* Improve locale validation, and restrict the number of preferred languages per user to 20. This should not have any practical impact on users of FusionAuth, but it will better protect FusionAuth from storing erroneous values for the user's preferred languages. If you have users that speak more than 20 languages, you will need to ask them to pick their top 20 favorites. 😎
* Resolves [GitHub Issue #2363](https://github.com/FusionAuth/fusionauth-issues/issues/2363)
* Improve username validation. This length limitation was already enforced by the schema, but the error message was not developer friendly. This change will add a proper validation error in the API response.
* Resolves [GitHub Issue #2368](https://github.com/FusionAuth/fusionauth-issues/issues/2368)
* Update the Tenant view dialog in the admin UI to reflect the changes made to the `/.well-known/openid-configuration` endpoint in version `1.46.0`. This is a cosmetic change only, and does not include any functional fixes.
* Resolves [GitHub Issue #2333](https://github.com/FusionAuth/fusionauth-issues/issues/2333)
* Fix Tenant select control on Group index page in the admin UI when only a single tenant is configured. This is just a cosmetic fix to how the form was being rendered.
* Resolves [GitHub Issue #2338](https://github.com/FusionAuth/fusionauth-issues/issues/2338)
* Reduce Kafka logging. So noisy.
* Resolves [GitHub Issue #2359](https://github.com/FusionAuth/fusionauth-issues/issues/2359)
* Protect the Kafka event sender from sending events related to it's own failure. This protects us from overloading the Kafka topic.
* Resolves [GitHub Issue #2362](https://github.com/FusionAuth/fusionauth-issues/issues/2362)
* Fix the `user.registration.update.complete` event to include the updates roles if applicable.
* Resolves [GitHub Issue #1898](https://github.com/FusionAuth/fusionauth-issues/issues/1898), thanks to [@sjswami](https://github.com/sjswami) for reporting the issue!
* Better defense against a truncated `oauth_context` request parameter. This parameter is passed around during various OAuth2 workflows to maintain context. This changes allows FusionAuth to fail more gracefully if this is value is intentionally or un-intentionally modified by a 3rd party.
* Resolves [GitHub Issue #2382](https://github.com/FusionAuth/fusionauth-issues/issues/2382)
* `username` and `fullName` fields can be queried using the `.exact` suffix on these fields which does an exact match.
* Resolves [GitHub Issue #602](https://github.com/FusionAuth/fusionauth-issues/issues/602) Thanks to [@patrickvalle](https://github.com/patrickvalle) for reporting this!
### Enhancements
* Add `user.preferredLanguages` to the basic self-service registration to allow a user's preferred language to be collected and then utilized to send localized emails without using advanced self-service registration.
* Resolves [GitHub Issue #1738](https://github.com/FusionAuth/fusionauth-issues/issues/1738), thanks to [@glen-84](https://github.com/glen-84) and [@geoalexidis](https://github.com/geoalexidis) for their input and patience while we delivered this enhancement.
* Improve handling of cache reload requests under heavy load. This should improve system performance at scale when mass creating or deleting of various items such as applications and keys.
* Resolves [GitHub Issue #2318](https://github.com/FusionAuth/fusionauth-issues/issues/2318)
* Add timers and metrics around lambda invocations and the use of HTTP Connect within a lambda function. This should help customers tune and manage lambdas by providing additional insight into the total execution time.
* Resolves [GitHub Issue #2389](https://github.com/FusionAuth/fusionauth-issues/issues/2389)
* Add configuration to accept any named parameter as a login hint coming from the SAML v2 SP when FusionAuth is acting as the SAML v2 IdP. Prior to this change, FusionAuth would accept `login_hint` if provided on the request. However, this value can not be configured or optionally disabled.
* Resolves [GitHub Issue #2222](https://github.com/FusionAuth/fusionauth-issues/issues/2222)
* Add `identityProviderName` to the IdP Link API response.
* Resolves [GitHub Issue #2337](https://github.com/FusionAuth/fusionauth-issues/issues/2337)
### New
* Support SAML v2 assertion encryption when FusionAuth is acting as the SAML v2 IdP. This means FusionAuth is now compatible with a SAML v2 SP that requires encrypted assertions.
* Resolves [GitHub Issue #1741](https://github.com/FusionAuth/fusionauth-issues/issues/1741), thanks [@annismckenzie](https://github.com/annismckenzie) for the request! This is a great addition to FusionAuth.
### Internal
* Add aggregate HTTP request timers and metrics that can be retrieved by the Status API and Prometheus Metrics API.
* Resolves [GitHub Issue #2369](https://github.com/FusionAuth/fusionauth-issues/issues/2369)
* Update dependencies.
* Resolves [GitHub Issue #2344](https://github.com/FusionAuth/fusionauth-issues/issues/2344)
* Resolves [GitHub Issue #2384](https://github.com/FusionAuth/fusionauth-issues/issues/2384)
* Enable GC (garbage collection) logging. A new log named `fusionauth-app.gc.log` will be found in the log directory.
* Resolves [GitHub Issue #2388](https://github.com/FusionAuth/fusionauth-issues/issues/2388)
* Improve performance and overhead when downloading and storing the IP location database required for resolving location meta-data for logins by IP address.
* Resolves [GitHub Issue #2195](https://github.com/FusionAuth/fusionauth-issues/issues/2195)
### Security
* An edge case exists where the CAPTCHA may be bypassed when using Advanced Registration forms.
* Resolves [GitHub Issue #2221](https://github.com/FusionAuth/fusionauth-issues/issues/2221)
* Perform additional validation on the `user_code` when completing a Device Grant by way of the Authorization Code Grant, Implicit Grant, or Password Credentials Grant.
* Resolves [GitHub Issue #2228](https://github.com/FusionAuth/fusionauth-issues/issues/2228)
* Perform additional defensive validation on self-service edit form.
* Resolves [GitHub Issue #2234](https://github.com/FusionAuth/fusionauth-issues/issues/2234)
* Mitigate a potential directory traversal attack. CloudFlare, AWS and similar cloud providers will generally block these requests by default.
* Please note, FusionAuth Cloud customers are not vulnerable to this type of attack.
* Resolves [GitHub Issue #2299](https://github.com/FusionAuth/fusionauth-issues/issues/2299)
### Fixed
* Always send email verification on user email change when configured for user self-service
* Resolves [GitHub Issue #2210](https://github.com/FusionAuth/fusionauth-issues/issues/2210)
* Resolve a JavaScript bug when enabling MFA during login. The bug caused an error to be written to the JavaScript console, but no functional errors occurred.
* Resolves [GitHub Issue #2296](https://github.com/FusionAuth/fusionauth-issues/issues/2296)
* When the `user.login.success` is configured to be transactional and the webhook returns a non `200` status code when the event is fired during the final step of the change password workflow, the failed webhook may not fail the login attempt.
* Resolves [GitHub Issue #2288](https://github.com/FusionAuth/fusionauth-issues/issues/2288)
* When enabling IdP initiated login on a SAMLv2 IdP, the base ACS URL is hidden in the view dialog
* Resolves [GitHub Issue #2146](https://github.com/FusionAuth/fusionauth-issues/issues/2146)
* When an `applicationId` is provided on a Two Factor Start or Send APIs, the application variable may not available in the email template.
* Resolves [GitHub Issue #2149](https://github.com/FusionAuth/fusionauth-issues/issues/2149)
* APIs that optionally take a `sourceId` to indicate you wish to copy will now fail validation if you provide additional parameters in the body that will otherwise be ignored.
* Resolves [GitHub Issue #2004](https://github.com/FusionAuth/fusionauth-issues/issues/2004), thanks to [@Pycnomerus](https://github.com/Pycnomerus) for the suggestion!
* When adding a user to multiple Groups using the `/api/group/member` API, the request may fail.
* Resolves [GitHub Issue #2197](https://github.com/FusionAuth/fusionauth-issues/issues/2197)
* When using a wildcard for authorized origin URL, you may receive an invalid origin error.
* Resolves [GitHub Issue #2227](https://github.com/FusionAuth/fusionauth-issues/issues/2227), thanks to [@beezerk23](https://github.com/beezerk23) for letting us know!
* The memory value for `fusionauth-app.memory` set in the `fusionauth.properties` file may not be set correctly.
* Resolves [GitHub Issue #2284](https://github.com/FusionAuth/fusionauth-issues/issues/2284)
* When using custom data with nested values such as `user.data.company.name` and `user.data.company.id` in an Advanced Registration form the nested values may not be properly persisted.
* Resolves [GitHub Issue #2239](https://github.com/FusionAuth/fusionauth-issues/issues/2239)
* When using the admin UI to update an IdP with >6k applications the request may cause a database error.
* Resolves [GitHub Issue #2262](https://github.com/FusionAuth/fusionauth-issues/issues/2262)
* Add index `entity_user_grants` to increase `SELECT` performance
* Resolves [GitHub Issue #2245](https://github.com/FusionAuth/fusionauth-issues/issues/2245)
* When using the `validateJWT` method in the FusionAuth Java REST Client, the `exp` or `iat` claims may have the incorrect precision.
* Resolves [GitHub Issue #2275](https://github.com/FusionAuth/fusionauth-issues/issues/2275)
* OpenAPI spec missing some endpoints
* Resolves [GitHub Issue #2247](https://github.com/FusionAuth/fusionauth-issues/issues/2247)
* A change in behavior was introduced in version `1.41.0` that may cause an error when accessing FusionAuth in Docker. The change was how the `Host` header was being parsed to pick up the local port.
* Resolves [GitHub Issue #2250](https://github.com/FusionAuth/fusionauth-issues/issues/2250), thanks to [@MarekUniq](https://github.com/MarekUniq) for his report, persistence and [contribution](https://github.com/FusionAuth/java-http/pull/9) to [java-http](https://github.com/FusionAuth/java-http)!
* The `user.create.complete` and `user.registration.create.complete` events may be sent before the transaction has closed during IdP Login.
* Resolves [GitHub Issue #2233](https://github.com/FusionAuth/fusionauth-issues/issues/2233)
* Correct the internal authentication to receive an internal webhook between FusionAuth service nodes. If you encounter this error, you may see errors in the event log that mention `returned response code [401] when sending [JWTRefreshTokenRevoke] event`. This error was introduced in version `1.37.0` and the error only occurs when you have more than one FusionAuth service node.
* Resolves [GitHub Issue #2257](https://github.com/FusionAuth/fusionauth-issues/issues/2257)
* When you have enabled Implicit Email Verification, when completing a Multi-Factor login, a `user.email.verified` event may be sent even if the user has already verified their email address.
* Resolves [GitHub Issue #2258](https://github.com/FusionAuth/fusionauth-issues/issues/2258)
* When the `user.reactivate` event is configured to be transactional and the webhook returns a non `200` status code, the transaction may not be correctly rolled back.
* Resolves [GitHub Issue #2281](https://github.com/FusionAuth/fusionauth-issues/issues/2281)
* When making a request to the self-service pages, such as `/account/` ensure any additional query parameters are preserved through a login workflow.
* Resolves [GitHub Issue #2282](https://github.com/FusionAuth/fusionauth-issues/issues/2282)
* When the `user.create` event is configured to be transactional, ensure the Setup Password email is not sent if a `user.create` webhook returns a non `200` status code.
* Resolves [GitHub Issue #2287](https://github.com/FusionAuth/fusionauth-issues/issues/2287)
* When using the Device Grant with the `/oauth2/device` themed page, you may be shown a Logout button if an SSO session exists during this workflow. Clicking this button will log the user out of the SSO session and return to this page. This fixes the logout link so that you do not receive an error when returning to the `/oauth2/device` page. A workaround is documented in the linked GitHub issue.
* Resolves [GitHub Issue #2331](https://github.com/FusionAuth/fusionauth-issues/issues/2331)
### Enhancements
* The OAuth2 Introspect endpoint now optionally takes a `client_secret`.
* Resolves [GitHub Issue #1100](https://github.com/FusionAuth/fusionauth-issues/issues/1100)
* A token obtained from the Client Credentials Grant may now be used with the OAuth2 Introspect endpoint.
* Resolves [GitHub Issue #1434](https://github.com/FusionAuth/fusionauth-issues/issues/1434)
* An additional JWT Expiration Policy is now available to configure a sliding window with a maximum lifetime.
* Resolves [GitHub Issue #1729](https://github.com/FusionAuth/fusionauth-issues/issues/1729)
* The OpenID Connect discovery endpoint will now accept the `tenantId` as a URL segment. This should make it easier to integrate with providers that would not otherwise allow a query parameter on this URL to specify the `tenantId`.
* Resolves [GitHub Issue #2259](https://github.com/FusionAuth/fusionauth-issues/issues/2259)
* Provide a validation error when using the `/api/jwt/reconcile` API with any IdP type `ExternalJWT`.
* Resolves [GitHub Issue #2074](https://github.com/FusionAuth/fusionauth-issues/issues/2074)
* Add configuration to allow unauthenticated access to `/api/status` and `/api/prometheus/metrics` APIs from localhost.
* Resolves [GitHub Issue #2310](https://github.com/FusionAuth/fusionauth-issues/issues/2310)
* Add additional support in the default theme to use Google reCAPTCHA v2 in an invisible mode w/ CAPTCHA fallback.
* Resolves [GitHub Issue #2237](https://github.com/FusionAuth/fusionauth-issues/issues/2237)
* Allow any string value in the `metaData.device.type` property on various APIs.
### New
* Allow Device Grant to be completed out of band.
* New API `/oauth2/device/approve`
* New API `/oauth2/device/user-code`
* Resolves [GitHub Issue #2218](https://github.com/FusionAuth/fusionauth-issues/issues/2218)
* New API to retrieve a pending IdP link.
* New API `/api/identity-provider/link/pending`
* Resolves [GitHub Issue #2218](https://github.com/FusionAuth/fusionauth-issues/issues/2218)
### Internal
* Upgrade Apache FreeMarker from version `2.3.30` to `2.3.32`.
* Resolves [GitHub Issue #2214](https://github.com/FusionAuth/fusionauth-issues/issues/2214)
* Upgrade FusionAuth Java HTTP dependency from version `0.1.13` to `0.1.14`.
* Resolves [GitHub Issue #2299](https://github.com/FusionAuth/fusionauth-issues/issues/2299)
* Upgrade Prime MVC dependency from version `4.7.1` to `4.9.10`.
* Resolves [GitHub Issue #2299](https://github.com/FusionAuth/fusionauth-issues/issues/2299)
### Fixed
* Ensure we correctly handle a truncated or malformed `oauth_context` request parameter when using the hosted login pages.
* Resolves [GitHub Issue #2382](https://github.com/FusionAuth/fusionauth-issues/issues/2382)
### Fixed
* Update `fusionauth/java-http` to the most recent version to pick up a bug fix.
This fixes a very low level HTTP server bug. In some rare cases, the HTTP response handler may not identify the end of the stream and effectively truncate the response body. It is difficult to say how may affect your integration if you were to encounter it. If you were to make an API call with a large response body, it may be possible the response would not include a valid JSON object if the response is truncated. When this error occurs, the HTTP status code will be valid, but the response will be truncated or non-existent.
For additional detail see the linked commit in the linked GitHub issue.
* Resolves [GitHub Issue #2292](https://github.com/FusionAuth/fusionauth-issues/issues/2292)
### Fixed
* If you have configured an access token signing key specific to an entity type, the signing key configuration may revert to the tenant configuration after upgrading to this version.
It is recommended to upgrade to this version at a minimum if you are coming from a version prior to version `1.45.0`.
* For more information on this issue, see the Known Issues in the `1.45.0` release notes.
* Resolves [GitHub Issue #2249](https://github.com/FusionAuth/fusionauth-issues/issues/2249)
### Changed
* Add additional validation when adding authorized origin to the OAuth2 configuration to ensure the values do not include a path or query string. This change will only affect validation when adding or editing the application configuration. This change will not affect existing configured origins or their use at runtime.
* Resolves [GitHub Issue #2185](https://github.com/FusionAuth/fusionauth-issues/issues/2185)
### Fixed
* Support for wildcard configuration when using `post_logout_redirect_uri` parameter on the OAuth2 Logout request.
* Resolves [GitHub Issue #2164](https://github.com/FusionAuth/fusionauth-issues/issues/2164)
* Fix salt validation for the `phpass-md5` or `phpass-sha512`. This will allow the import of users with this password hash when the salt includes a `.` (period) character.
* Resolves [GitHub Issue #2206](https://github.com/FusionAuth/fusionauth-issues/issues/2206)
### Known Issues
* When importing users using the `phpass-md5` or `phpass-sha512` schemes shipped in this release, if the salt contains a period (`.`) the import will fail validation.
* Resolved in version `1.45.1` via [GitHub Issue #2206](https://github.com/FusionAuth/fusionauth-issues/issues/2206)
* If you have configured an access token signing key specific to an entity type, the signing key configuration may revert to the tenant configuration after upgrading to this version.
If you wish to upgrade before a fix is available, please document your access token signing key configuration for each entity type that has provided a specific signing configuration. Then, once the upgrade has completed, review each entity type and confirm the correct signing key configuration. If the configuration is not correct, set the signing key to the previously documented signing key.
To verify if this issue may affect you during upgrade, confirm your signing configuration for each configured entity type.
* Navigate to Entity Management -> Entity Types -> Edit -> JWT.
* If you have not enabled Entity Type specific JWT signing, this section will be collapsed and this entity type will not be affected during upgrade. If the signing configuration is enabled and you have configured a key for the `Access token signing key` field, you may be affected. Please record this setting and ensure it has not changed after the upgrade has completed.
If you have not yet upgraded to version `1.45.0`, it is recommended to move to version `1.45.2` or later at a minimum and skip this version if you have confirmed you may be affected by this issue.
* Resolved in `1.45.2` via [GitHub Issue #2249](https://github.com/FusionAuth/fusionauth-issues/issues/2249)
### Security
* Update usage of `verificationId` on gated email or registration verification pages when configured to use a clickable link instead of a short code.
* Resolves [GitHub Issue #2182](https://github.com/FusionAuth/fusionauth-issues/issues/2182)
* Update 3rd party dependencies to remove CVE scan warnings. No known exploits are vulnerabilities exist in FusionAuth as the result of using these 3rd party clients. These upgrades are simply a precautionary measure to stay current.
* Upgrade Elasticsearch client from version `7.10.2` to `7.13.4`.
* Upgrade GraalJS from version `22.3.0` to `22.3.1`.
* Resolves [GitHub Issue #2183](https://github.com/FusionAuth/fusionauth-issues/issues/2183)
### Fixed
* Validate the length of an entity name in order to provide a more friendly validation error message.
* Resolves [GitHub Issue #2089](https://github.com/FusionAuth/fusionauth-issues/issues/2089)
* Updates to the OpenAPI spec to correct an error related to `BaseSAMLv2IdentityProvider`.
* Resolves [GitHub Issue #2103](https://github.com/FusionAuth/fusionauth-issues/issues/2103)
* Review and correct tooltips in the admin UI for Application specific email templates.
* Resolves [GitHub Issue #2163](https://github.com/FusionAuth/fusionauth-issues/issues/2163)
### Enhancements
* De-couple the self-service themed account pages from SSO. You may now use the self-service account pages even if you choose not to preserve your SSO session. For example, you can un-check the "Keep me signed in" checkbox and still use the self-service pages.
Also allow the self-service account session to be bootstrapped from a mobile application using token authentication, also known as the `Bearer` authentication scheme. This mechanism provides access to the self-service themed pages even if you are unable to share cookies with the web view used to complete login.
Example request header: `Authorization: Bearer `
* Resolves [GitHub Issue #1546](https://github.com/FusionAuth/fusionauth-issues/issues/1546), thanks to [@ansonallard](https://github.com/ansonallard) for the suggestion!
* Resolves [GitHub Issue #1860](https://github.com/FusionAuth/fusionauth-issues/issues/1860)
### New
* Add a policy to require a user to provide their current password when changing a password on the self-service account pages. See Applications -> Edit -> Registration -> Form settings -> Require current password.
* Resolves [GitHub Issue #1578](https://github.com/FusionAuth/fusionauth-issues/issues/1578)
* Integrate the Authorization Code grant workflow into FusionAuth for use with single page web applications. This feature may be used with the FusionAuth React or Angular SDKs to support the use of the Authorization Code grant without having to write any backend code.
And there was much rejoicing. 😅
* Resolves [GitHub Issue #1943](https://github.com/FusionAuth/fusionauth-issues/issues/1943)
* New Search APIs. These new APIs provide search and pagination capability across more APIs and may increase performance when using the FusionAuth admin UI with larger numbers of Tenants and Applications.
Applications, Consents, Groups, Tenants, Themes, Keys, API keys, User Comments, Email Templates, Identity Providers, Webhooks, and Lambdas. (🦁 🐯 🐻 ... oh my!)
* Resolves [GitHub Issue #2055](https://github.com/FusionAuth/fusionauth-issues/issues/2055)
* Resolves [GitHub Issue #2056](https://github.com/FusionAuth/fusionauth-issues/issues/2056)
* Resolves [GitHub Issue #2057](https://github.com/FusionAuth/fusionauth-issues/issues/2057)
* Resolves [GitHub Issue #2058](https://github.com/FusionAuth/fusionauth-issues/issues/2058)
* Resolves [GitHub Issue #2059](https://github.com/FusionAuth/fusionauth-issues/issues/2059)
* Resolves [GitHub Issue #2060](https://github.com/FusionAuth/fusionauth-issues/issues/2060)
* Resolves [GitHub Issue #2061](https://github.com/FusionAuth/fusionauth-issues/issues/2061)
* Resolves [GitHub Issue #2064](https://github.com/FusionAuth/fusionauth-issues/issues/2064)
* Resolves [GitHub Issue #2065](https://github.com/FusionAuth/fusionauth-issues/issues/2065)
* Resolves [GitHub Issue #2066](https://github.com/FusionAuth/fusionauth-issues/issues/2066)
* Resolves [GitHub Issue #2067](https://github.com/FusionAuth/fusionauth-issues/issues/2067)
* Resolves [GitHub Issue #2068](https://github.com/FusionAuth/fusionauth-issues/issues/2068)
* Add support for Drupal MD5, SHA-512 hashes for easier import
* New schemes include `phpass-md5` and `phppass-sha512`.
* See [phpass MD5](/docs/reference/password-hashes#phpass-md5) and [phpass SHA-512](/docs/reference/password-hashes#phpass-md5) for additional details.
* Resolves [GitHub Issue #2165](https://github.com/FusionAuth/fusionauth-issues/issues/2165)
### Internal
* Fix JSON exclusions for ignoring foreign keys.
* Resolves [GitHub Issue #2198](https://github.com/FusionAuth/fusionauth-issues/issues/2198)
*Additional details* \
This migration will add an index to the `identity_provider_links` table. It is not expected to negatively impact the migration time during upgrade, but please be aware that deployments with millions of Identity Provider Links may experience additional processing time during the migration.]
### Fixed
* A Lambda invocation may incorrectly fail indicating a recursive call was attempted. This is unlikely to occur, but under heavy load, it is possible.
* Resolves [GitHub Issue #2102](https://github.com/FusionAuth/fusionauth-issues/issues/2102)
* The Application API was failing to make a copy when using `sourceApplicationId` when the source Application has enabled and configured the SAML v2 IdP. This is a bug in a new feature that was added in version `1.43.0`.
* Resolves [GitHub Issue #2118](https://github.com/FusionAuth/fusionauth-issues/issues/2118)
### Enhancements
* Add default configuration for read and connect timeouts to the SMTP server configuration. This helps protect FusionAuth against an SMTP server that never closes a socket. From time to time we observed an SMTP server hold open a socket, and tie up a send thread which may block other senders. This includes the `mail.smtp.timeout` and `mail.smtp.connectiontimeout` settings. The default value is `2000` for each. These may be overridden by navigating to the `Advanced` tab in your tenant and adding them to the `SMTP settings` section.
* Resolves [GitHub Issue #1742](https://github.com/FusionAuth/fusionauth-issues/issues/1742)
* Change Link API request body to match the response. Backwards compatibility is maintained, but this provides a more consistent API feel.
* Resolves [GitHub Issue #1747](https://github.com/FusionAuth/fusionauth-issues/issues/1747)
* Update the Google IdP JavaScript in the themed pages. This change removes the deprecated Google JavaScript library, and adds support for One Tap.
* Resolves [GitHub Issue #1939](https://github.com/FusionAuth/fusionauth-issues/issues/1939), thanks to [@Brunom50](https://github.com/Brunom50), [@harishreddy-m](https://github.com/harishreddy-m), [@forteilgmbh](https://github.com/forteilgmbh) for their contribution.
* Return a `404` with status only for anything under `/api/*` instead of rendering a `404` page with HTML. It just seems like the right thing to do. Nobody wants HTML in their APIs!
* Resolves [GitHub Issue #2109](https://github.com/FusionAuth/fusionauth-issues/issues/2109)
* Add a new index to the `identity_provider_links` table to increase performance. Better. Faster. Stronger.
* Resolves [GitHub Issue #2122](https://github.com/FusionAuth/fusionauth-issues/issues/2122)
{/* // */}
* Add `apiMode: [Public|Partner]` to allow the user to select between the public or partner Steam API. The Partner API is preferred if you have access to it because it is not rate limited.
* Resolves [GitHub Issue #2127](https://github.com/FusionAuth/fusionauth-issues/issues/2127)
{/* // */}
### Internal
* Use `Cache-Control: no-store` more broadly in the FusionAuth admin application.
* Resolves [GitHub Issue #2097](https://github.com/FusionAuth/fusionauth-issues/issues/2097)
# Data Types
import WebauthnSupportedAlgorithms from 'src/content/docs/reference/_webauthn-supported-algorithms.mdx';
import URI from 'src/components/URI.astro';
## COSE Algorithm Identifiers
The WebAuthn specification uses COSE Algorithm Identifiers to specify which signing algorithms are allowed for new WebAuthn passkeys during registration and also the signing algorithm that a given passkey is using. These identifier values are defined by the [IANA COSE Algorithms registry](https://www.iana.org/assignments/cose/cose.xhtml). FusionAuth supports a subset of these algorithms.
## Instants
FusionAuth stores all time references as the number of milliseconds since the [unix epoch](#unix-epoch). This is is the same as [unix time](#unix-time) except the precision is milliseconds instead of seconds.
For example, consider the following date.
> 10:45 AM MST on July 4th, 2015
In order to send this value to FusionAuth, you would need to convert this date time to the number of milliseconds since the [unix epoch](#unix-epoch) which is `1436028300000` and then send this value as an input parameter. [Convert instants to human readable dates or vice versa.](/dev-tools/date-time)
When you retrieve these same values from FusionAuth you may then easily convert the value to any date and time format you wish with as much or little precision as you wish. For example, you may display only the day, month and year to the user, or include hours and minutes, but excludes the seconds. Because everything we store is in UTC - converting this value to a local time zone is easy and there is no guess work.
## Locales
FusionAuth accepts and returns Locales on the API using the Java standard format of a ISO 639-1 two letter language code followed by an optional underscore and a ISO 3166-1 alpha-2 country code. Below is a table of common language and country codes and the resulting locale string that can either be sent into an API or be expected on the API response. This is not an exhaustive list but only provided as an example.
_Locale Codes_
| Language | Country | Locale
| ---| ---| --- |
| Arabic | – | `ar`
| Danish | – | `da`
| German | – | `de`
| English | – | `en`
| Spanish | – | `es`
| Spanish | Mexico | `es_MX`
| Finish | – | `fi`
| French | – | `fr`
| Italian | – | `it`
| Japanese | – | `ja`
| Korean | – | `ko`
| Dutch | – | `nl`
| Norwegian | – | `no`
| Polish | – | `pl`
| Portuguese| – | `pt`
| Russian | – | `ru`
| Swedish | – | `sv`
| Chinese | Taiwan | `zh_TW`
| Chinese | China | `zh_CN`
## Time Zone
FusionAuth accepts time zones in an [IANA](https://www.iana.org/time-zones) time zone format.
For example, the following values are all valid time zone formats.
* `America/Chicago`
* `America/Denver`
* `America/New_York`
* `Asia/Tel_Aviv`
* `Asia/Tokyo`
* `Europe/Amsterdam`
* `Europe/Belfast`
* `Europe/Kiev`
* `Europe/Paris`
* `Pacific/Tahiti`
* `US/Central`
* `US/Pacific`
* `US/Mountain`
* `US/Eastern`
* `UTC-7`
* `UTC+2`
## UUIDs
Data types specified as UUID are expected to be in a valid string representation of a universally unique identifier (UUID). The API specifically expects the UUID to be provided in its canonical form which is represented by 32 lowercase hexadecimal digits displayed in five groups separated by hyphens.
This representation takes the form of 8-4-4-4-12 for a total of 36 characters, 32 hexadecimal characters and four hyphens. In case you are converting an array of bytes, the break down of bytes for the hexadecimal String is 4-2-2-2-6. UUIDs are version 4.
Here's an example of a UUID in the expected canonical string format in a JSON request or response body.
```json
{
"foo": {
"id": "965865ef-b17d-4153-b952-d8902e584f7d"
}
}
```
Here's an example of a UUID being provided as a URL segment for an API.
```
/api/user/965865ef-b17d-4153-b952-d8902e584f7d
```
Now that you're all excited about UUIDs, do you want to generate you own? Go ahead, we won't tell anyone - check out our ad-free [Online UUID generator](/dev-tools/uuid-generator).
## Unix time
Unix time is the number of seconds since the [unix epoch](#unix-epoch).
You'll mostly find unix time used in token claims because that is what the specification requires.
### Unix epoch
An epoch is simply a fixed point in time used as reference point from which we can measure things. The unix epoch is `1 January 1970 00:00:00 UTC`.
You can pronounce epoch however you wish, we're not the boss of you, but common pronunciations include ee-pok as well as eh-pock.
# 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
# Indexed Entity Fields
import IndexedEntityFieldsList from 'src/content/docs/reference/_indexed-entity-fields-list.astro';
If you are using the Elasticsearch engine, you can [search for entities](/docs/apis/entities/entities#search-for-entities) by the following attributes.
# GDPR Compliance in FusionAuth
## GDPR Compliance in FusionAuth
FusionAuth is designed with GDPR compliance in mind, incorporating essential features to protect user data and privacy. This guide outlines the key aspects of FusionAuth's GDPR compliance and how it helps your application meet regulatory requirements.
## Core Compliance Features
FusionAuth offers several built-in features that support GDPR compliance:
### Data Protection
FusionAuth employs strict server security, firewalls, and encryption to protect hosted customer data1.
### Data Isolation
As a single-tenant solution, FusionAuth ensures:
- User data is not co-mingled with other companies
- Data can be hosted in specific countries as required
- Data Retrieval and Deletion
FusionAuth provides APIs for:
- Collecting all stored user data, including custom data
- Deleting all user data, including behavioral data like IP addresses and login timestamps
With the appropriate license, FusionAuth provides a user accessible UI for collecting and modifying all stored user data, including custom data.
### User Data Pseudonymization
FusionAuth uses opaque tokens and complex user IDs to pseudonymize user data, making it difficult to match IDs to user data without database access.
### Password Security
FusionAuth includes:
- Customizable password rules to ensure compliance with NIST regulations
- Configurable password hashing algorithms, including BYO algorithm
- Ability to upgrade hashing algorithms during user login
### Breach Notification
FusionAuth maintains a strict breach notification policy, aiming to notify customers of any breach or suspected breach within 24 hours.
## Implementation Benefits
By using FusionAuth, developers can focus on their application's core functionality while ensuring GDPR compliance for user management. FusionAuth's security-first approach and continuous updates to best practices provide a robust and flexible solution for modern authentication and access management1.
## Further Resources
For more information on GDPR compliance and its impact on development, refer to the FusionAuth [Developer's Guide to the GDPR](/learn/expert-advice/ciam/developers-guide-to-gdpr). This resource covers essential information for maintaining compliance and avoiding potential fines under the regulation.
# Required Network Hostname Access
import HostsToAllowNetworkAccessFor from 'src/content/docs/_shared/_hosts-to-allow-network-access.mdx';
If you have a FusionAuth instance with a license, you must allow access to the following hostnames.
Learn more about [network requirements](/docs/get-started/download-and-install/system-requirements#network-access) for running FusionAuth.
# Password Hashing Algorithms
import Aside from 'src/components/Aside.astro';
## Overview
FusionAuth provides several options for password hashing schemes.
An ideal password hashing algorithm should be slow. When hashing is fast and password entropy is low, brute force attacks become a high risk. Even with enforced password policies, low password entropy can be difficult to mitigate. Choosing a slow algorithm is actually preferred for password hashing. Of the hashing schemes provided, only `PBKDF2` and `Bcrypt` are designed to be slow which makes them the best choice for password hashing, `MD5` and `SHA-256` were designed to be fast and as such this makes them a less than ideal choice.
When selecting a load factor for the hashing scheme, the minimum values are provided for a starting guideline only. The factor should be set as high as possible such that the login times are still acceptable to your end users. Be cautious with setting the factor too high, especially with `Bcrypt`, setting the factor too high may cause login requests to take seconds or minutes to complete.
## phpass MD5
This is the [phpass](https://www.openwall.com/phpass/) (pronounced "pH pass") MD5 algorithm commonly used by PHP applications. This is weak hash that has been shown to be compromised and is vulnerable to brute force attacks. This hash is provided for migration purposes and it should be upgraded to a stronger hash as soon as possible.
The following is the string value used by the FusionAuth API to request this algorithm.
* `phpass-md5`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
result = md5(join(bytes(salt), bytes(password)))
count = 0
while count < factor {
count = count + 1
temp = join(result, bytes(password))
result = md5(temp)
}
// encode and return the first 16 bytes of the result
result = result[:16]
return String(base64Encode(result))
}
```
## phpass SHA-512
This is the [phpass](https://www.openwall.com/phpass/) (pronounced "pH pass") SHA-512 algorithm commonly used by PHP applications. SHA-512 is part of the SHA-2 set of cryptographic standards. SHA-512 is a general purpose hash and similar to MD5 it was designed to be fast which makes it a less than ideal choice for a password hashing. This hash is mainly provided for migration purposes or where login performance is very critical. If login performance has not become an issue a stronger scheme should be utilized.
The following is the string value used by the FusionAuth API to request this algorithm.
* `phppass-sha512`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
result = sha512(join(bytes(salt), bytes(password)))
count = 0
while count < factor {
count = count + 1
temp = join(result, bytes(password))
result = sha512(temp)
}
// Encode the result, and return the first 43 characters
return String(base64Encode(result).sub(0, 43))
}
```
## Salted MD5
MD5 is a general purpose hashing algorithm producing a 128-bit hash. This is weak hash that has been shown to be compromised and is vulnerable to brute force attacks. This hash is provided for migration purposes and it should be upgraded to a stronger hash as soon as possible. A recommended minimum factor for this hashing algorithm is `20,000`.
The following is the string value used by the FusionAuth API to request this algorithm.
* `salted-md5`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
result = join(bytes(password), base64Decode(bytes(salt))
count = 0
while count < factor {
count = count + 1
result = md5(result)
}
return result
}
```
## Salted SHA-256
SHA-256 is part of the SHA-2 set of cryptographic standards. SHA-256 is a general purpose hash and similar to MD5 it was designed to be fast which makes it a less than ideal choice for a password hashing. This hash is mainly provided for migration purposes or where login performance is very critical. If login performance has not become an issue a stronger scheme should be utilized. A recommended minimum factor for this hashing algorithm is `20,000`.
The following is the string value used by the FusionAuth API to request this algorithm.
* `salted-sha256`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
result = join(bytes(password), base64Decode(bytes(salt))
count = 0
while count < factor {
count = count + 1
result = sha256(result)
}
return result
}
```
## Salted HMAC SHA-256
HMAC SHA-256 is a hash based message authentication code. This scheme is still vulnerable to brute force attacks and like MD5 and SHA-256 is mainly provided for migration purposes or where login performance is very critical. If login performance has not become an issue a stronger scheme should be utilized. This scheme does not utilize a factor.
The following is the string value used by the FusionAuth API to request this algorithm.
* `salted-hmac-sha256`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
key = {
salt: base64Decode(bytes(salt)
algorithm: "HmacSHA256"
}
hmac = Mac("HmacSHA256")
result = hmac(bytes(password))
return String(base64Encode(result))
}
```
## Salted PBKDF2 HMAC SHA-256
PBKDF2 (Password-Based Key Derivation Function2) applies a hash-based message authentication code (HMAC) to the salted input and iterates based upon a factor to produce the hashed output. A recommended factor for this hashing algorithm is between `5,000` and `100,000` depending on the CPU performance of your system.
FusionAuth provides two implementations of this algorithm, one with a `256` bit derived key, and another with `512` bit key.
The following are the two string values used by the FusionAuth API to request this algorithm with the `256` bit and the `512` bit key algorithm respectively.
* `salted-pbkdf2-hmac-sha256`
* `salted-pbkdf2-hmac-sha256-512`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import. The following example code shows a `256` key length, the pseudocode is the same for the `512` bit key.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
key = {
password: password
salt: base64Decode(bytes(salt)
factor: factor
keyLength: 256
}
secret = pbkdf2Sha256(key)
return String(base64Encode(secret))
}
```
## Salted PBKDF2 HMAC SHA-512
PBKDF2 (Password-Based Key Derivation Function2) applies a hash-based message authentication code (HMAC) to the salted input and iterates based upon a factor to produce the hashed output. A recommended factor for this hashing algorithm is between `5,000` and `100,000` depending on the CPU performance of your system.
The following is the string value used by the FusionAuth API to request this algorithm with the `512` bit key algorithm.
* `salted-pbkdf2-hmac-sha512-512`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
key = {
password: password
salt: base64Decode(bytes(salt)
factor: factor
keyLength: 512
}
secret = pbkdf2Sha512(key)
return String(base64Encode(secret))
}
```
## Salted Bcrypt
Bcrypt is a password hashing function based on the Blowfish cipher. A recommended factor for this hashing algorithm is between `8` and `14`. Unlike the other mentioned hashing functions the factor for Bcrypt is not simply an iteration count. Bcrypt uses the factor as a work factor, the work factor will be calculated using the provided factor as power of 2. This means that the difference between a factor of `12` and `13` is 2x. For example `2^12 = 4096` and `2^13 = 8192`.
The following is the string value used by the FusionAuth API to request this algorithm.
* `bcrypt`
The following pseudocode is provided to help you identify if this algorithm is likely to match your current hashing scheme such that it can be used during import.
```java
// Given a plain text password, a base64 encoded salt and a factor
hash(password, salt, factor) {
// Note that bcrypt uses a less common base64 character set for encoding and decoding.
// - The character set is: [./A-Za-z0-9]
passwordBytes = bytes(password)
saltBytes = base64Decode(bytes(salt))
result = bcrypt(passwordBytes, saltBytes, factor, bcryptIV)
resultLength = length(bcryptIV) * 4 - 1
result = sub(result, 0, resultLength)
return base64Encode(result)
}
```
## Additional Schemes
If you require a different hashing scheme, you can build a [password hashing plugin](/docs/extend/code/password-hashes/custom-password-hashing).
You may also want to review the [community provided plugins repository](https://github.com/FusionAuth/fusionauth-contrib/tree/main/Password%20Hashing%20Plugins).
These are provided without any warranty of suitability but may prove useful.
# Indexed User Fields
import IndexedUserFieldsList from 'src/content/docs/reference/_indexed-user-fields-list.astro';
If you are using the Elasticsearch engine, you can [search for users](/docs/lifecycle/manage-users/search/user-search-with-elasticsearch) by the following attributes.
# FusionAuth Android SDK
import RemoteContent from 'src/components/RemoteContent.astro';
## Overview
## Getting Started
If you are new to Android development, you may want to start with the Quickstart guide. If you are already familiar with Android development, skip to the Configuration section.
### Quickstart
### Configuration
## Usage
## Example App
## Documentation
The latest full library documentation of the SDK is available here: https://fusionauth.github.io/fusionauth-android-sdk/.
## Source Code
The source code is available here: https://github.com/FusionAuth/fusionauth-android-sdk/
# FusionAuth Dart Client Library
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## Dart Client Library
The dart client is being deprecated and the best path forward is to build the client from the [FusionAuth OpenAPI Specification](/docs/sdks/openapi).
### Example Apps
## Upgrade Policy
# FusionAuth Angular SDK
import HostedBackendWarning from 'src/content/docs/_shared/_hosted-backend-warning.md';
import RemoteContent from 'src/components/RemoteContent.astro';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## Usage With FusionAuth Cloud
## Source Code
The source code is available here: https://github.com/FusionAuth/fusionauth-javascript-sdk/tree/main/packages/sdk-angular/
## Upgrade Policy
# FusionAuth Go Client Library
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
import StaticPatchNote from 'src/content/docs/sdks/_static-patch-note.mdx';
## Go Client Library
The Go client library allows you to integrate FusionAuth with your Go application.
Source Code:
* https://github.com/FusionAuth/go-client
{/* TODO change this across all the client libraries */}
### Installation
```bash
go mod init example.com/test/fusionauth
go mod tidy
```
### Example Usage
Put this file in `fusionauth.go`
```go
package main
import (
"net/http"
"net/url"
"time"
"fmt"
"github.com/FusionAuth/go-client/pkg/fusionauth"
)
const host = "http://localhost:9011"
var apiKey = "YOUR_API_KEY"
var httpClient = &http.Client{
Timeout: time.Second * 10,
}
var baseURL, _ = url.Parse(host)
{/* Construct a new FusionAuth Client */}
var client = fusionauth.NewClient(httpClient, baseURL, apiKey)
func main() {
response, errors, err := client.RetrieveUserByEmail("user@example.com")
if err != nil {
// err is a transport layer error (connection failed, etc)
fmt.Println(err)
return
}
if errors != nil {
// err is a FusionAuth response error (user couldn't be found, etc)
fmt.Println(response.StatusCode)
return
}
fmt.Println(response.User.Email)
fmt.Println(response.User.FirstName)
fmt.Println(response.User.LastName)
}
```
To build an executable:
```bash
go build
```
To run:
```bash
./fusionauth
```
### Usage Suggestions
## PATCH requests
### Example apps
## Upgrade Policy
# Client Libraries and SDKs Overview
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
import Versioning from 'src/content/docs/operate/deploy/_client-library-versioning.mdx'
## Overview
Client libraries and SDKs will help you quickly integrate your application with FusionAuth. All of our client libraries are open source and hosted on our [GitHub account](https://github.com/FusionAuth). You can fork and tweak them as well as look over the code to learn how the client libraries work.
## SDKs vs Client Libraries
At FusionAuth, a **client library** is a thin wrapper over our FusionAuth APIs, and it provides complete coverage over all public FusionAuth API endpoints. A client library is like a set of legos, to be put together by a developer who wants to extend or manipulate FusionAuth to meet their needs.
You can use a client library to manage FusionAuth. For instance, if you wanted to rotate client secrets regularly, you could use a client library to do so.
It can also be used to integrate with a custom application to offer login experiences that are different from those that are offered out of the box. If, in your app, you wanted to prompt someone for a username first, then do a lookup, then offer them a custom password field, then prompt them to enter their favorite color, use a client library to perform these complicated, custom operations.
At FusionAuth, an **SDK** is an opinionated set of higher level constructs. These focus on a subset of functionality. These are like an assembled lego set.
These let you quickly accomplish the common tasks and are often targeted at developers working on the front end: mobile/React/Vue/Angular/JavaScript developers.
FusionAuth SDKs have:
* A button/function for logging in
* A button/function for logging out
* A button/function to register the user
* A filter/some way to examine roles and limit information displayed to a given role or set of roles
* A way to refresh a token without asking the user to reauthenticate.
* Secure access and refresh token storage
SDKs should require minimal customization to use.
If you want both the easy solutions provided by an SDK and the fine-grained control provided by a client library, you can use an SDK and a client library in the same application.
## Languages
If we are missing a language, open a [GitHub Issue](https://github.com/FusionAuth/fusionauth-issues/issues) as a Feature Request if you don't see it already listed as an open feature.
* [Angular SDK](/docs/sdks/angular-sdk)
* [Dart Client Library](/docs/sdks/dart)
* [Go Client Library](/docs/sdks/go)
* [Java Client Library](/docs/sdks/java)
* [.NET Core Client Library](/docs/sdks/netcore)
* [OpenAPI Client Library](/docs/sdks/openapi)
* [PHP Client Library](/docs/sdks/php)
* [Python Client Library](/docs/sdks/python)
* [React SDK](/docs/sdks/react-sdk)
* [Ruby Client Library](/docs/sdks/ruby)
* [Typescript Client Library](/docs/sdks/typescript)
* [Vue SDK](/docs/sdks/vue-sdk)
There are also [community contributed client libraries for other languages](https://github.com/FusionAuth/fusionauth-contrib/blob/main/client-libraries.md).
## Usage Suggestions
## Versioning
## Upgrade Policy
# FusionAuth Java Client Library
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
import StaticPatchNote from 'src/content/docs/sdks/_static-patch-note.mdx';
## Java Client Library
The Java client library allows you to integrate FusionAuth with your Java application.
Source Code:
* https://github.com/FusionAuth/fusionauth-java-client
Maven Dependency
```xml
io.fusionauthfusionauth-java-client${fusionauth.version}
```
When building your application, utilize the version that corresponds to the version of FusionAuth your running. View all available versions on [https://search.maven.org](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.fusionauth%22%20AND%20a%3A%22fusionauth-java-client%22).
## Using the FusionAuth and consuming the ClientResponse
The Java client has two styles of use, the first return a `ClientResponse` object. This object contains everything that occurred while communicating with the FusionAuth server. If the communication with the server encountered a network issue, the `ClientResponse.exception` might contain an `IOException`.
The following code assumes FusionAuth is running on `http://localhost:9011` and uses an API key `6b87a398-39f2-4692-927b-13188a81a9a3`, you will need to supply your own API key, and if you are not running FusionAuth locally, your host parameter may be different.
Here is an example of using the `retrieveUserByEmail` method to retrieve a User by an email address.
```java
import com.inversoft.error.Errors;
import io.fusionauth.client.FusionAuthClient;
import io.fusionauth.domain.User;
import io.fusionauth.domain.api.UserResponse;
import com.inversoft.rest.ClientResponse;
public class Example {
private final FusionAuthClient client;
public Example() {
client = new FusionAuthClient("6b87a398-39f2-4692-927b-13188a81a9a3", "http://localhost:9011");
}
public User getUserByEmail(String email) {
ClientResponse response = client.retrieveUserByEmail(email);
if (response.wasSuccessful()) {
return response.successResponse.user;
} else if (response.errorResponse != null) {
// Error Handling
Errors errors = response.errorResponse;
} else if (response.exception != null) {
// Exception Handling
Exception exception = response.exception;
}
return null;
}
}
```
## Using the Lambda Delegate
The Java Client may also be used along with our Lambda delegate that provides exception handling and allows you to write code assuming a happy path.
Here is the same example from above using the lambda delegate:
```java
import com.inversoft.error.Errors;
import io.fusionauth.client.LambdaDelegate;
import io.fusionauth.client.FusionAuthClient;
import io.fusionauth.domain.User;
import com.inversoft.rest.ClientResponse;
public class Example {
private final String apiKey = "6b87a398-39f2-4692-927b-13188a81a9a3";
private final String fusionauthURL = "http://localhost:9011";
private final FusionAuthClient client;
private final LambdaDelegate delegate;
public Example(String apiKey, String fusionauthURL) {
this.client = new FusionAuthClient(apiKey, fusionauthURL);
this.delegate = new LambdaDelegate(this.client, (r) -> r.successResponse, this::handleError);
}
public User getUserByEmail(String email) {
return delegate.execute(c -> c.retrieveUserByEmail("user@example.com")).user;
}
private void handleError(ClientResponse clientResponse) {
if (clientResponse.exception != null) {
// Handle the exception
...
} else if (clientResponse.errorResponse != null && clientResponse.errorResponse instanceof Errors) {
// Handle errors
...
}
}
}
```
As you can see, using the lambda delegate requires less code to handle the success response and the error handling code can be re-used.
### Usage Suggestions
## PATCH requests
### Example Apps
## Upgrade Policy
# FusionAuth OpenAPI Specification
## OpenAPI Specification
This OpenAPI Specification allows you to use FusionAuth with OpenAPI tooling. It supports OpenAPI version 3.
The [OpenAPI specification project](https://github.com/FusionAuth/fusionauth-openapi) contains the YAML file and a README with further information, including known issues.
The [current OpenAPI specification](https://raw.githubusercontent.com/FusionAuth/fusionauth-openapi/main/openapi.yaml) suitable for downloading and using.
# FusionAuth .NET Core Client Library
import Breadcrumb from 'src/components/Breadcrumb.astro';
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
import StaticPatchNote from 'src/content/docs/sdks/_static-patch-note.mdx';
## .NET Core Client Library
The .NET Core client library allows you to integrate FusionAuth with your .NET Core application.
Source Code:
* https://github.com/FusionAuth/fusionauth-netcore-client
NuGet Package:
* https://www.nuget.org/packages/FusionAuth.Client/
To install the FusionAuth Client from NuGet run the following command.
```bash
Install-Package FusionAuth.Client
```
### Usage Suggestions
## PATCH requests
## FusionAuth Templates for .NET
FusionAuth has a collection of .NET templates available as a NuGet package. Quickly create new secured .NET applications with FusionAuth templates using the .NET CLI or Visual Studio. The new applications are pre-configured to use FusionAuth for authentication and authorization. Only standard .NET security libraries are used in the templates.
Currently, the following .NET templates are implemented:
* FusionAuth Blazor Server Application.
* FusionAuth MVC Application.
* FusionAuth Web API Application.
### Requirements
* A FusionAuth installation. You can [install FusionAuth locally, or sign up for a hosted account](/docs/get-started/download-and-install).
* .NET Core 7.0 SDK or higher.
* Visual Studio 2022 for Mac, version 17.6 and above (optional).
* Visual Studio 2022 for Windows, version 17.6 and above (optional).
### Installing the Templates
FusionAuth .NET templates are available on [NuGet](https://www.nuget.org/packages/FusionAuth.Templates/). You can install them by running the following command in your terminal.
```bash
dotnet new install FusionAuth.Templates::1.0.0
```
When installed successfully, the templates will be available in the .NET CLI and Visual Studio. The installation is the same for both Windows and macOS.
### Using the Templates
To help you set up a valid application in FusionAuth, we have created a FusionAuth [Kickstart](/docs/get-started/download-and-install/development/kickstart), available on [GitHub](https://github.com/FusionAuth/fusionauth-example-client-libraries/tree/main/kickstart/kickstart.json). Follow the instructions in the [README.md](https://github.com/FusionAuth/fusionauth-example-client-libraries/tree/main/dotnet/templates/README.md) file to set up FusionAuth for your project. If you don't want to use the Kickstart file, you can set up your application manually in FusionAuth, using the values referenced in the [kickstart.json](https://github.com/FusionAuth/fusionauth-example-client-libraries/tree/main/kickstart/kickstart.json) file.
Note that the Kickstart is designed to be used when starting up FusionAuth for the first time using `docker compose up`.
The FusionAuth instance created by the Kickstart assumes that your .NET project will be running on `HTTPS` on port `5001`. Your project might not run on the same port, as Visual Studio will randomly choose a port if the chosen one is already in use by another project. It may also be a different port if you run the project through IIS or another web server. In this case, update the `authorizedRedirectURL` and `logoutURL` variables in the [kickstart.json](https://github.com/FusionAuth/fusionauth-example-client-libraries/tree/main/kickstart/kickstart.json) file to that of your project. You can also update the URLs on the Application settings page in the FusionAuth admin UI on [the OAuth tab](/docs/get-started/core-concepts/applications#oauth) at any time after the Kickstart has run.
Some templates will ask for a FusionAuth Client Secret when initializing a new project. Use a non-sensitive secret from a local FusionAuth installation. If you use the Kickstart to set up your FusionAuth instance, the Client Secret will be `change-this-in-production-to-be-a-real-secret`.
Do not use a production or sensitive Client Secret in the template prompts, as it is stored in the `appsettings.Development.json` file, and will be available in plain text and committed to your repo. To provide the Client Secret to your application in production, you should use one of the secure methods [recommended by Microsoft](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&tabs=windows). The platform-independent key for the Client Secret setting is `FusionAuth__ClientSecret` if you want to provide the Client Secret via an [environment variable](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&tabs=windows#environment-variables).
#### .NET CLI
To create a new project from a template, navigate to your new project directory and run the following command.
```bash
dotnet new [template-name] [options]
```
Where `[template-name]` is the name of the template you want to use from one of the following:
- `fusionauthblazorserver` creates a new Blazor Server application with FusionAuth authentication and authorization.
- `fusionauthmvcwebapp` creates a new MVC application with FusionAuth authentication and authorization.
- `fusionauthwebapi` creates a new Web API application with FusionAuth authentication and authorization.
Use `[options]` to provide your FusionAuth URL and FusionAuth Application Client Id. The following options are available:
- `--issuer` is the fully qualified URL to your FusionAuth server. The default value is `http://localhost:9011`.
- `--client-id` is the [Client Id](/docs/get-started/core-concepts/applications) associated with your application. The default value is `3c219e58-ed0e-4b18-ad48-f4f92793ae32`.
- `--port` is the port to run on under [Kestrel](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-7.0), using HTTPS. The default value is `5001`. This can be changed after installation in the `appsettings.Development.json` file in the root directory of the project and `launchSettings.json` in the `Properties` directory of the project.
#### Visual Studio for macOS
FusionAuth .NET templates require Visual Studio for macOS version 17.6 or higher.
To create a new project from a template, first create or open a Solution. Then select File -> New Project. In the New Project dialog, select Custom from the left-hand menu. Select the FusionAuth template you want to use and click Continue. Fill in the required information, including the fully qualified URL to your FusionAuth server and your FusionAuth Application Client Id. Click Continue.
Set the project name and click Create.
#### Visual Studio for Windows
FusionAuth .NET templates require Visual Studio for Windows version 17.6 or higher.
To create a new project from a template, first create or open a Solution. Then select File -> New Project. In the New Project dialog, select "FusionAuth" from the All project types dropdown. Select the FusionAuth template you want to use. Set the project name and click Next. Fill in the required information, including the fully qualified URL to your FusionAuth server and your FusionAuth Application Client Id.
Click Create.
### Testing
To test projects created using the .NET templates, refer to the testing section in the [README.md](https://github.com/FusionAuth/fusionauth-example-client-libraries/tree/main/dotnet/templates/README.md) file.
### Uninstalling the Templates
You can uninstall the templates using the following command.
```bash
dotnet new uninstall FusionAuth.Templates
```
You will need to restart Visual Studio for the changes to take effect.
### Example Apps
## Upgrade Policy
# FusionAuth PHP Client Library
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## PHP Client Library
The PHP client library allows you to integrate FusionAuth with your PHP application.
Source code:
* https://github.com/FusionAuth/fusionauth-php-client
### Install the library
To use the client library on your project simply copy the PHP source files from the `src` directory to your project or the following
Composer package.
Packagist
* https://packagist.org/packages/fusionauth/fusionauth-client
```bash
composer require fusionauth/fusionauth-client
```
Include composer autoloader
```php
require __DIR__ . '/vendor/autoload.php';
```
### Usage Suggestions
### Create the Client
The following code assumes FusionAuth is running on `http://localhost:9011` and uses an API key `5a826da2-1e3a-49df-85ba-cd88575e4e9d`, you will need to supply your own API key, and if you are not running FusionAuth locally, your host parameter may be different.
```php
$apiKey = "5a826da2-1e3a-49df-85ba-cd88575e4e9d";
$client = new FusionAuth\FusionAuthClient($apiKey, "http://localhost:9011");
```
### Login a user
```php
$applicationId = "68364852-7a38-4e15-8c48-394eceafa601";
$request = array();
$request["applicationId"] = $applicationId;
$request["loginId"] = "joe@fusionauth.io";
$request["password"] = "abc123";
$result = $client->login($request);
if (!$result->wasSuccessful()) {
// Error
}
{/* Hooray! Success */}
```
### Example Apps
### Other PHP Libraries
Here are other PHP libraries that may be useful. Some are community supported; please visit the library website to learn more.
* [WordPress OpenID Connect Plugin](https://github.com/FusionAuth/wordpress-openid-connect)
* [FusionAuth Provider for the PHP League's OAuth 2.0 Client](https://github.com/jerryhopper/oauth2-fusionauth)
* [FusionAuth Provider for Laravel Socialite](https://github.com/SocialiteProviders/FusionAuth)
## Upgrade Policy
# FusionAuth Python Client Library
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## Python Client Library
The Python client library allows you to integrate FusionAuth with your Python application.
Source code:
* https://github.com/FusionAuth/fusionauth-python-client
PyPI Package:
* https://pypi.org/project/fusionauth-client/
To install the FusionAuth Python Client package run:
```bash
pip install fusionauth-client
```
The following code assumes FusionAuth is running on `http://localhost:9011` and uses an API key `6b87a398-39f2-4692-927b-13188a81a9a3`, you will need to supply your own API key, and if you are not running FusionAuth locally, your host parameter may be different.
Here is an example of using the `create_user` method to create, and then the `retrieveUserByEmail` method to retrieve the User by email address.
```python
from fusionauth.fusionauth_client import FusionAuthClient
# You must supply your API key and URL here
client = FusionAuthClient('6b87a398-39f2-4692-927b-13188a81a9a3', 'http://localhost:9011')
user_request = {
'sendSetPasswordEmail': False,
'skipVerification': True,
'user': {
'email': 'art@vandaleyindustries.com',
'password': 'password'
}
}
client_response = client.create_user(user_request)
# Create a User
if client_response.was_successful():
print(client_response.success_response)
else:
print(client_response.error_response)
# Retrieve a user by email address
client_response = client.retrieve_user_by_email('art@vandaleyindustries.com')
if client_response.was_successful():
print(client_response.success_response)
else:
print(client_response.error_response)
```
### Usage Suggestions
### Example Apps
## Upgrade Policy
# FusionAuth React SDK
import HostedBackendWarning from 'src/content/docs/_shared/_hosted-backend-warning.md';
import RemoteContent from 'src/components/RemoteContent.astro';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## Usage With FusionAuth Cloud
## Source Code
The source code is available here: https://github.com/FusionAuth/fusionauth-javascript-sdk/tree/main/packages/sdk-react/
## Upgrade Policy
# FusionAuth Swift SDK for iOS
import RemoteContent from 'src/components/RemoteContent.astro';
## Overview
## Getting Started
If you are new to iOS development, you may want to start with the Quickstart guide. If you are already familiar with iOS development, skip to the Configuration section.
### Quickstart
### Configuration
## Usage
## Example App
## Documentation
## Source Code
The source code is available here: https://github.com/FusionAuth/fusionauth-swift-sdk/
# FusionAuth Ruby Client Library
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## Ruby Client Library
The Ruby client library allows you to integrate FusionAuth with your Ruby application.
Source Code:
* https://github.com/FusionAuth/fusionauth-ruby-client
Gem:
* https://rubygems.org/gems/fusionauth_client
To install the FusionAuth Ruby Gem package run:
```bash
gem install fusionauth_client
```
The following code assumes FusionAuth is running on `http://localhost:9011` and uses an API key `6b87a398-39f2-4692-927b-13188a81a9a3`, you will need to supply your own API key, and if you are not running FusionAuth locally, your host parameter may be different.
Here is an example of using the `register` and the `login` methods to create a new User and Registration and then login the user.
```ruby
require 'fusionauth/fusionauth_client'
require 'securerandom'
require 'pp'
# Construct the FusionAuth Client
client = FusionAuth::FusionAuthClient.new(
'REPLACE_ME',
'http://localhost:9011'
)
application_id = '85a03867-dccf-4882-adde-1a79aeec50df'
# Create a user + registration
id = SecureRandom.uuid
response = client.register(id, {
user: {
firstName: 'Ruby',
lastName: 'User',
email: 'ruby_user@example.com',
password: 'password'
},
registration: {
applicationId: application_id,
data: {
foo: 'bar'
},
preferredLanguages: %w(en fr),
roles: %w(dev)
}
})
if response.success_response
pp response.success_response
else
if response.exception
# if we can't connect
print response.exception
end
print "status: #{response.status}"
print response.error_response
exit
end
```
### Usage Suggestions
### Example Apps
## Upgrade Policy
# FusionAuth Typescript Client Library
import Aside from 'src/components/Aside.astro';
import ExampleApps from 'src/content/docs/sdks/examples/_example-footer.astro';
import HowToUseClientLibraries from 'src/content/docs/sdks/_how-to-use-client-libraries.mdx';
import PublicClientNote from 'src/content/docs/sdks/_public-client-note.mdx';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## Typescript Client Library
The Typescript client library allows you to integrate FusionAuth with your JavaScript application.
Regardless of the fact that this is written in TypeScript, this client supports both Node.js and Browser environments without requiring that your application is also written in typescript.
### Installing
#### Source Code:
* https://github.com/FusionAuth/fusionauth-typescript-client
#### NPM Package:
* https://www.npmjs.com/package/@fusionauth/typescript-client
To install the FusionAuth Typescript Client package run:
```bash
npm install @fusionauth/typescript-client
```
#### Browser bundle:
We also release a prebundled version of the client for the browser on our GitHub releases page. This version can be simply included as an HTML `
```
You can also find this example's [source code](https://github.com/FusionAuth/fusionauth-typescript-client/tree/main/examples/browser-example) in the [typescript repo](https://github.com/FusionAuth/fusionauth-typescript-client).
#### Hybrid
You can write the hybrid exactly the same as the Node.js example (but keep in mind that API keys will be exported so it is not recommended to use API keys at all). The key difference in this case is the build script. Instead of just using `tsc` to compile and running Node.js on the resulting JavaScript, you will instead use a tool like `browserify` or `webpack` to build your script. This example uses `browserify` for simplicity.
We can easily build a hybrid project using one of two commands, each associated with the target
```bash
# Compile for Node.js
tsc
# Compile for browser
npm run build-browser
# AKA
npx browserify example.ts --debug -p tsify -t browserify-shim -o dist/example-browser.js
```
You can also find this example's [source code](https://github.com/FusionAuth/fusionauth-typescript-client/tree/main/examples/hybrid-example) in the [typescript repo](https://github.com/FusionAuth/fusionauth-typescript-client).
### Usage Suggestions
### Client Authentication
### Example Apps
## Upgrade Policy
# FusionAuth Vue SDK
import HostedBackendWarning from 'src/content/docs/_shared/_hosted-backend-warning.md';
import RemoteContent from 'src/components/RemoteContent.astro';
import SdkUpgradePolicy from 'src/content/docs/sdks/_upgrade-policy.mdx';
## Usage With FusionAuth Cloud
## Source Code
The source code is available here: https://github.com/FusionAuth/fusionauth-javascript-sdk/tree/main/packages/sdk-vue/
## Upgrade Policy
# Actioning Users
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import ActionUserRequestBody from 'src/content/docs/apis/_action-user-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import ActionUserResponseBody from 'src/content/docs/apis/_action-user-response-body.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import ActionUserListResponseBody from 'src/content/docs/apis/_action-user-list-response-body.mdx';
import ActionUserUpdateRequestBody from 'src/content/docs/apis/_action-user-update-request-body.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
## Overview
This page contains the APIs that are used for actioning users.
Once you have created the User Actions, either via the administrative user interface or the [User Actions API](/docs/apis/user-actions), you use this API to invoke a User Action on a User.
## Take an Action on a User
This API is used to take a User Action on a User. User Actions are the method that FusionAuth uses to discipline, reward and interact with Users.
### Request
### Response
The response for this API contains the User Action along with any event and email information that was generated by FusionAuth.
## Retrieve a Previously Taken Action
This API is used to retrieve a User Action that was previously taken on a User, this can be thought of as the log or historical record.
### Request
#### Request Parameters
The unique Id of the Action to retrieve.
#### Request Parameters
The unique Id of the User for which to retrieve all of the Actions.
When this parameter is provided and set to `true`, only active actions will be returned. When this parameter is provided and set to `false`, only the inactive actions will be returned. When this parameter is omitted, all actions will be returned.
An active action is a time based action that has not yet expired or been canceled. An inactive action is either a time based action that has expired, canceled or an action that is not time based.
This parameter and `preventingLogin` are mutually exclusive.
When this value is provided and set to `true`, only active actions that are preventing the user from login will be returned. Omitting this parameter, or setting this parameter to `false` does not affect the API behavior.
This parameter and `active` are mutually exclusive because an action that is preventing login is always active.
### Response
The response for this API contains either a single User Action Log or a list of User Actions Logs for a User. If you specified an `actionId` on the URI the response will contain the User Action Log for that Id. If you pass in a `userId` as a URL parameter the response will contain all of the User Action Logs for that User. Both responses are defined below along with an example JSON response.
## Update a Previously Taken Action
This API is used to update a User Action that was previously taken on a User. User Actions are the method that FusionAuth uses to discipline, reward and interact with Users.
### Request
#### Request Parameters
The Id of the User Action being updated.
### Response
The response for this API contains the User Action along with any event and email information that was generated by FusionAuth.
## Cancel a Previously Taken Action
This API is used to cancel a User Action that was previously taken on a User. User Actions are the method that FusionAuth uses to discipline, reward and interact with Users.
### Request
#### Request Parameters
The Id of the User Action being canceled.
### Response
The response for this API contains the User Action along with any event and email information that was generated by FusionAuth.
# API Explorer
import InlineField from 'src/components/InlineField.astro';
import Aside from 'src/components/Aside.astro';
import SwaggerExplorer from 'src/content/docs/apis/_swagger-explorer.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
This tool uses the [FusionAuth OpenAPI specification](https://github.com/fusionauth/fusionauth-openapi) to let you explore the APIs FusionAuth offers.
This is designed to be used against a local FusionAuth instance.
## Prerequisites
FusionAuth can be locally installed or used as a SaaS solution. This API explorer is useful only for a local installation.
Please install FusionAuth locally, using [Docker or any other supported method](/docs/get-started/download-and-install), to use the [Explorer](#explorer).
After you install FusionAuth, make sure you have [created an API key with the correct permissions](/docs/apis/authentication#managing-api-keys). This API key will not be stored.
## Configuration
This tool defaults to using the latest version of the FusionAuth API. If you are using a different version, find the [correct version](https://github.com/FusionAuth/fusionauth-openapi/tags) and update the URL in the input box, then click Explore.
For example, to view the 1.40.0 release, put `https://raw.githubusercontent.com/FusionAuth/fusionauth-openapi/1.40.0/openapi.yaml` in the YAML URL input.
Click on the Authorize button to add the FusionAuth API key you created above. You will need to do this every time you reload the page.
### In-Browser API Calls
If you want to use the in-browser API explorer, you have to configure CORS on the local FusionAuth instance. Doing so is not required if using the example curl commands to call the API from the command line.
To set up CORS:
* Log in to your FusionAuth administrative user interface
* Navigate to Settings -> System
* Enable CORS.
* Update Allowed headers to include `authorization`, `accept` and `content-type` headers.
* Check all the Allowed methods
* Set Allowed origins to your origin. You can also use the value of `*`, which allows any origin to connect.
## Explorer
# API Keys
import Aside from 'src/components/Aside.astro';
import InlineField from 'src/components/InlineField.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import ApikeyPostPutRequestBody from 'src/content/docs/apis/_apikey-post-put-request-body.mdx';
import ApikeyCopyRequestBody from 'src/content/docs/apis/_apikey-copy-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import ApikeyPostPutResponseBody from 'src/content/docs/apis/_apikey-post-put-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import ApikeyGetResponseBody from 'src/content/docs/apis/_apikey-get-response-body.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import { YouTube } from '@astro-community/astro-embed-youtube';
## Overview
The FusionAuth APIs are primarily secured using API keys. This API can only be accessed using an API key that has a `keyManager` attribute of `true`. In order to retrieve, update or delete an API key, an API key with equal or greater permissions must be used. A "tenant-scoped" API key can retrieve, create, update or delete an API key for the same tenant. This page describes APIs that are used to manage API keys.
Here's a brief video covering the API keys API:
Please refer to the [Authentication](/docs/apis/authentication#) document for more details about using API keys.
## The Key Manager Setting
Below is an image of an API key being created in the administrative user interface with Key manager enabled:
For security purposes, the Key manager setting may be modified only using the administrative user interface or Kickstart. It can't be changed using this API.
## Create an API Key
This API is used to create a new API Key. An API key with key manager permission set to `true` can create keys. An API key that is tenant scoped can create another key for the same tenant.
A key with key manager permissions can not be created using this API. Only through admin UI or kickstart can you create such a key.
### Request
#### Request Parameters
The unique Id of the API Key to create. If not specified a secure random UUID will be generated.
#### Request Parameters
The unique Id of the API Key to create. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the Key that was created.
## Retrieve an API Key
This API is used to retrieve a single API Key by unique Id. To retrieve a key, an API key with equal or greater permissions must be used.
### Request Parameters
The unique Id of the API Key to retrieve.
### Response
The response for this API contains a single API Key. The response is defined below along with an example JSON response.
## Update an API Key
This API is used to update an existing API Key. A tenant-scoped API key can update another API key for the same tenant.
### Request Parameters
The unique Id of the API Key to update.
### Response
The response for this API contains the Key that was updated.
## Delete an API Key
This API is used to delete a Key. Deletion is possible only with another API key with equal or greater permissions. A tenant-scoped API key can delete another API key for the same tenant.
### Request Parameters
The unique Id of the API Key to delete.
### Response
This API does not return a JSON response body.
# Applications
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import API from 'src/components/api/API.astro';
import ApplicationCopyRequestBody from 'src/content/docs/apis/_application-copy-request-body.mdx';
import ApplicationOauthConfigurationResponseBody from 'src/content/docs/apis/_application-oauth-configuration-response-body.mdx';
import ApplicationRequestBody from 'src/content/docs/apis/_application-request-body.mdx';
import ApplicationResponseBody from 'src/content/docs/apis/_application-response-body.mdx';
import ApplicationsResponseBody from 'src/content/docs/apis/_applications-response-body.mdx';
import ApplicationResponseBodyBase from 'src/content/docs/apis/_application-response-body-base.mdx';
import ApplicationSearchRequestParameters from 'src/content/docs/apis/_application-search-request-parameters.mdx';
import Aside from 'src/components/Aside.astro';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import JSON from 'src/components/JSON.astro';
import RoleResponseBody from 'src/content/docs/apis/_role-response-body.mdx';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import XFusionauthTenantIdHeaderCreateOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-create-operation.mdx';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
## Overview
This page contains the APIs that are used to manage Applications as well as the Roles of an Application. Here are the APIs:
## Create an Application
This API is used to create an Application. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the Application. Otherwise, FusionAuth will generate an Id for the Application.
### Request
#### Request Parameters
The Id to use for the new Application, which must be unique across all Tenants. If not specified a secure random UUID will be generated.
#### Request Parameters
The Id to use for the new Application. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the information for the Application that was created.
## Retrieve an Application
This API is used to retrieve one or all of the configured Applications. Specifying an Id on the URI will retrieve a single Application. Leaving off the Id will retrieve all of the Applications.
### Request
#### Request Parameters
Set this parameter to `true` in order to retrieve only inactive Applications. Setting this parameter to `false` is equivalent omitting the `inactive` parameter.
#### Request Parameters
The Id of the Application to retrieve. This request will return the Application if it exists regardless if the Application is active or not.
### Response
The response for this API contains either a single Application or all of the Applications. When you call this API with an Id the response will contain just that Application. When you call this API without an Id the response will contain all of the Applications. Both response types are defined below along with an example JSON response.
## Update an Application
### Request
### Response
The response for this API contains the new information for the Application that was updated.
## Search for Applications
This API is used to search for Applications and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
#### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
### Response
The response for this API contains the Applications matching the search criteria in paginated format.
#### Response Body
## Delete an Application
This API is used to delete an Application. You must specify the Id of the Application on the URI. You can also specify whether or not the Application is soft or hard deleted. Soft deleted Applications are marked as inactive but not deleted from FusionAuth.
### Request
#### Request Parameters
The Id of the Application to delete.
Whether or not the Application is soft or hard deleted. A hard delete is a permanent operation.
### Response
This API does not return a JSON response body.
## Reactivate an Application
This API is used to reactivate an inactive Application. You must specify the Id of the Application on the URI.
### Request
#### Request Parameters
The Id of the Application to reactivate.
### Response
The response for this API contains the information for the Application that was reactivated.
## Create an Application Role
This API is used to create a role for an Application. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the role. Otherwise, FusionAuth will generate an Id for the role.
### Request
#### Request Parameters
The Id of the Application.
The Id to use for the new role. If not specified a secure random UUID will be generated.
#### Request Body
A description for the role.
The name of the Role.
Whether or not the Role is a default role. A default role is automatically assigned to a user during registration if no roles are provided.
Whether or not the Role is a considered to be a super user role. This is a marker to indicate that it supersedes all other roles. FusionAuth will attempt to enforce this contract when using the web UI, it is not enforced programmatically when using the API.
### Response
The response for this API contains the information for the role that was created.
## Update an Application Role
### Request
#### Request Parameters
The Id of the Application.
The Id of the role that is being updated.
#### Request Body
A description for the role.
The name of the Role.
Whether or not the Role is a default role. A default role is automatically assigned to a user during registration if no roles are provided. More than one role can be marked as default.
Whether or not the Role is a considered to be a super user role. This is a marker to indicate that it supersedes all other roles. FusionAuth will attempt to enforce this contract when using the web UI, it is not enforced programmatically when using the API.
### Response
The response for this API contains the new information for the role that was updated.
## Delete an Application Role
This API is used to delete a role from an Application.
### Request
#### Request Parameters
The Id of the Application to which the role belongs.
The Id of the role to delete.
#### Request Parameters
The Id of the Application to which the role belongs.
The name of the role to delete.
### Response
This API does not return a JSON response body.
## Retrieve OAuth Configuration
This API is used to retrieve the Application OAuth configuration. When an API key is provided on the request the OAuth client secret
will also be returned. When this API is called without authentication the client secret will not be returned in the response body.
### Request
#### Request Parameters
The Id of the Application to retrieve the OAuth configuration.
### Response
# Audit Logs
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import JSON from 'src/components/JSON.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import InlineField from 'src/components/InlineField.astro';
import Aside from 'src/components/Aside.astro';
## Overview
This page contains the APIs that are used to manage the Audit Log. Here are the APIs:
## Add an Entry to the Audit Log
This API allows you to insert an Audit Log. Generally, Audit Logs are created automatically whenever an admin does something from the FusionAuth UI. However, you can use this API to insert Audit Logs directly if you need.
### Request
#### Request Body
An object that can hold additional details of an audit log.
Intended to be utilized during a change to record the new value.
Intended to be utilized during a change to record the old value prior to the change.
Intended to be utilized during a change to indicate the reason for the modification.
The user that took the action that is being written to the Audit Logs. We suggest you use email addresses for this field.
The message of the Audit Log.
### Response
The response for this API does not contain a body. It only contains a status code.
## Retrieve an Audit Log
### Request
#### Request Parameters
The unique Id of the Audit Log to retrieve.
### Response
#### Response Body
Additional details of an audit log.
The new value of a changed object.
The previous value of a changed object.
The reason why the audit log was created.
The Audit Log unique Id.
The [instant](/docs/reference/data-types#instants) when the Audit Log was created.
The user that created the Audit Log.
The message of the Audit Log.
## Search the Audit Log
This API allows you to search and paginate through the Audit Logs.
### Request
When calling the API using a `GET` request you will send the search criteria on the URL using request parameters. In order to simplify the example URL above, not every possible parameter is shown, however using the provided pattern you may add any of the documented request parameters to the URL.
#### Request Parameters
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The string to search in the Audit Log message for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The string to search for in the Audit Log field for newValue. Note, that not all audit log entries will contain this field, it is primarily used for Audit Logs for updates to existing objects.
The number of results to return from the search.
The string to search for in the Audit Log field for oldValue. Note, that not all audit log entries will contain this field, it is primarily used for Audit Logs for updates to existing objects.
The database column to order the search results on plus the order direction.
The possible values are:
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Audit Log was created
* `insertUser` - the user that create the Audit Log
* `message` - the message of the Audit Log
For example, to order the results by the insert instant in a descending order, the value would be provided as `insertInstant DESC`. The final string is optional can be set to `ASC` or `DESC`.
The string to search for in the Audit Log field for reason. Note, that not all audit log entries will contain this field.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
The string to search in the Audit Log user for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The string to search in the Audit Log message for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The string to search for in the Audit Log field for newValue. Note, that not all audit log entries will contain this field, it is primarily used for Audit Logs for updates to existing objects.
In versions >= 1.49.0 sensitive values may be masked.
The number of results to return from the search.
The string to search for in the Audit Log field for oldValue. Note, that not all audit log entries will contain this field, it is primarily used for Audit Logs for updates to existing objects.
In versions >= 1.49.0 sensitive values may be masked.
The database column to order the search results on plus the order direction.
The possible values are:
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Audit Log was created
* `insertUser` - the user that create the Audit Log
* `message` - the message of the Audit Log
For example, to order the results by the insert instant in a descending order, the value would be provided as `insertInstant DESC`. The final string is optional can be set to `ASC` or `DESC`.
The string to search for in the Audit Log field for reason. Note, that not all audit log entries will contain this field.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
The string to search in the Audit Log user for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
### Response
The response for this API contains the Audit Logs matching the search criteria in paginated format.
#### Response Body
The list of Audit Logs returned by the search.
Additional details of an audit log.
The new value of a changed object.
In versions >= 1.49.0 sensitive values may be masked.
The previous value of a changed object.
In versions >= 1.49.0 sensitive values may be masked.
The reason why the audit log was created.
The Audit Log unique Id.
The [instant](/docs/reference/data-types#instants) when the Audit Log was created.
The user that created the Audit Log.
The message of the Audit Log.
The total number of Audit Logs matching the search criteria. Use this value along with the numberOfResults and startRow in the Search request to perform pagination.
## Export Audit Logs
This API is used to export the Audit Logs, the response will be a compressed zip archive.
### Request
When calling the API using a `GET` request you will send the export criteria on the URL using request parameters. In order to simplify the example URL above, not every possible parameter is shown, however using the provided pattern you may add any of the documented request parameters to the URL.
#### Request Parameters
The format string used to format the date and time columns in the export result.
When this parameter is omitted a default format of `M/d/yyyy hh:mm:ss a z` will be used. See the [DateTimeFormatter patterns](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) for additional examples.
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The string to search in the Audit Log message for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The string to search in the Audit Log user for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The [time zone](/docs/reference/data-types#time-zone) used to adjust the stored UTC time in the export result.
For example:
> `America/Denver` or `US/Mountain`
When this parameter is omitted the configured default report time zone will be used. See reportTimezone in the [System Configuration API](/docs/apis/system).
When calling the API using a `POST` request you will send the export criteria in a JSON request body.
#### Request Body
The end [instant](/docs/reference/data-types#instants) of the date/time range to include in the export.
The string to search in the Audit Log message for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The start [instant](/docs/reference/data-types#instants) of the date/time range to include in the export.
The string to search in the Audit Log user for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The format string used to format the date and time columns in the export result.
When this parameter is omitted a default format of `M/d/yyyy hh:mm:ss a z` will be used. See the [DateTimeFormatter patterns](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) for additional examples.
The [time zone](/docs/reference/data-types#time-zone) used to adjust the stored UTC time in the export result.
For example:
> `America/Denver` or `US/Mountain`
When this parameter is omitted the configured default report time zone will be used. See reportTimezone in the [System Configuration API](/docs/apis/system).
### Response
The response for this API will contain a compressed zip of the audit logs.
# API Authentication
import APIAuthenticationIcon from "src/components/api/APIAuthenticationIcon.astro";
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import APIKeyCrossTenantNote from 'src/content/docs/apis/_api-key-cross-tenant-note.mdx';
import Aside from 'src/components/Aside.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import ClientSideApiKeys from 'src/content/docs/_shared/_client-side-api-keys.mdx';
import NewApiKey401 from 'src/content/docs/apis/_new-api-key-401.mdx';
import EnterprisePlanBlurb from 'src/content/docs/_shared/_enterprise-plan-blurb.astro';
import TenantAuthentication from 'src/content/docs/apis/_tenant-authentication.mdx';
import { YouTube } from '@astro-community/astro-embed-youtube';
import InlineField from '../../../components/InlineField.astro';
## Overview
The FusionAuth APIs are primarily secured using API keys. A few APIs may use alternate credentials, such as a JWT, basic authentication. Certain APIs are accessible with no authentication. All secured APIs will return an `401 Unauthorized` response if improper credentials are provided.
Each API endpoint is marked with an icon describing supported authentication methods:
* [API Key Authentication](#api-key-authentication)
* [Basic Authentication using an API Key](#basic-authentication-using-an-api-key)
* [Client Credentials](#client-credentials)
* [JWT Authentication](#jwt-authentication)
* [No Authentication Required](#no-authentication-required)
* [Localhost Authentication Bypass](#localhost-authentication-bypass)
You can also learn about:
Below you will find a detailed explanation of each type of authentication used in the API documentation.
## API Key Authentication
When an API is marked with a red locked icon such as it means you are required to provide an API key.
To enable access to a secured API, create one or more API keys. The API key is then supplied in the HTTP request using the Authorization header. See [Managing API Keys](#managing-api-keys) for more information on adding additional keys.
The following example demonstrates the HTTP Authorization header with an API key of: `7DUrRlA75b5LBRARYoTmScCTk6G6U1nG8R9mr7MGnvzA7AMxEXAMPLE`
```properties
Authorization: 7DUrRlA75b5LBRARYoTmScCTk6G6U1nG8R9mr7MGnvzA7AMxEXAMPLE
```
The following is a curl example using the Authorization header using the above API key to retrieve a user. The line breaks and spaces are for readability.
```shell
curl -H 'Authorization: 7DUrRlA75b5LBRARYoTmScCTk6G6U1nG8R9mr7MGnvzA7AMxEXAMPLE' \
'https://local.fusionauth.io/api/user?email=richard@piedpiper.com'
```
Here's a brief video covering some aspects of API keys:
## Basic Authentication using an API Key
When an API endpoint is marked with a shield such as it means you call this API and authenticate using HTTP basic authentication. HTTP basic authentication is a simple, standards based, authentication method. A username and password are supplied, separated by a `:`. It must be prefaced by the string `Basic` and a space. The `username:password` string is base64 encoded.
When using this authentication method in FusionAuth for an API, the username must be the string `apikey` in lowercase. The password may be any API key with the appropriate permission for the endpoint being called.
Basic authentication using an API key is only utilized by a select few FusionAuth APIs. These are typically integrated with other software packages which expect such an authentication method.
### Authorization Header Examples
The following example demonstrates the HTTP Basic Authorization header.
```properties
Authorization: Basic YXBpa2V5OjY5Y1dxVW8wNGhpNFdMdUdBT2IzMmRXZXQwalpkVzBtSkNjOU9yLUxEamNIUXFMSzJnR29mS3plZg==
```
The following is a curl example using the HTTP Basic Authorization header with a line break and spaces for readability.
```shell
curl -X GET \
-H 'Authorization: Basic YXBpa2V5OjY5Y1dxVW8wNGhpNFdMdUdBT2IzMmRXZXQwalpkVzBtSkNjOU9yLUxEamNIUXFMSzJnR29mS3plZg==' \
'https://local.fusionauth.io/api/prometheus/metrics'
```
## Client Credentials
When an API is marked with a blue passport icon such as , the authorization becomes a two step process. To complete the process and generate a token you must:
* Use the `client_credentials` grant to obtain a JSON Web Token (JWT). The requester should be granted the appropriate permissions on the target entity.
* Make a request of the API with the JWT in the `Authorization` header using the `Bearer` scheme.
If the JWT is expired or incorrect, the request will fail.
The requesting and target entities, as well as permissions, are all managed using [Entities](/docs/get-started/core-concepts/entity-management).
## Client Credentials Examples
Here is an example [client credentials grant using Entities](/docs/lifecycle/authenticate-users/oauth/#example-client-credentials-grant).
Here's another example. First, you get the token:
```shell title="Curl example to retrieve JWT"
curl -u "eb6fce6a-4ed8-4010-8091-1709fc823329:_7bz1Ct1Sode-zIyevcQFSyzW9w3TkfKSWuS-Ls8vQQ" \
https://local.fusionauth.io/oauth2/token \
-d 'grant_type=client_credentials&scope=target-entity:a647e989-1c7e-4386-9ec6-fa4fe6908906:scim:user:read'
```
Here's an example JWT that might be returned:
```properties title="SCIM request example Authorization header"
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImd0eSI6WyJjbGllbnRfY3JlZGVudGlhbHMiXSwia2lkIjoiMDUzYWE1Y2QxIiwidXNlIjoic2NpbV9zZXJ2ZXIifQ.eyJhdWQiOiJhNjQ3ZTk4OS0xYzdlLTQzODYtOWVjNi1mYTRmZTY5MDg5MDYiLCJleHAiOjE2NTU3NjExNzAsImlhdCI6MTY1NTc1NzU3MCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiJlYjZmY2U2YS00ZWQ4LTQwMTAtODA5MS0xNzA5ZmM4MjMzMjkiLCJqdGkiOiJjMTMxYThiZi0yN2E5LTQ2MGUtOTFiYi0xOTI5NmE2MDFlMTEiLCJzY29wZSI6InRhcmdldC1lbnRpdHk6YTY0N2U5ODktMWM3ZS00Mzg2LTllYzYtZmE0ZmU2OTA4OTA2OnNjaW06dXNlcjpyZWFkIiwidGlkIjoiNTc5NzA5ZjQtMWYyMi1jMTMxLWRlMjYtZTc3MGUwNGJhMTJkIiwicGVybWlzc2lvbnMiOnsiYTY0N2U5ODktMWM3ZS00Mzg2LTllYzYtZmE0ZmU2OTA4OTA2IjpbInNjaW06dXNlcjpyZWFkIl19fQ.XNLUF-8IT5Mh411uD0jOb_3aaT5YJrbM6q4PZrOxfbQ
```
After retrieving the JWT, place it in the `Authorization` header with a prefix of `Bearer `. Then you call the API endpoint:
```shell title="Curl example to call API"
curl -XGET -H "Authorization: Bearer eyJhbG..." 'https://local.fusionauth.io/api/scim/resource/v2/Users'
```
## JWT Authentication
When an API is marked with a red key icon such as it means you may call this API without
an API key. Instead, provide a JSON Web Token (JWT). A JWT is obtained from the Login API or an OAuth grant. The token will also be provided as an HTTP Only Session cookie. If cookies are being managed for you by the browser or some
other RESTful client, the JWT cookie will automatically be sent to FusionAuth on your behalf. In this case, you may omit the `Authorization` header.
### Authorization Header Examples
The following example demonstrates the HTTP Authorization header using the `Bearer` scheme.
```properties
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo
```
The following is a curl example using the HTTP Authorization header using the `Bearer` scheme with a line break and spaces for readability.
```shell
curl -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo' \
https://example.fusionauth.io/api/user
```
### Cookie Example
If a cookie is provided on a request to an endpoint which accepts an API key or an JWT, the API key will be preferred.
The following is an HTTP GET request with the JWT Access Token provided as a cookie.
```shell
GET /api/user HTTP/1.1
Cookie: access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo
```
## No Authentication Required
When an API that is marked with a green unlocked icon such as it means that you are not required to provide an `Authorization` header as part of the request. The API is either designed to be publicly accessible or the request may take a parameter that is in itself secure.
## Localhost Authentication Bypass
Some APIs may be authenticated by the source IP address of the request. For example, if `fusionauth-app.local-metrics.enabled` is set to `true`, `/api/prometheus/metrics` and `/api/status` will accept requests from `localhost` without any other form of authentication.
## Managing API Keys
Navigate to Settings -> API Keys to manage API keys.
Create as many API keys as you like, each one may be optionally limited in ability to minimize security risk.
For example, the User API `/api/user` has five HTTP methods, `GET`, `POST`, `PUT`, `PATCH` and `DELETE`. While each API may have different semantics, in a general sense you can think of these HTTP methods as being retrieve, create, update, partial update, and delete respectively. With that in mind, if you'd like to create an API key that can only retrieve users, limit the API key to the `GET` method on the `/api/user` API.
When you create an API key, the key value is defaulted to a secure random value. However, the API key is a string, so you may set it to `super-secret-key`, a UUID such as `02e56c92-f5e1-4b0f-8298-b5103bc7add7`, or any other string value that you'd like. A long and random value makes a good API key because it is unique and difficult to guess, so allowing FusionAuth to create the key value is recommended.
### Managing API Keys via the API
Prior to version `1.26.0`, the FusionAuth administrative user interface was the only way to create API keys. This functionality was not available through an API. Starting from version 1.26.0, API keys may be created using an API. Please refer to the [API Key API](/docs/apis/api-keys) for more information.
### Create an API Key

#### Form Fields
The unique Id of this API key.
The unique string representing the API key. This is what is presented in the `Authorization` header for requests to FusionAuth.
The name of this API key. If the Retrievable selector is set to `Not Retrievable`, this field is required.
An optional description of this API key.
This selector allows you to determine whether or not an API key can be retrieved after it is created.
The possible values are:
* `Retrievable` - The API key can be retrieved after it is created. This is the default setting.
* `Not Retrievable` - The API key cannot be retrieved after it is created. So keep it safe!
If a key is `Not Retrievable` then a Name is required.
The optional tenant to which this API key will be assigned. This value cannot be changed once the API key is created.
When you assign an API key to a tenant, any requests made with this key will only be able to operate on users, applications, groups, and other entities in the selected tenant.
One or more endpoints this API key will be authorized to access.
Selecting no endpoints will **authorize this key for all API endpoints**.
Enable to have this key be a key manager. When a key is a key manager, it can be used to call the [API keys APIs](/docs/apis/api-keys#).
Being able to create other API keys via the API is a **privileged operation**. Use it wisely.
Any attempt to call the API Keys API with a non-manager key (`keyManager` set to `false`) will return a HTTP response status code `401`.
The optional [IP Access Control List](/docs/apis/ip-acl) for restricting the usage of this API key by network address.
The optional date and time at which this API key will expire and no longer be usable for API authentication.
Any attempt to call an API with an expired key will result in a `401` response code.
## API Key Permissions
Each API Key can be granted zero or more endpoint permissions.
Each permission corresponds to an endpoint and an HTTP method.
API keys are limited to the allowed endpoints and HTTP methods.
These permissions are managed via the [API Key API](/docs/apis/api-keys) or in the administrative user interface under the Endpoints section.
When using the administrative user interface, you may click on the HTTP method column or the endpoint row.
Either will toggle all the settings for the column or row, respectively.

For example, if you were to grant an API key `POST` permissions on `/api/user`, the API key would be able to create users in FusionAuth.
Any calls with this API key would be denied access to any other functionality, including listing users, creating applications, and deleting registrations.
Calling other endpoints would result in a `401` response code.
## Tenant Scoped API Keys
When you assign an API key to a tenant, any requests made with this key will only be able to operate on users, applications, groups, and other entities in the selected tenant.
Protect such API keys in the same way you would any other API key.
## Client Side API Keys
## Troubleshooting
# Consents
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import ConsentRequestBody from 'src/content/docs/apis/_consent-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import ConsentResponseBody from 'src/content/docs/apis/_consent-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import ConsentsResponseBody from 'src/content/docs/apis/_consents-response-body.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import ConsentSearchRequestParameters from 'src/content/docs/apis/_consent-search-request-parameters.mdx';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import UserConsentRequestBody from 'src/content/docs/apis/_user-consent-request-body.mdx';
import UserConsentResponseBody from 'src/content/docs/apis/_user-consent-response-body.mdx';
import UserConsentsResponseBody from 'src/content/docs/apis/_user-consents-response-body.mdx';
## Overview
A FusionAuth Consent is a definition of a permission that can be given to a User. At a minimum a consent has a name, and defines the minimum age of self-consent. A consent can then be granted to a User from a family member or optionally a User may self-consent if they meet the minimum age defined by the consent.
The first API allows you to create, delete, update and retrieve a consent. The FusionAuth Consent is the object that defines the consent, the values, minimum ages, etc.
The second API is the User Consent API, this API allows you to grant a User Consent, and update a User Consent. In order to revoke a User Consent you simply need to update the consent status.
[//]: # (Removing Related posts for now)
## Create a Consent
This API is used to create a new Consent.
### Request
#### Request Parameters
The Id to use for the new Consent. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the Consent that was created.
## Retrieve a Consent
This API is used to retrieve a single Consent by unique Id or all of the configured Consents.
### Request
#### Request Parameters
The unique Id of the Consent to retrieve.
### Response
The response for this API contains either a single Consent or all of the Consents. When you call this API with an Id the response will contain a single Consent. When you call this API without an Id the response will contain all of the Consents. Both response types are defined below along with an example JSON response.
## Update a Consent
### Request
#### Request Parameters
The Id to use for the Consent to update.
### Response
The response for this API contains the Consent that was updated.
## Delete a Consent
This API is used to permanently delete a Consent. Deleting a Consent will also permanently delete all granted User Consent. This operation cannot be reversed and it may affect users across multiple tenants.
### Request
#### Request Parameters
The unique Id of the Consent to delete.
### Response
This API does not return a JSON response body.
## Search for Consents
This API is used to search for Consents and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
### Request Body
### Response
The response for this API contains the Consents matching the search criteria in paginated format and the total number of results matching the search criteria.
## Grant a User Consent
This API is used to grant Consent to a User.
### Request
#### Request Parameters
The Id to use for the new User Consent. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the User Consent that was created.
## Retrieve a User Consent
This API is used to retrieve a single User Consent by unique Id or all of User's Consents by user Id.
### Request
#### Request Parameters
The unique Id of the User to retrieve User Consents for.
The unique Id of the User Consent to retrieve.
### Response
The response for this API contains either a single User Consent or all of a User's Consents. When you call this API with an Id the response will contain a single Consent. When you call this API with the `userId` query parameter, the response will contain all of the User's Consents. Both response types are defined below along with an example JSON response.
## Update a User Consent
This API is used to update a consent. Once consent has been granted to a User, only the values and status may be modified.
### Request
#### Request Parameters
The Id of the User Consent to update.
### Response
The response for this API contains the User Consent that was updated.
## Revoke a User Consent
This API is used to revoke a consent. This is equivalent to using the Update User Consent API and modifying the status to `Revoked`.
### Request
### Response
This API does not return a JSON response body.
# Emails
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import EmailTemplateRequestBody from 'src/content/docs/apis/_email-template-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import EmailTemplateResponseBody from 'src/content/docs/apis/_email-template-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import EmailTemplatesResponseBody from 'src/content/docs/apis/_email-templates-response-body.mdx';
import Aside from 'src/components/Aside.astro';
import EmailTemplateSearchRequestParameters from 'src/content/docs/apis/_email-template-search-request-parameters.mdx';
import JSON from 'src/components/JSON.astro';
import EmailTemplateResponseBodyBase from 'src/content/docs/apis/_email-template-response-body-base.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import EmailPreviewResponseBody from 'src/content/docs/apis/_email-preview-response-body.mdx';
import InlineField from 'src/components/InlineField.astro';
import SendResponseBody from 'src/content/docs/apis/_send-response-body.mdx';
## Overview
This page contains the APIs for managing Email Templates as well as emailing users using those templates. Here are the APIs:
## Create an Email Template
This API is used to create an Email Template. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the Email Template. Otherwise, FusionAuth will generate an Id for the Email Template.
### Request
#### Request Parameters
The Id to use for the new Email Template. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the information for the Email Template that was created.
## Retrieve an Email Template
This API is used to retrieve one or all of the configured Email Templates. Specifying an Id on the URI will retrieve a single Email Template. Leaving off the Id will retrieve all of the Email Templates.
### Request
#### Request Parameters
The Id of the Email Template to retrieve.
### Response
The response for this API contains either a single Email Template or all of the Email Templates. When you call this API with an Id the response will contain just that Email Template. When you call this API without an Id the response will contain all of the Email Templates. Both response types are defined below along with an example JSON response.
## Search for Email Templates
This API is used to search for Email Templates and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
#### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
### Response
The response for this API contains the Email Templates matching the search criteria in paginated format.
#### Response Body
## Update an Email Template
### Request
#### Request Parameters
The Id of the Email Template to update.
### Response
The response for this API contains the new information for the Email Template that was updated.
## Delete an Email Template
This API is used to delete an Email Template. You must specify the Id of the Email Template on the URI.
### Request
#### Request Parameters
The Id of the Email Template to delete.
### Response
This API does not return a JSON response body.
## Preview an Email Template
This API is used to preview an Email Template. You simply pass all of the information for the Email Template in the request and a rendered version of the Email is sent back to you in the response. The Email Template in the request does not need to be completely filled out either. You can send in a partial Email Template and the response will contain only what you provided.
### Request
#### Request Body
The default From Name used when sending emails. This is the display name part of the email address ( i.e. **Jared Dunn** jared@piedpiper.com).
The default HTML Email Template.
The default Subject used when sending emails.
The default Text Email Template.
The email address that this email will be sent from. This is the address part email address (i.e. Jared Dunn jared@piedpiper.com).
The From Name used when sending emails to users who speak other languages. This overrides the default From Name based on the user's list of preferred languages.
The HTML Email Template used when sending emails to users who speak other languages. This overrides the default HTML Email Template based on the user's list of preferred languages.
The Subject used when sending emails to users who speak other languages. This overrides the default Subject based on the user's list of preferred languages.
The Text Email Template used when sending emails to users who speak other languages. This overrides the default Text Email Template based on the user's list of preferred languages.
The locale to use when rendering the Email Template. If this is null, the defaults will be used and the localized versions will be ignored.
### Response
The response for this API contains the rendered Email and also an Errors that contains any rendering issues FusionAuth found. The template might have syntax or logic errors and FusionAuth will put these errors into the response.
## Send an Email
This API is used to send an Email to one or more users using an Email Template.
### Request
#### Request Parameters
The Id of the Email Template to use to generate the Email from.
#### Request Body
An optional application Id, when provided the application object will be available in the email template for variable replacement.
A list of email addresses to BCC when sending the Email.
A list of email addresses to CC when sending the Email.
An ordered list of locale strings to utilize when localizing the email template for address provided in the toAddresses. See [Locales](/docs/reference/data-types#locales).
An optional JSON object that is passed to the Email Template during rendering. The variables in the JSON object will be accessible to the FreeMarker templates of the Email Template.
A list of email addresses to send the Email to. It is not required that a user exist in FusionAuth with this email address, this may be useful when sending invitations to users that do not yet exist in FusionAuth.
This field may be used in addition to, or as an alternative to the userIds field.
The email address for the user. Using the toAddresses is optional, but when providing one or more entries, this field is required.
An optional display name that can be used to construct the to address.
For example, in this example string `Erlich Bachman`, `Erlich Bachman` is the display name and `bachman@piedpiper.com` is the address.
The list of User Ids to send the Email to.
This field may be used in addition to, or as an alternative to the toAddresses field.
Prior to version `1.28.0`, this field was required.
### Response
{/* Unset the variables used in this part. */}
# API Errors
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import JSON from 'src/components/JSON.astro';
import InlineField from 'src/components/InlineField.astro';
## API Errors
When FusionAuth encounters an error or finds validation errors in your request, an Errors object is returned in the response body. The Errors object is defined as follows, where fieldName indicates the field in the request body the message is describing and [x] indicates the value is part of an array of one or more values.
### Error Fields
The list of general error messages.
The code of the error message.
A descriptive error message that details the problem that occurred.
The list of field error message.
The list of error messages for that field
The code of the error message.
A descriptive error message that details the problem that occurred.
# Event Logs
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import JSON from 'src/components/JSON.astro';
import InlineField from 'src/components/InlineField.astro';
## Overview
The Event Log contains messages that are not easy to convey to user at runtime - logs and errors from asynchronous code execution. These messages include:
* SMTP transport errors
* Lambda execution exceptions
* Lambda execution console logs
* SAML IdP integration errors and debug
* Webhook event errors
* Runtime exceptions due to email template rendering issues
This page contains the APIs that are used to retrieve Event Logs. Here are the APIs:
## Retrieve an Event Log
### Request
#### Request Parameters
The unique Id of the Event Log to retrieve.
### Response
#### Response Body
The event Log unique Id.
The [instant](/docs/reference/data-types#instants) when the Event Log was created.
The message of the event Log.
The type of the Event Log. Possible values are:
* `Information`
* `Debug`
* `Error`
## Search Event Logs
### Request
When calling the API using a `GET` request you will send the search criteria on the URL using request parameters. In order to simplify the example URL above, not every possible parameter is shown, however using the provided pattern you may add any of the documented request parameters to the URL.
#### Request Parameters
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The string to search in the Event Log message for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Event Log was created
* `insertUser` - the user that create the Event Log
* `message` - the message of the Event Log
* `type` - the type of the Event Log
For example, to order the results by the insert instant in a descending order, the value would be provided as `insertInstant DESC`. The final string is optional can be set to `ASC` or `DESC`.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
The type of Event Logs to return. Only one type may be provided. If omitted, all types will be returned.
The possible values are:
* `Information`
* `Debug`
* `Error`
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The string to search in the Event Log message for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Event Log was created
* `insertUser` - the user that create the Event Log
* `message` - the message of the Event Log
For example, to order the results by the insert instant in a descending order, the value would be provided as `insertInstant DESC`. The final string is optional can be set to `ASC` or `DESC`.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
The type of Event Logs to return. Only one type may be provided. If omitted, all types will be returned.
The possible values are:
* `Information`
* `Debug`
* `Error`
### Response
The response for this API contains the Event Logs matching the search criteria in paginated format.
#### Response Body
The list of Event Logs returned by the search.
The Event Log unique Id.
The [instant](/docs/reference/data-types#instants) when the Event Log was created.
The message of the Event Log.
The type of the Event Log. Possible values are:
* `Information`
* `Debug`
* `Error`
The total number of Event Logs matching the search criteria. Use this value along with the numberOfResults and startRow in the Search request to perform pagination.
# Families
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import FamilyRequestBody from 'src/content/docs/apis/_family-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import FamilyResponseBody from 'src/content/docs/apis/_family-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import FamiliesResponseBody from 'src/content/docs/apis/_families-response-body.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import FamilyPendingResponseBody from 'src/content/docs/apis/_family-pending-response-body.mdx';
import FamilyRequestRequestBody from 'src/content/docs/apis/_family-request-request-body.mdx';
## Overview
A Family allows you to define relationships between one or more Users. A adult User may belong to a single Family, a teen or child may belong to one or more families.
The following APIs are provided to manage Families and Family memberships.
[//]: # (related posts?)
## Add a User to a Family
This API is used to add a User to a Family. You cannot directly create a family, instead a family is implicitly created when the first User is added.
### Request
#### Request Parameters
The Id to use for the new Family. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the Family that was created.
## Retrieve a Family
This API is used to retrieve a Family by a User Id or by Family Id.
### Request
#### Request Parameters
The unique Id of the Family.
### Request
#### Request Parameters
The unique Id of the User.
The response for this API contains the requested family or families.
## Update a Family
This API is used to update an existing Family member. You may only update the User's role or owner status.
### Request
#### Request Parameters
The unique Id of the Family.
### Response
The response for this API contains the Family that was updated.
## Remove a User from a Family
This API is used to remove a User from an existing Family.
### Request
#### Request Parameters
The unique Id of the Family.
The unique Id of the User.
### Response
This API does not return a JSON response body.
## Retrieve Pending Family Members
This API is used to retrieve the users pending parent approval.
### Request
#### Request Parameters
The email address of the parent.
### Response
The response for this API contains the requested pending users.
## Request Parental Approval
This API is used to send an email requesting parental approval for a child registration using the configured `tenant.familyConfiguration.familyRequestEmailTemplateId`.
### Request
### Response
This API does not return a JSON response body.
# Groups
import API from 'src/components/api/API.astro';
import XFusionauthTenantIdHeaderCreateOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-create-operation.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import GroupRequestBody from 'src/content/docs/apis/_group-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import GroupResponseBody from 'src/content/docs/apis/_group-response-body.mdx';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import GroupsResponseBody from 'src/content/docs/apis/_groups-response-body.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import Aside from 'src/components/Aside.astro';
import GroupSearchRequestParameters from 'src/content/docs/apis/_group-search-request-parameters.mdx';
import JSON from 'src/components/JSON.astro';
import MemberRequestBody from 'src/content/docs/apis/_member-request-body.mdx';
import MemberResponseBody from 'src/content/docs/apis/_member-response-body.mdx';
import GroupDeleteMembersByIdRequestBody from 'src/content/docs/apis/_group-delete-members-by-id-request-body.mdx';
import GroupDeleteMembersRequestBody from 'src/content/docs/apis/_group-delete-members-request-body.mdx';
import MembersResponseBodySearch from 'src/content/docs/apis/_members-response-body-search.mdx';
## Overview
A FusionAuth Group is a named object that optionally contains one to many Application Roles.
When a Group does not contain any Application Roles it can still be utilized to logically associate users. Assigning Application Roles to a group allow it to be used to dynamically manage Role assignment to registered Users. In this second scenario as long as a User is registered to an Application the Group membership will allow them to inherit the corresponding Roles from the Group.
The following APIs are provided to manage Groups and Group Membership.
## Create a Group
This API is used to create a new Group.
### Request
#### Request Parameters
The Id to use for the new Group. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the Group that was created.
## Retrieve a Group
This API is used to retrieve a single Group by unique Id or all of the configured Groups.
### Request
#### Request Parameters
The unique Id of the Group to retrieve.
### Response
The response for this API contains either a single Group or all of the Groups. When you call this API with an Id the response will contain a single Group. When you call this API without an Id the response will contain all of the Groups. Both response types are defined below along with an example JSON response.
## Update a Group
### Request
#### Request Parameters
The Id of the Group to update.
### Response
The response for this API contains the Group that was updated.
## Delete a Group
This API is used to permanently delete a Group. Deleting a Group that has Application Roles will effectively modify User Registrations by removing these Roles from Group members.
### Request
#### Request Parameters
The unique Id of the Group to delete.
### Response
This API does not return a JSON response body.
## Search for Groups
This API is used to search for Groups and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
#### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
### Response
The response for this API contains the Groups matching the search criteria in paginated format.
#### Response Body
## Add Users to a Group
This API is used to add Users to a Group. A User that is added to a Group is called a member, a user can belong to one to many Groups.
Adding a User to a Group can be used to logically group users, Group members can be returned by the Search API by searching by the Group Id. Application Roles may also be managed by a Group membership. When a User becomes a member of a Group they will inherit the Application Roles assigned to the Group for their registered Applications. If a User is not registered for an Application the Application Roles for that Application will not be applied to the User.
### Request
### Response
## Update Users in a Group
This API is used to completely replace the existing membership of a Group. Calling this API is equivalent to removing all Users from a Group and then making a `POST` request to the `/api/group/member` to add Users to the Group. Use this API with caution.
### Request
### Response
## Remove Users from a Group
This API is used to remove Users from a Group. Removing a User from a Group removes their Group membership. Removing a User from a Group effectively modifies their assigned Roles if Application Roles are being managed through the Group membership.
### Request
#### Request Parameters
The unique Id of the Group Member to delete.
#### Request Parameters
The unique Id of the Group to remove the User from.
The unique Id of the User to remove from the Group.
#### Request Parameters
The unique Id of the Group.
### Response
This API does not return a JSON response body.
## Search for Group Members
The Group Member Search API allows you to search for Group Members with a paginated response.
### Request
When calling the API using a `GET` request you will send the search criteria on the URL using request parameters. In order to simplify the example URL above, only the `groupId` parameter is shown, however you may add any of the documented request parameters to the URL.
#### Request Parameters
The unique Id of the Group used to search for Group Members.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `groupId` - the unique Id of the Group
* `id` - the id of the Group Member
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Group Member was created
* `userId` - the unique Id of the User
For example, to order the results by the insert instant in descending order, the value would be provided as `insertInstant DESC`. The final string is optional, can be set to `ASC` or `DESC`, or omitted and will default to `ASC`.
Prior to version `1.52.0` this defaults to `insertInstant ASC`.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
The unique Id of the User to search for Group Members. A single user may belong to one or more Groups, so searching on this field may still produce multiple results.
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
The unique Id of the Group used to search for Group Members.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `groupId` - the unique Id of the Group
* `id` - the id of the Group Member
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Group Member was created
* `userId` - the unique Id of the User
For example, to order the results by the insert instant in descending order, the value would be provided as `insertInstant DESC`. The final string is optional, can be set to `ASC` or `DESC`, or omitted and will default to `ASC`.
Prior to version `1.52.0` this defaults to `insertInstant ASC`.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
The unique Id of the User to search for Group Members. A single user may belong to one or more Groups, so searching on this field may still produce multiple results.
### Response
# Hosted Backend
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import API from 'src/components/api/API.astro';
import Aside from 'src/components/Aside.astro';
import HostedBackendResponseCookies from 'src/content/docs/_shared/_hosted-backend-response-cookies.mdx';
import HostedBackendWarning from 'src/content/docs/_shared/_hosted-backend-warning.md';
import InlineField from 'src/components/InlineField.astro';
import OauthAuthorizeRedirectParameters from 'src/content/docs/_shared/_oauth-authorize-redirect-parameters.mdx';
import UserInfoResponse from 'src/content/docs/_shared/_userinfo-response.mdx';
## Overview
The hosted backend APIs provide a pre-built solution for getting your app up and running using the OAuth2 Authorization Code grant with PKCE. We have in the past shown you how to [create these endpoints yourself](/blog/2021/11/11/how-to-authenticate-your-react-app#create-the-express-server) but this solution allows you to get going with your app without writing any backend code. You just need FusionAuth!
## Prerequisites
Be sure to review the [Applications](/docs/get-started/core-concepts/applications#oauth) section of the FusionAuth user guide to ensure proper configuration before using the hosted endpoints.
The hosted backend endpoints will set the following cookies, which are `Secure` and have a `SameSite` value of `Lax`. This follows our [expert advice on client-side storage](/learn/expert-advice/oauth/oauth-token-storage#client-side-storage).
When you are making requests against these endpoints from your JavaScript application, ensure that you are sending cookies as well. The exact syntax varies, but for many frameworks, you must set `withCredentials` to `true` when you make the request.
_Cookies Set By the Hosted Backend_
| Name | HttpOnly | Description |
|------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| app.at | true | The access token for the configured application. This is a JWT and can be presented to your APIs to access data and functionality. |
| app.rt | true | The refresh token for the configured application. Only present if the `offline_access` scope is requested. This can be presented to FusionAuth to retrieve a new access token. |
| app.idt | false | The Id token for the user for the configured application. Only present if the `openid` scope is requested. This is a JWT and can be accessed by JavaScript to display user account information. |
| app.at_exp | false | The UNIX epoch timestamp indicating when the access token will expire. This can be checked by JavaScript to determine when a refresh token should be used to get a new access token. |
FusionAuth will set the domain on these cookies to `.example.com` where `example` is the domain name that FusionAuth is serving from either from the domain or any subdomain, `com` is the top-level domain, and the `.` allows the cookie to match the domain and all subdomains. If the host is a simple host name or IP address FusionAuth will set the domain to that (i.e. `localhost` or `127.0.0.1`). If FusionAuth is on a nested domain, then it will set cookies on the broadest domain that is not a top-level domain.
What this means is that FusionAuth needs to be hosted on the same domain or a subdomain or sibling domain of the application that you intend to use with these endpoints.
For example if your app is on `app.example.com` and FusionAuth is on `auth.example.com` the cookies would be usable by your application. If FusionAuth is on `auth.department.division.example.com` and the app lives on `app.otherdepartment.otherdivision.example.com`, the cookies would still be usable, since the cookies are set on the `example.com` domain.
## Login
This API will start an OAuth2 Authorization Code grant by building a valid request and then redirecting the browser to our `/oauth2/authorize` endpoint. If the user is not logged in the user will be presented with the login page and prompted for credentials before being redirected back to the [Callback](#callback) endpoint.
To use this API, redirect the browser to this route. This is not meant to be called by non-browser clients.
### Request
#### Request Parameters
The client Id for your Application.
The URL encoded URL that the browser will be redirected to at the end of the login flow. If provided, this URL must be included in the Authorized Redirect URLs array for your application. If not provided, the default will be the first value in the Authorized Redirect URLs array configured for your application. This parameter is validated the same as if it were being passed to `/oauth2/authorize`, however when using this endpoint FusionAuth will pass [Callback](#callback) as the redirect_uri to `/oauth2/authorize` as that route will handle the token exchange.
The value of this parameter will be echoed back in the state parameter of the redirect URL at the end of the login flow.
The OAuth2 scope parameter to be passed to the `/oauth2/authorize` endpoint. The format is a URL encoded, space-separated list of scopes (i.e `openid+offline_access` or `openid%20offline_access`).
Available scopes:
* `openid` - This scope is used to request the `app.idt` Id token cookie be returned in the response
* `offline_access` - This scope is used to request the `app.rt` refresh token cookie be returned in the response
Example Request URL
```
https://auth.example.com/app/login/297ca84b-69a9-4508-8649-97644e1d0b3d?redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&state=yourStateData&scope=offline_access
```
### Response
Successful invocations of this route will return a `302` redirect to `/oauth2/authorize`. Other status codes indicate an error.
_Response Codes_
| Code | Description |
|------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | There was an error. The route will serve up an error page with HTML and details on what went wrong. |
| 302 | A successful request will redirect the user to `/oauth2/authorize` to log in. |
| 403 | A forbidden response typically means that the Origin of this request did not pass the FusionAuth CORS filter. Add your app origin to your [CORS Configuration](/docs/operate/secure/cors) as an Allowed Origin. |
| 500 | There was a FusionAuth internal error. A stack trace is provided and logged in the FusionAuth log files. |
## Register
This API will start a registration flow by building a valid request and then redirecting the browser to our `/oauth2/register` endpoint. This endpoint is nearly identical to the [Login](#login) endpoint; however the end result is user registration instead of a login. If the user is not logged in the user will be presented with the registration page and prompted for credentials before being redirected back to the [Callback](#callback) endpoint. If the user is logged in they will be redirected to `/oauth2/authorize` and subsequently to the [Callback](#callback) endpoint.
[Self-service Registration](/docs/get-started/core-concepts/applications#registration) will need to be enabled otherwise this endpoint will redirect to [Login](#login).
To use this API, redirect the browser to this route. This is not meant to be called by non-browser clients.
### Request
#### Request Parameters
The client Id for your Application.
The URL encoded URL that the browser will be redirected to at the end of the registration. If provided, this URL must be included in the Authorized Redirect URLs array for your application. If not provided, the default will be the first value in the Authorized Redirect URLs array configured for your application. This parameter is validated the same as if it were being passed to `/oauth2/register`, however when using this endpoint FusionAuth will pass [Callback](#callback) as the redirect_uri to `/oauth2/register` as that route will handle the token exchange.
The value of this parameter will be echoed back in the state parameter of the redirect URL at the end of the registration flow.
The OAuth2 scope parameter to be passed to the `/oauth2/register` endpoint. The format is a URL encoded, space-separated list of scopes (i.e `openid+offline_access` or `openid%20offline_access`).
Available scopes:
* `openid` - This scope is used to request the `app.idt` Id token cookie be returned in the response
* `offine_access` - This scope is used to request the `app.rt` refresh token cookie be returned in the response
Example Request URL
```
https://auth.example.com/app/register/297ca84b-69a9-4508-8649-97644e1d0b3d?redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&state=yourStateData&scope=offline_access
```
### Response
Successful invocations of this route will return a `302` redirect to `/oauth2/register`. Other status codes indicate an error.
_Response Codes_
| Code | Description |
|------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | There was an error. The route will serve up an error page with HTML and details on what went wrong. |
| 302 | A successful request will redirect the user to `/oauth2/register` to register. |
| 403 | A forbidden response typically means that the Origin of this request did not pass the FusionAuth CORS filter. Add your app origin to your [CORS Configuration](/docs/operate/secure/cors) as an Allowed Origin. |
| 500 | There was a FusionAuth internal error. A stack trace is provided and logged in the FusionAuth log files. |
## Callback
### Request
#### Request Parameters
The client Id for your Application.
The Id of the Tenant that is associated with the Application.
Example Request URL
```
https://auth.example.com/app/callback?code=wJfjafZLvo_KH5-D4r-3YwMmStN3yHoZDGmBivjioz0&locale=en&state=eyJjIjoiODVhMDM4NjctZGNjZi00ODgyLWFkZGUtMWE3&userState=Authenticated&client_id=297ca84b-69a9-4508-8649-97644e1d0b3d&tenantId=e707be45-afa8-4881-9efb-4be7288395d2
```
### Response
A successful response will set cookies and return a `302` redirect to the `redirect_uri` specified in the initial request. Other status codes indicate an error.
_Response Codes_
| Code | Description |
|------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | There was an error. The route will serve up an error page with HTML and details on what went wrong. |
| 302 | A successful request will redirect the user to `redirect_uri` specified in the request or the default Authorized Redirect URL configured for the Application. |
| 500 | There was a FusionAuth internal error. A stack trace is provided and logged in the FusionAuth log files. |
#### Response Cookies
## Refresh
This endpoint will extract the `app.rt` cookie if present and use it to make a `refresh_token` request from `/oauth/token`. The configuration rules for your Application configuration apply; ensure that Refresh token grant is enabled. If successful a new set of cookies will be set on the response that will continue to allow access to the application. You can call this any time or you can review the value of `app.at_exp` and call it when the access token is about to expire.
This API request is made from the client application. The browser must *NOT* be redirected to this endpoint.
### Request
#### Request Parameters
The client Id for your Application.
Example Request URL
```
https://auth.example.com/app/refresh/297ca84b-69a9-4508-8649-97644e1d0b3d
```
### Response
A successful response will set cookies and return a `200`.
_Response Codes_
| Code | Description |
|------|----------------------------------------------------------------------------------------------------------------|
| 200 | There was an error. The route will serve up an error page with HTML and details on what went wrong. |
| 400 | The request was not successful. The client needs to reauthorize. Redirect the browser to the `Login` endpoint. |
| 500 | There was a FusionAuth internal error. A stack trace is provided and logged in the FusionAuth log files. |
#### Response Cookies
## Me
This API is used to retrieve information about the currently logged in user. This call will take the `app.at` cookie value and use that to call the `/oauth2/userinfo` API.
This is an API request made from the client application and the browser must *NOT* be redirected to this endpoint.
### Request
Example Request URL
```
https://auth.example.com/app/me
```
### Response
A successful response will set cookies and return a `302` redirect to the `redirect_uri` specified in the initial request. Other status codes indicate an error.
_Response Codes_
| Code | Description |
|------|----------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. The response will contain a JSON body. |
| 401 | The user is not authorized. Call `Refresh` or redirect the browser to the `Login` endpoint. |
| 500 | There was a FusionAuth internal error. A stack trace is provided and logged in the FusionAuth log files. |
#### Response Body
## Logout
This API will start a logout. The cookies set on [Callback](#callback) or [Refresh](#refresh) will be removed. If an SSO session was started, it will be ended.
To use this API, redirect the browser to this route and the router will respond with a `302` redirect status code. This is not meant to be called by non-browser clients.
### Request
#### Request Parameters
The client Id for your Application.
The URL encoded URL that the browser will be redirected to at the end of the logout flow. This value must be in the Application's Authorized Redirect URLs list. If no `post_logout_redirect_uri` is provided, the user will be redirected to the Logout URL configured for the Application.
Example Request URL
```
https://auth.example.com/app/logout/297ca84b-69a9-4508-8649-97644e1d0b3d?redirect_uri=https%3A%2F%2Fapp.example.com%2
```
### Response
Successful invocations of this route will return a `302` redirect to `/oauth2/logout`. Other status codes indicate an error. After logout the browser is redirected to the defined `redirect_uri`.
_Response Codes_
| Code | Description |
|------|----------------------------------------------------------------------------------------------------------|
| 200 | There was an error. The route will serve up an error page with HTML and details on what went wrong. |
| 302 | A successful request will redirect the user to `/oauth2/logout` to complete the logout. |
| 500 | There was a FusionAuth internal error. A stack trace is provided and logged in the FusionAuth log files. |
# Identity Verify
import API from 'src/components/api/API.astro';
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 JSON from 'src/components/JSON.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
## Overview
The identity verification APIs allow you to manage a workflow for verifying a user's identity. This API is similar to the [Verify Email](/docs/apis/users#verify-a-users-email) API.
An identity verification workflow involves three steps:
1. Starting the verification process, which generates a verification code
2. Delivering the code to a user in a way that is specific to the identity (e.g. sending and email to an email address, or an SMS message to a phone number)
3. Having the user complete the verification workflow by presenting the code
In general you will not need to call these APIs directly, as most of identity verification is handled automatically by FusionAuth. The main verification use cases and the applicability of the API are shown below.
| Use Case | Start API | Send API | Complete API |
|------------------------------------------------------- |:---------:| :--------:|:---------------:|
| **User creation** | Automatic | Automatic | N/A |
| **User update** | Automatic | Automatic | N/A |
| **Hosted Pages - login** | N/A | N/A | Automatic |
| **Hosted Pages - resend verification** | Automatic | Automatic | N/A |
| **Login API** | N/A | N/A | Yes* |
| **Login API - resending verification emails or SMS messages** | Yes | Yes | N/A |
| **Verifying identities before user creation** | Yes | Yes | Yes |
_* You will need to use the Complete API if you want to use `FormField` verification or if you don't want to use FusionAuth's `ClickableLink` page._
## Start Identity Verification
This API allows you to generate a verification code for a User's identity. This code can be sent to the User via email or SMS using the [Send Identity Verification API](#send-identity-verification), or can be delivered by some other method of your choosing. The User will then use this code to complete the verification process. This API can also be used to verify an identity before creating a user.
### Request
#### Request Body
The login identifier of the User identity to begin verification for. The login identifier can be one of the following:
* Email address
* Phone number
The identity type that FusionAuth will use when comparing the loginId. Can be one of the following:
* `email`
* `phoneNumber`
An application Id. If this is not provided and there are multiple tenants, the X-FusionAuth-TenantId header is required.
When this value is provided, it will be used to resolve an application-specific email or message template and make `application` available as a template variable.
If not provided, only the tenant configuration will be used when resolving templates, and `application` will not be available as a template variable.
Whether an existing user that matches loginId is required. Can be one of the following:
* `mustExist` - There must be a user that matches. This is used to verify an existing user's identity.
* `mustNotExist` - There must NOT be a user that matches. This is used to verify an identity of a yet to be created user.
An optional object that will be returned un-modified when you complete verification. This may be useful to return the User to particular state once verification is completed.
The strategy to use when verifying the User. Can be one of the following:
* `ClickableLink` - send the User a code with a clickable link.
* `FormField` - send the User a short code intended to be manually entered into a form field
The default, when `loginIdType` is `email`, is tenant.emailConfiguration.verificationStrategy. When `loginIdType` is `phoneNumber`, the default is tenant.phoneConfiguration.verificationStrategy.
### Response
#### Response Body
The verification Id that was generated by this API request. This identifier should be used by the [Complete Identity Verification](#complete-identity-verification) API and may be used by the [Send Identity Verification](#send-identity-verification) API.
The verification One Time Code is used with the gated Email or Phone Verification workflow. The User enters this code to verify their email or phone number when the `ClickableLink` strategy is not in use.
## Send Identity Verification
This API allows you to send a verification code, previously generated by the [Start Identity Verification API](#start-identity-verification), to a User via email or SMS. This is typically used to notify the User that they need to verify their identity.
If the `verificationId` was generated for:
* an email identity - the message will be sent via email using the SMTP settings for the user's tenant and the message template defined by tenant.emailConfiguration.verificationEmailTemplateId
* a phone number identity - the message will be sent via SMS using the message template defined by tenant.phoneConfiguration.verificationTemplateId and the messenger defined by tenant.phoneConfiguration.messengerId
### Request
#### Request Body
The verification Id that was generated by the start API.
### Response
This API does not return a JSON response body.
## Complete Identity Verification
This API allows you to complete the identity verification process by providing the verification code sent to the User. If the code is valid, the User's identity will be verified and user.identities\[x].verifiedReason will be set to `Completed`.
### Request
#### Request Body
The verification Id generated by the [Start Identity Verification API](#start-identity-verification), used to verify the User's identity is valid by ensuring they have access to the provided email address or phone number.
When using the `FormField` strategy for verification, this value is used along with the `oneTimeCode` as a pair to perform verification.
The short code used to verify the User's account is valid by ensuring they have access to the provided email address or phone number. This field is required when the verification strategy is `FormField`.
### Response
#### Response Body
If state was provided during the [Start Identity Verification API](#start-identity-verification) request, this value will be returned exactly as it was provided.
# API Overview
import NullWarning from 'src/content/docs/apis/_null_warning.mdx';
import JSON from 'src/components/JSON.astro';
import TroubleshootingApiCalls from 'src/content/docs/_shared/_troubleshooting-api-calls.mdx';
import NewApiKey401 from 'src/content/docs/apis/_new-api-key-401.mdx';
import { YouTube } from '@astro-community/astro-embed-youtube';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
The core of FusionAuth is a set of RESTful APIs that allow you to quickly integrate login, registration and advanced User management features into your application. The FusionAuth web UI is built upon these APIs. Everything in the user interface is available through an API.
On this page you will find links to each of the API groups and a general overview of the API status codes you can expect back from each API. Each API will also document specific status codes and the specific meaning of the status code.
* [API Authentication](/docs/apis/authentication)
* [API Errors](/docs/apis/errors)
* [API Status Codes](#status-codes)
Here's a brief video showing how to use an API:
## APIs
Unless stated otherwise, all of the FusionAuth APIs will expect to receive a JSON request body. Ensure you have added the `Content-Type` HTTP header to your request.
```plaintext options="wrap" title="Content-Type Header"
Content-Type: application/json
```
The APIs are grouped into the following categories.
* [Actioning Users](/docs/apis/actioning-users) - These APIs allow you to take actions on Users or modify previous actions (CRUD operations).
* [API Keys](/docs/apis/api-keys) - These APIs allow you to take actions on API Keys or modify existing API Keys (CRUD operations).
* [Applications](/docs/apis/applications) - These APIs allow you to create, retrieve, update and delete Applications and Application Roles
* [Audit Logs](/docs/apis/audit-logs) - These APIs allow you to create, retrieve, search and export the Audit Log.
* [Connectors](/docs/apis/connectors/) - These APIs allow you to manage Connectors (CRUD operations).
* [Consents](/docs/apis/consents) - These APIs allow you to manage Consent (CRUD operations).
* [Emails](/docs/apis/emails) - These APIs allow you to both manage Email Templates (CRUD operations) as well as send emails to Users.
* [Entities](/docs/apis/entities/entities) - These APIs allow you to manage Entities (CRUD operations) as well as search and grant permissions to them.
* [Entity Types](/docs/apis/entities/entity-types) - These APIs allow you to manage Entity Types.
* [Event Logs](/docs/apis/event-logs) - These APIs allow you to retrieve and search event logs.
* [Families](/docs/apis/families) - These APIs allow you to manage Families (CRUD operations).
* [Forms](/docs/apis/custom-forms/forms) - These APIs allow you to manage Forms (CRUD operations).
* [Form Fields](/docs/apis/custom-forms/form-fields) - These APIs allow you to manage Form Fields (CRUD operations).
* [Groups](/docs/apis/groups) - These APIs allow you to manage Groups (CRUD operations) as well Group membership.
* [Hosted Backend](/docs/apis/hosted-backend) - These APIs allow you initiate OAuth2 code flow logins with FusionAuth-hosted backend endpoints.
* [Identity Providers](/docs/apis/identity-providers/) - These APIs allow you to manage Identity Providers for federating logins.
* [Identity Verify](/docs/apis/identity-verify) - These APIs allow you to manage identity verification, including starting, sending and completing identity verification.
* [Integrations](/docs/apis/integrations) - These APIs allow you to manage FusionAuth integrations such as Kafka, Twilio and CleanSpeak.
* [IP Access Control Lists](/docs/apis/ip-acl) - These APIs allow you to manage IP Access Control Lists.
* [JSON Web Tokens](/docs/apis/jwt) - These APIs allow you to manage Refresh Tokens, verify Access Tokens and retrieve public keys used for verifying JWT signatures.
* [Keys](/docs/apis/keys) - These APIs allow you to manage cryptographic keys (CRUD operations).
* [Lambdas](/docs/apis/lambdas) - These APIs allow you to manage Lambdas (CRUD operations).
* [Login](/docs/apis/login) - These APIs allow you to authenticate Users.
* [Messengers](/docs/apis/messengers/) - These APIs allow you to manage Messengers (CRUD operations).
* [Multi-Factor](/docs/apis/two-factor) - This API allows you to enable and disable Multi-Factor Authentication (MFA) on a user.
* [Passwordless](/docs/apis/passwordless) - These APIs allow you to authenticate Users without a password.
* [Registrations](/docs/apis/registrations) - These APIs allow you to manage the relationship between Users and Applications, also known as Registrations (CRUD operations).
* [Reactor](/docs/apis/reactor) - These APIs allow you to manage licensing features.
* [Reports](/docs/apis/reports) - These APIs allow you to retrieve reporting information from FusionAuth.
* [SCIM](/docs/apis/scim/) - These APIs allow you to provision users and groups in FusionAuth using SCIM requests from a SCIM Client.
* [System](/docs/apis/system) - These APIs allow you to retrieve and update the system configuration, export system logs and retrieve system status.
* [Tenants](/docs/apis/tenants) - These APIs allow you to manage Tenants (CRUD operations).
* [Themes](/docs/apis/themes) - These APIs allow you to manage Themes (CRUD operations).
* [Users](/docs/apis/users) - These APIs allow you to create, retrieve, update and delete Users, Search for Users, Bulk Import and Password Management
* [User Actions](/docs/apis/user-actions) - These APIs allow you to manage User Actions which are the definitions of actions that can be taken on Users (CRUD operations).
* [User Action Reasons](/docs/apis/user-action-reasons) - These APIs allow you to manage User Action Reasons which are used when you action Users (CRUD operations).
* [User Comments](/docs/apis/user-comments) - These APIs allow you to retrieve or create comments on Users.
* [WebAuthn](/docs/apis/webauthn) - These APIs allow you to register, use, and manage WebAuthn passkeys.
* [Webhooks](/docs/apis/webhooks) - These APIs allow you to manage Webhooks (CRUD operations).
## Status Codes
Each API may document specific status codes and provide a specific reason for returning that status code. This is a general overview of the status codes you may expect from an API and what they will mean to you.
_Response Codes_
| Code | Description |
|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. Generally the response body will contain JSON unless documented otherwise. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | The request authentication failed. This request requires authentication and the API key was either omitted or invalid. In some cases this may also be returned if you are not authorized to make the request. See [Authentication](/docs/apis/authentication) for additional information on API authentication. |
| 404 | The object you requested doesn't exist. The response will be empty. |
| 405 | The HTTP method you requested is not allowed for the URI. This is a user error in making the HTTP request to the API. For example, if `POST` is the only supported way to call a particular API and you make the HTTP request with `GET`, you will receive a `405` status code. No body will be returned. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. This is generally a FusionAuth error condition. If possible open a [GitHub Issue](https://github.com/FusionAuth/fusionauth-issues/issues) so we can help you resolve the issue. |
| 501 | The HTTP method you requested is not implemented. This is a user error in making the HTTP request to the API. |
| 503 | The requested action cannot be completed due the current rate of requests. Retry the request later. |
| 512 | A lambda invocation failed during this API request. An event log will have been created with details of the exception. See System -> Event Log. |
## The PATCH HTTP Method
There are three options for using `PATCH` operations. You choose between them by specifying a particular `Content-Type` on the request.
_PATCH options_
| Name | Content-Type | Array Behavior | Available Since | RFC Link | Client Library Support | Notes |
|------------------|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------|-----------------|----------------------------------------------------|------------------------|---------------------------------------------------------------------------|
| Original | `application/json` | Varies, sometimes a merge, other times an append. Read the documentation and test before using. Safest option is `GET` then `PUT`. | 1.12.0 | N/A | Yes | May be deprecated in the future. |
| JSON Patch | `application/json-patch+json` | Uses operations to specify JSON modifications. | 1.39.0 | [RFC 6902](https://www.rfc-editor.org/rfc/rfc6902) | No | [Useful patch builder tool](https://json-patch-builder-online.github.io/) |
| JSON Merge Patch | `application/merge-patch+json` | If target value is an array, overwrite the existing value with what is provided. | 1.39.0 | [RFC 7396](https://www.rfc-editor.org/rfc/rfc7396) | No | N/A |
### PATCH Example
Here's an example of how the different options work when used to modify the roles of a [Group](/docs/apis/groups) which has roles of `ceo` and `dev` to remove the `dev` role.
If you are only modifying specific object fields, all three `PATCH` methods are equivalent.
#### Original
With the original, pre 1.39.0 `PATCH` method, the correct way to remove the `dev` role is to request the group JSON, find the `ceo` role from the `roleIds` array, and use `PUT` to update the group object.
```json title="PUT Request JSON"
{
"group": {
"name": "Paid employees",
"data": {}
},
"roleIds": [
"0a15cfdd-e231-4de4-9411-6d1015e05d99"
]
}
```
After you make this `PUT` request, the group JSON will look like this.
#### JSON Patch
With JSON Patch, you have a flexible set of operations that can update, remove or move fields in a JSON object. Please review [RFC 6902](https://www.rfc-editor.org/rfc/rfc6902) for the full list of operations. Here's the original JSON again:
If you make a `PATCH` request with a `Content-Type` of `application/json-patch+json` and a body like below:
```json title="JSON Patch Request JSON"
[
{
"op": "remove",
"path": "/roleIds/1"
}
]
```
This call removes the second value of the `roleIds` array, which corresponds to the "devs" role. You'll need to find what array element you want to delete, perhaps with a separate request. After you make this `PATCH` request, the group JSON will look like this.
This approach is precise and can make multiple changes to a given object with one call. It also requires you to learn a new set of operations. Additionally, the data is sent in format (an array of operations) which is only vaguely related to the structure of the object being changed.
#### JSON Merge Patch
JSON Merge Patch is a more straightforward way to update complex JSON objects. Please review [RFC 7386](https://www.rfc-editor.org/rfc/rfc7386) for a full description of the patch behavior. Here's the original JSON again:
If you make a `PATCH` request with a `Content-Type` of `application/merge-patch+json` and a body like below:
```json title="JSON Patch Request JSON"
{
"roleIds": [
"0a15cfdd-e231-4de4-9411-6d1015e05d99"
]
}
```
After you make this `PATCH` request, the group JSON will look like this.
## Exploring The APIs
You can explore our APIs using a self hosted instance, one you run yourself on a remote server, or using the [Sandbox](https://sandbox.fusionauth.io).
You can use our [API explorer](/docs/apis/api-explorer) or our [Postman collection](https://www.postman.com/fusionauth).
## Backwards Compatibility
FusionAuth strives to maintain backwards compatibility when making changes to APIs and features. Occasionally, FusionAuth will deprecate APIs or features in preparation for removal. Please see our [Deprecation Policy](/docs/operate/roadmap/deprecation-policy) for more.
## Troubleshooting
### 401s With New API Keys
# Integrations
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import IntegrationResponseBody from 'src/content/docs/apis/_integration-response-body.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import IntegrationRequestBody from 'src/content/docs/apis/_integration-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
## Overview
This page contains the APIs that are used for retrieving and updating integrations. An integration is a third party API that has been integrated into FusionAuth. These APIs are used to enable and configure these third party integration.
## Retrieve Integrations
This API is used to retrieve integrations.
### Request
### Response
The response for this API contains the Integrations.
## Update Integrations
### Request
### Response
The response for this API contains Integrations.
# IP Access Control Lists
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import IpAclRequestBody from 'src/content/docs/apis/_ip-acl-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import IpAclResponseBody from 'src/content/docs/apis/_ip-acl-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import IpAclResponseBodySearch from 'src/content/docs/apis/_ip-acl-response-body-search.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
## Overview
An IP ACL (Access Control List) is a list of IP ranges that are either Allowed or Blocked. Along with one entry that defines a start IP address of `*` (wild) that defines the default behavior when an IP address does not match any other range in the list. This means an IP ACL will have a default action of either Allow or Block. The IP address start and end entries for ranges currently only support IPv4.
An IP ACL may be assigned to an API Key, a Tenant or an Application.
When an IP ACL is assigned to an API key, the IP ACL will restrict the usage of the API key based upon the request originating IP address. If a request is made using an API key with an assigned IP ACL and the IP address is found to be blocked, a 401 status code will be returned. The user of this API key will not be able to tell the difference between an invalid API key and an API key that is blocked due to the IP ACL.
When an IP ACL is assigned to a Tenant or Application, it is used to restrict access to the FusionAuth SSO. This means it will be used to restrict access to endpoints that begin with `/oauth2/`, `/account/`, `/email/`, `/password/`, `/registration/` and any other user accessible themed pages. It will not be used to restrict access to the FusionAuth admin UI except when accessed through SSO, or the FusionAuth API.
If two IP ACLs are assigned one to a Tenant and the other to an Application, the Application IP ACL will take precedence.
The IP address used to test against the IP ACL is resolved by using the first value in the `X-Forwarded-For` HTTP header. If this header is not found, then the IP address reported by the HTTP Servlet request as the remote address will be used. If you are accessing FusionAuth through a proxy it is important that you trust your edge proxy to set the correct value in the `X-Forwarded-For` HTTP header. Because this header can be set by any HTTP client, it is only secure or trustworthy when managed by a trusted edge proxy. You should not rely upon this feature alone to restrict access to an API key.
The following APIs are provided to manage IP ACLs.
## Create an IP ACL
This API is used to create a new IP ACL.
### Request
#### Request Parameters
The Id to use for the new IP ACL. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the IP ACL that was created.
## Retrieve an IP ACL
This API is used to retrieve a single IP ACL by unique Id.
### Request
#### Request Parameters
The unique Id of the IP ACL to retrieve.
### Response
## Search for IP ACLs
### Request
When calling the API using a `GET` request you will send the search criteria on the URL using request parameters. In order to simplify the example URL above, only the IP ACL specific parameter is shown, however you may add any of the documented request parameters to the URL.
#### Request Parameters
The string to match all or part of the IP ACL name. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `id` - the id of the IP ACL
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the IP ACL was created
* `lastUpdateInstant` - the last [instant](/docs/reference/data-types#instants) that the IP ACL was updated
* `name` - the name of the IP ACL
For example, to order the results by the insert instant in descending order, the value would be provided as `insertInstant DESC`. The final string is optional, can be set to `ASC` or `DESC`, or omitted and will default to `ASC`.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
The string to match all or part of the IP ACL name. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `id` - the id of the IP ACL
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the IP ACL was created
* `lastUpdateInstant` - the last [instant](/docs/reference/data-types#instants) that the IP ACL was updated
* `name` - the name of the IP ACL
For example, to order the results by the insert instant in descending order, the value would be provided as `insertInstant DESC`. The final string is optional, can be set to `ASC` or `DESC`, or omitted and will default to `ASC`.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
### Response
The response for this API contains the IP ACLs matching the search criteria in paginated format.
## Update an IP ACL
### Request
#### Request Parameters
The Id of the IP ACL to update.
### Response
The response for this API contains the IP ACL that was updated.
## Delete an IP ACL
This API is used to permanently delete an IP ACL. Deleting an IP ACL will remove it from any tenants and/or applications it was assigned. Delete will fail with a validation error if the IP ACL is still in use.
### Request
#### Request Parameters
The unique Id of the IP ACL to delete.
### Response
This API does not return a JSON response body.
# JWTs & Refresh Tokens
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import InlineField from 'src/components/InlineField.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import ExternalJwtProviderWarning from 'src/content/docs/_shared/_external-jwt-provider-warning.mdx';
import XFusionauthTenantIdHeaderScopedOperationRowOnly from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation-row-only.mdx';
import ReconcileRequestBody from 'src/content/docs/apis/_reconcile-request-body.mdx';
import UserResponseBody from 'src/content/docs/apis/_user-response-body.mdx';
import Aside from 'src/components/Aside.astro';
import JSON from 'src/components/JSON.astro';
import RefreshTokenResponseBody from 'src/content/docs/apis/_refresh-token-response-body.mdx';
import RefreshTokensResponseBody from 'src/content/docs/apis/_refresh-tokens-response-body.mdx';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import { YouTube } from '@astro-community/astro-embed-youtube';
## Overview
JSON Web Tokens (JWTs) are portable identity tokens. A JWT is issued after completing a [Login](/docs/apis/login#authenticate-a-user) request and is used to identify a user. JWTs can be used to call various FusionAuth APIs or they can be used to authenticate and authorize your APIs. In this document the term JWT and access token are used interchangeably.
Here's a presentation discussing how to use JWTs in a microservices architecture:
## Issue a JWT
This API is used to issue a new access token (JWT) using an existing access token (JWT).
This API provides the single sign-on mechanism for access tokens. For example you have an access token for application A and you need an access
token for application B. You may use this API to request an access token to application B with the authorized token to application A. The returned access token will have the same expiration of the one provided.
This API will use a JWT as authentication. See [JWT Authentication](/docs/apis/authentication#jwt-authentication) for examples of how you can send the JWT to FusionAuth.
### Request
#### Request Parameters
The Id of the application for which authorization is being requested.
An existing refresh token used to request a refresh token in addition to a JWT in the response. If the cookie `refresh_token` is also on the request it will take precedence over this value.
The target application represented by the applicationId request parameter must have refresh tokens enabled in order to receive a refresh token in the response.
#### Request Cookies
The refresh token to be used to exchange for a refresh token in the application represented by the applicationId request parameter.
```shell title="Example HTTP Request using cookie"
GET /api/jwt/issue HTTP/1.1
Cookie: refresh_token=xRxGGEpVawiUak6He367W3oeOfh+3irw+1G1h1jc
```
### Response
#### Response Body
The encoded access token.
The refresh token. This value will only be returned if a valid non-expired refresh token was provided on the request and application.loginConfiguration.generateRefreshTokens is `true`. The returned refresh token will share the same creation time as the original refresh token in regards to how the token expiration is calculated.
The refresh token expiration policy as defined by jwtConfiguration.refreshTokenExpirationPolicy must be the same as the source application, if the policies are different a refresh token will not be returned.
## Reconcile a JWT Using the External JWT Provider
The Reconcile API is used to take a JWT issued by a third party identity provider as described by an [External JWT Identity Provider](/docs/apis/identity-providers/external-jwt/)
configuration and reconcile the User represented by the JWT to FusionAuth.
### Request
#### Request Headers
The IP address of a client requesting authentication. If the IP address is provided it will be stored for login history of the user. It is
generally preferred to specify the IP address in the request body. If it is not provided in the request body this header value will be used
if available, the request body value will take precedence.
### Response
The response for this API contains the User object.
_Response Codes_
| Code | Description |
|------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The reconcile was successful. The response will contain the User object that was authenticated. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | The request cannot be completed. The `identityProviderId` is invalid, the JWT signature cannot be validated, the JWT does not contain a claim identified by the `uniqueIdentityClaim` property in the Identity Provider configuration, or the domain of the email address claim in the JWT is not managed by the Identity Provider Configuration. |
| 404 | The user was not found or the password was incorrect. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
#### Response Cookies
The encoded access token. This cookie is written in the response as an `HttpOnly` session cookie.
The refresh token. This cookie is written in the response as an `HttpOnly` persistent cookie. The cookie expiration is configured in the JWT
configuration for the application or the global JWT configuration.
## Retrieve Public Keys
This API is used to retrieve Public Keys generated by FusionAuth. These can be used to cryptographically verify JWTs signed with the corresponding private key.
### Request
#### Request Parameters
The Application Id is used to retrieve a specific Public Key. This will return the Public Key that has been specifically configured for the provided Application to sign the access token.
A public key may not be available for an Application if it is configured to use the global JWT configuration or a HMAC is the configured algorithm for JWT signing.
#### Request Parameters
The Key Id used to retrieve a specific Public Key. This will return the Public Key associated with the Key Id.
### Response
#### Response Body
The public keys keyed by the kid.
#### Response Body
The public key configured for the specified Application.
## Refresh a JWT
This can be used to extend a centrally managed session when a refresh token represents a user session. [Learn more about using refresh tokens to model sessions](/docs/lifecycle/authenticate-users/logout-session-management).
### Request
The refresh token may be provided either in the HTTP request body or as a cookie. If both are provided, the cookie will take precedence.
#### Request Cookies
The refresh token to be used to obtain a new access token.
This value is required but optional as a cookie. It must be provided in either the request body or as a cookie.
The previously issued encoded access token. When provided on the request, this value will be relayed in the related JWT Refresh webhook event within the `original` field.
#### Request Body
The refresh token to be used to obtain a new access token.
This value is required but optional in the request body. It must be provided in either the request body or as a cookie.
The previously issued encoded access token. When provided on the request, this value will be relayed in the related JWT Refresh webhook event within the `original` field.
The time to live for the new access token.
When provided on the request, this value will override the default TTL, provided it is less than the default value. The default TTL is taken from application.jwtConfiguration.timeToLiveInSeconds if it is set there, otherwise it is taken from tenant.jwtConfiguration.timeToLiveInSeconds.
```shell title="Example POST HTTP Request containing Cookie Header"
POST /api/jwt/refresh HTTP/1.1
Cookie: refresh_token=xRxGGEpVawiUak6He367W3oeOfh+3irw+1G1h1jc; access_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkFuYV91STRWbWxiMU5YVXZ0cV83SjZKZFNtTSJ9.eyJleHAiOjE1ODgzNTM0NjAsImlhdCI6MTU4ODM1MzQwMCwiaXNzIjoiZnVzaW9uYXV0aC5pbyIsInN1YiI6IjAwMDAwMDAwLTAwMDAtMDAwMS0wMDAwLTAwMDAwMDAwMDAwMCIsImF1dGhlbnRpY2F0aW9uVHlwZSI6IlBBU1NXT1JEIiwiZW1haWwiOiJ0ZXN0MEBmdXNpb25hdXRoLmlvIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInByZWZlcnJlZF91c2VybmFtZSI6InVzZXJuYW1lMCJ9.ZoIHTo3Pv0DpcELeX_wu-ZB_rd988jefZc2Ozu9_p59kttwqMm5PV8IDbgxJw9xcq9TFoNG8e_B6renoc11JC54UbiyeXBjF7EH01n9LDz-zTGqu9U72470Z4E7IPAHcyvJIBx4Mp9sgsEYAUm9Tb8ChudqNHhn6ZnXYI7Sew7CtGlu62f10wdBYGX0soYARHBv9CwhJC3-gsD2HLmqHAP_XhrpaYPNr5EAvmCHlM-JlTiEQ9bXwSc4gv-XbPQWamwy8Kcdb-g0EEAml_dC_b2CduwwYg0EoPQB3tQxzTUQzADi7K6q0CtQXv2_1VrRi6aQ4lt7v7t-Na39wGry_pA
```
### Response
#### Response Body
The refresh token.
When jwtConfiguration.refreshTokenUsagePolicy is equal to `Reusable` this will be equal to the refresh token provided in the request. When jwtConfiguration.refreshTokenUsagePolicy is equal to `OneTimeUse` a new value will be returned and the previous refresh token value will no longer be valid.
The jwtConfiguration.refreshTokenUsagePolicy is configured at the tenant, and optionally per application.
This unique Id is the persistent identifier for this refresh token, and will not change even when using one-time use refresh tokens. This value may optionally be used to revoke the token using the [Refresh Token API](/docs/apis/jwt#revoke-refresh-tokens).
The encoded access token.
#### Response Cookies
The encoded access token. This cookie is written in the response as an `HttpOnly` session cookie.
The encoded refresh token.
This cookie is written in the response as an `HttpOnly` cookie. When jwtConfiguration.refreshTokenUsagePolicy is equal to `Reusable` this will be equal to the refresh token provided in the request. When jwtConfiguration.refreshTokenUsagePolicy is equal to `OneTimeUse` a new value will be returned and the previous refresh token value will no longer be valid.
The jwtConfiguration.refreshTokenUsagePolicy is configured at the tenant, and optionally per application.
## Retrieve Refresh Tokens
This can be used to examine a centrally managed session when the refresh token represents a user session. [Learn more about using refresh tokens to model sessions](/docs/lifecycle/authenticate-users/logout-session-management).
### Request
#### Request Parameters
The Id of the token.
### Response
#### Request Parameters
The Id of the user for whom to retrieve issued Refresh Tokens.
### Response
## Revoke Refresh Tokens
This can be used to revoke a centrally managed session, when the refresh token is being used to model a session. [Learn more about using refresh tokens to model sessions](/docs/lifecycle/authenticate-users/logout-session-management).
### Request
#### Request Parameters
The Id of the application to revoke all issued Refresh Tokens. This will result in any user issued a Refresh Token for this application being required to be issued a new Refresh Token, in other words they'll need to be authenticated again.
This essentially provides a kill switch for all Refresh Tokens scoped to the application.
#### Request Parameters
The Id of the user to revoke issued Refresh Tokens.
#### Request Parameters
The Id of the application.
The Id of the user.
This API may be authenticated using a JWT or an API key. If using JWT authentication, the JWT owner and token owner must match. See [Authentication](/docs/apis/authentication) for examples of authenticating using a JWT.
#### Request Parameters
The Id of the refresh token to be revoked.
When deleting a single token, using this parameter is recommended. Using this parameter does not expose the refresh token.
This API may be authenticated using a JWT or an API key. If using JWT authentication, the JWT owner and token owner must match. See [Authentication](/docs/apis/authentication) for examples of authenticating using a JWT.
#### Request Parameters
The refresh token in string form that is to be revoked. This string may contain characters such as a plus sign that need to be encoded to be valid on the URL. If you're manually building this request ensure you are properly URL encoding this value.
You can also pass the refresh token in the HTTP body by specifying a Content-Type header of `application/x-www-form-urlencoded` and providing the proper URL encoded value for the parameter. This will prevent the refresh token from being written to HTTP access logs.
If possible, it is recommended use the tokenId parameter rather than this one.
### Response
This API does not return a JSON response body.
## Validate a JWT
This API is used to validate a JSON Web Token. A valid JWT indicates the signature is valid and the payload has not be tampered with and the token is not expired.
You can also validate a JWT without using this API call. To do so, validate the JWT attributes and signature locally. Many programming languages have libraries to do this. Here's an [example in Java](https://github.com/fusionauth/fusionauth-jwt#verify-and-decode-a-jwt-using-hmac).
### Request
The access token can be provided to the API using an HTTP request header, or a cookie. The response body will contain the decoded JWT payload.
#### Request Headers
The encoded JWT to validate sent in on the Authorization request header.
The header is expected be in the following form: `Authorization: Bearer [encoded_access_token]`.
See [Authentication](/docs/apis/authentication) for additional examples.
#### Request Cookies
The encoded JWT. This cookie is written to the client by the Login API.
_Response Codes_
| Code | Description |
|------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. The response will contain a JSON body. |
| 401 | The access token is not valid. A new access token may be obtained by authentication against the Login API, the Token Endpoint or by utilizing a Refresh Token. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
#### Response Body
The decoded JWT payload. The payload contains the identity claims for the user.
## Vend a JWT
This API is used to create a free-form access token (JWT) with claims defined by the caller. The only "reserved" claims that cannot be specified are `amr`, `exp` and `iat`. The `iat` claim is the issued at time of the JWT and the `exp` is the expiration time of the JWT as computed by adding to the `iat` value either the user passed timeToLiveInSeconds or the tenant JWT timeToLiveInSeconds. If a reserved claim is passed into the claims object, it will be ignored.
Here's a video showing how to use this feature.
### Request
#### Request Body
A set of claims to add to this JWT. If any of the "reserved" claims, `exp` or `iat`, are specified they will be ignored. Otherwise, the claims can be any valid JSON value.
The Id of the signing key to use when signing this JWT. If this is not supplied, the tenant's JWT access token signing key will be used.
The length of time in seconds before the JWT expires and is no longer valid. Any integer value greater than `0` is allowed. If omitted, the tenant's timeToLiveInSeconds value will be used instead.
### Response
#### Response Body
The encoded access token.
# Keys
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import KeyResponseBody from 'src/content/docs/apis/_key-response-body.mdx';
import KeyResponsesBody from 'src/content/docs/apis/_key-responses-body.mdx';
import UpdateKeyNote from 'src/content/docs/_shared/_update-key-note.mdx';
import KeyPutRequestBody from 'src/content/docs/apis/_key-put-request-body.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import KeySearchRequestParameters from 'src/content/docs/apis/_key-search-request-parameters.mdx';
import KeyGeneratePostRequestBody from 'src/content/docs/apis/_key-generate-post-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import KeyImportPostRequestBody from 'src/content/docs/apis/_key-import-post-request-body.mdx';
## Overview
Cryptographic keys are used in signing and verifying JWTs and verifying responses for third party identity providers. It is more likely you will interact with keys using the FusionAuth UI in the Key Master menu. If you do have a need to retrieve or manage keys using the API the following APIs have been provided.
## Retrieve a Key
This API is used to retrieve a single Key by unique Id or all of the configured Keys.
### Request
#### Request Parameters
The unique Id of the Key to retrieve.
### Response
The response for this API contains either a single Key or all of the Keys. When you call this API with an Id the response will contain a single Key. When you call this API without an Id the response will contain all of the Keys. Both response types are defined below along with an example JSON response.
## Update a Key
This API method is used to update an existing Key.
### Request Parameters
The unique Id of the Key to update.
### Response
The response for this API contains the Key that was updated.
## Delete a Key
This API is used to delete a Key.
### Request Parameters
The unique Id of the Key to delete.
### Response
This API does not return a JSON response body.
## Search for Keys
This API is used to search for Keys and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
### Request Body
### Response
The response for this API contains the Keys matching the search criteria in paginated format and the total number of results matching the search criteria.
## Generate a Key
This API is used to generate a new Key.
### Request Parameters
The Id to use for the new key. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the Key that was generated.
## Import a Key
This API is used to import an existing Key into FusionAuth.
For RSA pairs, possible key lengths are: `1024` (only valid when importing a public key for signature verification), `2048`, `3072` or `4096`.
For EC pairs, possible key lengths are: `256`, `384`, or `521`.
### Request Parameters
The unique Id of the Key. Use if you want to specify a known UUID. This is useful if you are migrating from an existing system or will otherwise depend on having a known key Id.
### Response
The response for this API contains the Key that was imported.
# Lambdas
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import LambdaRequestBody from 'src/content/docs/apis/_lambda-request-body.mdx';
import LambdaRequestBodySuffix from 'src/content/docs/apis/_lambda-request-body-suffix.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import LambdaResponseBody from 'src/content/docs/apis/_lambda-response-body.mdx';
import LambdaResponseBodySuffix from 'src/content/docs/apis/_lambda-response-body-suffix.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import LambdaResponsesBody from 'src/content/docs/apis/_lambda-responses-body.mdx';
import LambdaResponsesBodySuffix from 'src/content/docs/apis/_lambda-responses-body-suffix.mdx';
import LambdaSearchRequestParameters from 'src/content/docs/apis/_lambda-search-request-parameters.mdx';
import JSON from 'src/components/JSON.astro';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import LambdaPutRequestBody from 'src/content/docs/apis/_lambda-put-request-body.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import LambdaType from 'src/content/docs/apis/_lambda-type.astro';
export const singlePrefix = 'lambda.';
export const multiPrefix = 'lambda[x].';
## Overview
Lambdas are user defined JavaScript functions that may be executed at runtime to perform various functions. Lambdas may be used to customize the claims returned in a JWT, reconcile a SAML v2 response or an OpenID Connect response when using these external identity providers.
## Create a Lambda
This API is used to create a Lambda.
### Request Parameters
The Id to use for the new Lambda. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the Lambda that was created.
## Retrieve a Lambda
This API is used to retrieve a single Lambda by unique Id or all of the Lambdas.
### Request
#### Request Parameters
#### Request Parameters
The unique Id of the Lambda to retrieve.
### Response
The response for this API contains either a single Lambda or all of the Lambdas. When you call this API with an Id the response will contain a single Lambda. When you call this API without an Id the response will contain all of the Lambdas. Both response types are defined below along with an example JSON response.
## Search for Lambdas
This API is used to search for Lambdas and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
#### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
### Response
The response for this API contains the Lambdas matching the search criteria in paginated format.
## Update a Lambda
The lambda type may not be changed.
### Request Parameters
The unique Id of the Lambda to update.
### Response
The response for this API contains the Lambda that was updated.
## Delete a Lambda
### Request Parameters
The unique Id of the Lambda to delete.
### Response
This API does not return a JSON response body.
# Login
import InlineField from 'src/components/InlineField.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import XFusionauthTenantIdHeaderScopedOperationRowOnly from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation-row-only.mdx';
import LoginApplicationidParameter from 'src/content/docs/apis/_login-applicationId-parameter.mdx';
import LoginMetadataDevice from 'src/content/docs/apis/_login-metadata-device.mdx';
import JSON from 'src/components/JSON.astro';
import LoginResponseCodesAuthenticated from 'src/content/docs/apis/_login-response-codes-authenticated.mdx';
import LoginIdField from 'src/content/docs/apis/_login-id-field.mdx';
import LoginIdTypeField from 'src/content/docs/apis/_login-id-type-field.mdx';
import UserResponseBody from 'src/content/docs/apis/_user-response-body.mdx';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import Aside from 'src/components/Aside.astro';
import LoginEvents from 'src/content/docs/_shared/_login_events.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Authenticate a User
The Login API is used authenticate a user in FusionAuth. The issuer of the One Time Password will dictate if a JWT or a Refresh Token may be issued in the API response.
### Request
By default, this API will require API key authentication when called with an applicationId. API key authentication may be disabled per Application, see application.loginConfiguration.requireAuthentication in the [Application API](/docs/apis/applications) or navigate to Applications -> Edit -> Security in the user interface.
Prior to version `1.5.0` this API did not accept an API key and never required authentication.
#### Request Headers
The IP address of a client requesting authentication. If the IP address is provided it will be stored for login history of the user. It is
generally preferred to specify the IP address in the request body. If it is not provided in the request body this header value will be used
if available, the request body value will take precedence.
#### Request Cookies
The Multi-Factor Trust identifier returned by the Multi-Factor Login API response. This value may be provided to bypass the Multi-Factor challenge when a User has Multi-Factor enabled. When this cookie exists on the request it will take precedence over the twoFactorTrustId if provided in the request body.
#### Request Body
The IP address of the end-user that is logging into FusionAuth. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. The IP address will
be stored in the User login history.
When this value is set to true a JWT will not be issued as part of this request. The response body will not contain the `token` or `refreshToken` fields, and the `access_token` and `refresh_token` cookies will not be written to the HTTP response.
This optional parameter may be helpful when performing high volume authentication requests and the JWT is not being utilized, in this scenario removing the additional latency required to issue and sign the JWT may have a measurable cumulative effect on performance.
The user's password or an Application specific [Authentication Token](/docs/lifecycle/authenticate-users/application-authentication-tokens).
The Multi-Factor Trust identifier returned by the Multi-Factor Login API response. This value may be provided to bypass the Multi-Factor challenge when a User has Multi-Factor enabled.
### Response
The response for this API contains the User object.
#### Response Cookies
The encoded access token. This cookie is written in the response as an HTTP Only session cookie.
The refresh token. This cookie is written in the response as an HTTP only persistent cookie. The cookie expiration is configured in the JWT
configuration for the application or the global JWT configuration.
## Authenticate a User with a one time password
This API is used to login using a One Time Password that has been returned from the Change Password API. The login request is nearly identical, however the `oneTimePasswordId` will take the place of both the `loginId` and the `password` properties.
### Request
By default, this API will require authentication when called with an applicationId. Authentication may be disabled per Application, see application.loginConfiguration.requireAuthentication in the [Application API](/docs/apis/applications) or navigate to Applications -> Edit -> Security in the user interface.
#### Request Headers
The IP address of a client requesting authentication. If the IP address is provided it will be stored for login history of the user. It is
generally preferred to specify the IP address in the request body. If it is not provided in the request body this header value will be used
if available, the request body value will take precedence.
#### Request Body
The IP address of the end-user that is logging into FusionAuth. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. The IP address will
be stored in the User login history.
The one time password returned by the Change Password API. This value takes the place of the loginId and the password fields.
When this value is set to true a JWT will not be issued as part of this request. The response body will not contain the `token` or `refreshToken` fields, and the `access_token` and `refresh_token` cookies will not be written to the HTTP response.
This optional parameter may be helpful when performing high volume authentication requests and the JWT is not being utilized, in this scenario removing the additional latency required to issue and sign the JWT may have a measurable cumulative effect on performance.
The Multi-Factor Trust identifier returned by the Multi-Factor Login API response. This value may be provided to bypass the Multi-Factor challenge when a User has Multi-Factor enabled.
### Response
The response for this API contains the User object.
#### Response Cookies
The encoded access token. This cookie is written in the response as an HTTP Only session cookie.
The refresh token. This cookie is written in the response as an HTTP only persistent cookie. The cookie expiration is configured in the JWT
configuration for the application or the global JWT configuration.
## Complete Multi-Factor Authentication
The Multi-Factor Login API is used to complete the authentication process when a `242` status code is returned by the Login API or as the last step of a [Step Up Procedure](/docs/lifecycle/authenticate-users/multi-factor-authentication#step-up-auth).
### Request
Complete a login request when a User has Multi-Factor authentication enabled.
#### Request Headers
The IP address of a client requesting authentication. If the IP address is provided it will be stored for login history of the user. It is generally preferred to specify the IP address in the request body. If it is not provided in the request body, this header value will be used if available. If provided in both places, the request body value takes precedence.
#### Request Body
The Multi-Factor verification code. This may also be a recovery code.
The IP address of the end-user that is logging into FusionAuth. If this value is omitted FusionAuth will attempt to obtain the IP address
of the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. The IP address
will be stored in the User login history.
When this value is set to true a JWT will not be issued as part of this request. The response body will not contain the `token` field,
and the `access_token` and `refresh_token` cookies will not be written to the HTTP response.
When this value is set to true the response will contain a Multi-Factor Trust identifier. This can be used on subsequent Login requests to
allow the Multi-Factor challenge to be bypassed.
An Id generated and returned in the response body during the initial authentication attempt.
The default duration of this identifier is 5 minutes. This means that you have 5 minutes to complete the request to this API after calling the Login API. Once the identifier has expired you will need to call the Login API again to restart the process.
This duration can be modified using the Tenant API or in the FusionAuth UI.
### Response
The response for this API contains the User object.
{/* keep in sync with _login-response-codes.adoc */}
_Response Codes_
| Code | Description |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The authentication was successful. The response will contain the User object that was authenticated. |
| 202 | The user was authenticated successfully. The user is not registered for the application specified by `applicationId` on the request. The response will contain the User object that was authenticated. |
| 203 | The user was authenticated successfully. The user is required to change their password, the response will contain the `changePasswordId` to be used on the [Change Password](/docs/apis/users#change-a-users-password) API. Since version `1.15.0`, the response will also contain a `changePasswordReason` field which can have one of the following values:
`Administrative` - An administrator has required this user to change their password.
`Breached` - The password has been found to have belonged to a breached dataset and must be changed, per the Reactor configuration.
`Expired` - The password has expired, per the expiration setting in the tenant configuration.
`Validation` - The password fails the validation rules configured in the tenant password settings.
{/* eslint-disable-line */} |
| 212 | The user's email address (if an email address or username was used to authenticate) or phone number has not yet been verified. The response will contain the User object that was authenticated. If the tenant verification strategy has been set to `FormField`, the response will contain the verification Id that was generated for the user. |
| 213 | The user's registration has not yet been verified. The response will contain the User object that was authenticated. If the verification strategy has been set to `FormField`, the response will contain the registrationVerificationId that was generated for the user. Prior to version `1.27.0`, this status code was not returned, and you will see a `200` instead. {/* eslint-disable-line */} |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 404 | The `twoFactorId` was invalid or expired. You will need to authenticate again using the [Login](#authenticate-a-user) API. The response will be empty. |
| 409 | The user is currently in an action that has prevented login. The response will contain the actions that prevented login. |
| 410 | The user has expired. The response will be empty. |
| 421 | The `code` request parameter is not valid. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
| 504 | One or more Webhook endpoints returned an invalid response or were unreachable. Based on the transaction configuration for this event your action cannot be completed. A stack trace is provided and logged in the FusionAuth log files. |
#### Response Cookies
The encoded access token. This cookie is written in the response as an HTTP Only session cookie.
The refresh token. This cookie is written in the response as an HTTP Only persistent cookie. The cookie expiration is configured in the
JWT configuration for the application or the global JWT configuration.
The Multi-Factor Trust identifier. This value is returned when `trustComputer` was set to `true` on the request. This value can be used by
subsequent login requests to bypass the Multi-Factor challenge. This cookie is written in the response as an HTTP Only persistent cookie.
## Update Login Instant
Sends a ping to FusionAuth indicating that the user has authenticated, and (optionally) automatically logged into an application.
When using FusionAuth's SSO or your own, you should call this if the user is already logged in centrally, but accesses an
application where they no longer have a session. This helps correctly track login counts, times and helps with reporting.
### Request
#### Request Headers
The IP address of a client requesting authentication. If the IP address is provided it will be stored for login history of the user. It is
generally preferred to specify the IP address in the request body. If it is not provided in the request body this header value will be used
if available, the request body value will take precedence.
#### Request Parameters
The Id of the user logging in.
The IP address of the end-user that is logging into FusionAuth. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. The IP address will
be stored in the User login history.
The `userId` is not required on the request. The `userId` and `applicationId` values will be retrieved from the identity claims in the JWT payload.
#### Request Parameters
The IP address of the end-user that is logging into FusionAuth. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. The IP address will
be stored in the User login history.
### Response
This API does not return a JSON response body.
_Response Codes_
| Code | Description |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The update was successful. |
| 202 | The user exists but is not registered for the application specified by applicationId on the request. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
| 404 | The user was not found. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
## Logout a User
The Logout API is intended to be used to remove the refresh token and access token cookies if they exist on the client and revoke the refresh token. This
API does nothing if the request does not contain an access token or refresh token cookies.
The refresh token is only revoked if the request contains the `refresh_token` cookie or the `refreshToken` request parameter.
This does not revoke the FusionAuth SSO session. Use [`/oauth2/logout`](/docs/lifecycle/authenticate-users/oauth/endpoints#logout) to do so.
### Request
#### Request Cookies
The access token cookie. When this cookie available in the request it will be deleted from the client.
The refresh token cookie. When this cookie available in the request it will be deleted from the client and revoked in FusionAuth.
#### Request Body
When this value is set to true all of the refresh tokens issued to the owner of the provided refresh token will be revoked. If no refresh token is provided on the request no refresh tokens will be revoked.
The `refresh_token` as a request parameter instead of coming in via a cookie. If provided this takes precedence over the cookie.
### Response
This API does not return a JSON response body.
_Response Codes_
| Code | Description |
|------|------------------------------------------------------------------------------------------------|
| 200 | The update was successful. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. |
## Search Login Records
This API allows you to search and paginate through the Login Records. Login Records are created in the following scenarios:
You can limit the number of Login Records retained by navigating to Settings -> System -> Advanced -> Login record settings and configuring automatic deletion of Login Records after a certain number of days.
### Request
When calling the API using a `GET` request you will send the search criteria on the URL using request parameters. In order to simplify the example URL above, not every possible parameter is shown, however using the provided pattern you may add any of the documented request parameters to the URL.
#### Request Parameters
The unique Id of the Application used to narrow the search results to logins for a particular application.
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The number of results to return from the search.
Set this to `true` if you want the total possible results returned in the response. With a very large number of login records settings this value to `true` will increase the response time of this request.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The offset into the total results. In order to paginate the results, increment this value by the numberOfResults for subsequent requests.
The unique Id of the User used to narrow the search results to login records for a particular user.
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
Set this to `true` if you want the total possible results returned in the response. With a very large number of login records settings this value to `true` will increase the response time of this request.
The unique Id of the Application used to narrow the search results to logins for a particular application.
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The number of results to return from the search.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The offset into the total results. In order to paginate the results, increment this value by the numberOfResults for subsequent requests.
The unique Id of the User used to narrow the search results to login records for a particular user.
### Response
The response for this API will contain all login records matching the search criteria in paginated format.
#### Response Body
The list of Login Records returned by the search.
The unique Id of the application.
The name of the application. Because the application name may be modified after the login event occurred, only the applicationId should be considered immutable for historical purposes when identifying the application.
The identity used to log in. Because an identity may be modified after the login event occurred, only the userId should be considered immutable for historical purposes when identifying the user.
In version `1.59.0` and later, the loginId is stored in the login record when the correct value can be identified. In these cases the loginIdType will be populated.
The type of identity used to log in. A missing value on the response indicates the login was not associated with a specific identity, or the login record was created prior to version `1.59.0`.
The [instant](/docs/reference/data-types#instants) when the login occurred.
The recorded IP address for this login record.
The unique Id of the user.
The total number of login records available. This will only be provided in the response when retrieveTotal was set to `true` on the request.
## Export Login Records
This API is used to export Login Records, the response will be a compressed zip archive of CSV files.
### Request
When calling the API using a `GET` request you will send the export criteria on the URL using request parameters. In order to simplify the example URL above, not every possible parameter is shown, however using the provided pattern you may add any of the documented request parameters to the URL.
#### Request Parameters
The unique Id of the Application used to reduce the export result to logins for a particular application.
The format string used to format the date and time columns in the export result.
When this parameter is omitted a default format of `M/d/yyyy hh:mm:ss a z` will be used. See the [DateTimeFormatter patterns](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) for additional examples.
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
The unique Id of the User used to reduce the export result to logins for a particular user.
The [time zone](/docs/reference/data-types#time-zone) used to adjust the stored UTC time in the export result.
For example:
> `America/Denver` or `US/Mountain`
When this parameter is omitted the configured default report time zone will be used. See reportTimezone in the [System Configuration API](/docs/apis/system).
When calling the API using a `POST` request you will send the export criteria in a JSON request body.
#### Request Body
The unique Id of the Application used to reduce the export result to logins for a particular application.
The end [instant](/docs/reference/data-types#instants) of the date/time range to include in the export.
The start [instant](/docs/reference/data-types#instants) of the date/time range to include in the export.
The unique Id of the User used to reduce the export result to logins for a particular user.
The format string used to format the date and time columns in the export result.
When this parameter is omitted a default format of `M/d/yyyy hh:mm:ss a z` will be used. See the [DateTimeFormatter patterns](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) for additional examples.
The [time zone](/docs/reference/data-types#time-zone) used to adjust the stored UTC time in the export result.
For example:
> `America/Denver` or `US/Mountain`
When this parameter is omitted the configured default report time zone will be used. See reportTimezone in the [System Configuration API](/docs/apis/system).
### Response
The response for this API will contain a compressed zip of the login records.
In version `1.59.0` and later, the export file contains Identity value and Identity type columns. If a login record is associated with a particular identity, those values will be reflected in the export. Older login records and new login records not associated with a particular identity will omit values for these columns in the export.
```plaintext title="Sample file export"
"User Id ","Identity value ","Identity type ","Time ","Application Id ","IP Address ","City ","Country ","Zipcode ","Region ","Latitude ","Longitude "
00000000-0000-0000-0000-000000000001,,,5/12/2025 02:46:44 PM MDT,,107.170.227.24,San Francisco,US,,CA,37.7309,-122.3886
00000000-0000-0000-0000-000000000001,richard@piedpiper.com,email,5/12/2025 12:25:12 AM MDT,3c219e58-ed0e-4b18-ad48-f4f92793ae32,127.0.0.1,,,,,,
```
# Message Templates
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import MessageTemplateRequestBody from 'src/content/docs/apis/_message-template-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import MessageTemplateResponseBody from 'src/content/docs/apis/_message-template-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import MessageTemplatesResponseBody from 'src/content/docs/apis/_message-templates-response-body.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import InlineField from 'src/components/InlineField.astro';
import JSON from 'src/components/JSON.astro';
import MessagePreviewResponseBody from 'src/content/docs/apis/_message-preview-response-body.mdx';
## Overview
This page contains the APIs for managing Message Templates as well as messaging users using those templates. Here are the APIs:
## Create a Message Template
This API is used to create a Message Template. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the Message Template. Otherwise, FusionAuth will generate an Id for the Message Template.
### Request
#### Request Parameters
The Id to use for the new Message Template. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the information for the Message Template that was created.
## Retrieve a Message Template
This API is used to retrieve one or all of the configured Message Templates. Specifying an Id on the URI will retrieve a single Message Template. Leaving off the Id will retrieve all of the Message Templates.
### Request
#### Request Parameters
The Id of the Message Template to retrieve.
### Response
The response for this API contains either a single Message Template or all of the Message Templates. When you call this API with an Id the response will contain just that Message Template. When you call this API without an Id the response will contain all of the Message Templates. Both response types are defined below along with an example JSON response.
## Update a Message Template
### Request
#### Request Parameters
The Id of the Message Template to update.
### Response
The response for this API contains the new information for the Message Template that was updated.
## Delete a Message Template
This API is used to delete a Message Template. You must specify the Id of the Message Template on the URI.
### Request
#### Request Parameters
The Id of the Message Template to delete.
### Response
This API does not return a JSON response body.
## Preview a Message Template
This API is used to preview a Message Template. You pass all of the information for the Message Template in the request and a rendered version of the Message is sent back to you in the response. See [previewing message templates](/docs/customize/email-and-messages/message-templates-replacement-variables#previewing-message-templates) for the sample values that are used with the request.
The Message Template in the request does not need to be completely filled out. You can send in a partial Message Template and the response will contain only what you provided.
### Request
#### Request Body
The locale to use when rendering the Message Template. If this is null or omitted, the defaults will be used and the localized versions will be ignored.
The default Message Template to preview.
The Message Template used when sending messages to users who speak other languages. This overrides the default Message Template based on the locale string passed.
The type of the template. This must be the value `SMS`.
### Response
The response for this API contains the rendered Message and also an Errors that contains any rendering issues FusionAuth found. The template might have syntax or logic errors and FusionAuth will put these errors into the response.
# Passwordless
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import InlineField from 'src/components/InlineField.astro';
import JSON from 'src/components/JSON.astro';
import LoginIdField from "src/content/docs/apis/_login-id-field.mdx";
import LoginIdTypeField from "src/content/docs/apis/_login-id-type-field.mdx";
import PasswordlessStartResponseBody from 'src/content/docs/apis/_passwordless-start-response-body.mdx';
import XFusionauthTenantIdHeaderScopedOperationRowOnly from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation-row-only.mdx';
import DeviceTypeList from 'src/content/docs/_shared/_device-type-list.mdx';
import LoginResponseCodes from 'src/content/docs/apis/_login-response-codes.mdx';
import UserResponseBody from 'src/content/docs/apis/_user-response-body.mdx';
## Overview
This page contains the APIs that are used to authenticate users without passwords using magic links and codes.
You also may find the [Magic Links guide](/docs/lifecycle/authenticate-users/passwordless/magic-links) helpful.
## Start Passwordless Login
This API allows you to generate a passwordless code that can be used to complete login. This is the first step in completing a passwordless login.
If you plan to utilize the FusionAuth login page then you will not need to use this API. Instead, once passwordless authentication is enabled for the FusionAuth Application, a new button will be presented to the user on the login page which will allow them to request an email.
### Request
#### Request Body
The unique Id of the Application you are requesting to log into.
If you are using the Send Passwordless Login API with the code returned by this call, that API will send a message using a delivery method appropriate for the loginId used here. If you supplied a username or email address loginId, the message will be sent via email. If you supplied a phone number loginId then the message will be delivered via an SMS messenger.
} />
An optional object that will be returned un-modified when you complete the passwordless login request. This may be useful to return the user to particular state once they complete login using the passwordless code.
The process by which the user will complete the passwordless login. The possible values are:
* `ClickableLink` - send the user a code with a clickable link.
* `FormField` - send the user a short code intended to be manually entered into a form field.
If not specified, the default is based on the `loginIdType` of `loginId`:
* email address or username - `ClickableLink`
* phone number - `FormField`
### Response
_Response Codes_
| Code | Description |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
| 404 | The user was not found. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
## Send Passwordless Login
This API allows you to send an email or SMS message to a user that will contain a code that can be used to complete login. This API should be used if you want to build your own login page.
If you plan to utilize the FusionAuth login page then you will not need to use this API. Instead, once passwordless authentication is enabled for the FusionAuth Application, a new button will be presented to the user on the login page which will allow them to request an email or SMS message.
This API does not require authentication.
### Request
#### Request Body
The unique code to send via email or SMS, used to complete the login request. This value can be generated with a call to the [Start Passwordless Login](#start-passwordless-login) API. The `loginStrategy` value used in the [Start Passwordless Login](#start-passwordless-login) API controls whether an email or SMS is sent.
#### Request Body
The unique Id of the Application you are requesting to log into.
The login identifier of the user. The login identifier can be either the email or the username.
An optional object that will be returned un-modified when you complete the passwordless login request. This may be useful to return the user to particular state once they complete login using the email link.
### Response
The response for this API does not contain a body. It only contains a status code.
_Response Codes_
| Code | Description |
|------|------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
## Complete a Passwordless Login
This API is used to complete the passwordless login request. This API should be used if you want to build your own login page.
If you plan to utilize the FusionAuth login page then you will not need to use this API. Instead, once passwordless authentication is enabled for the FusionAuth Application, a new button will be presented to the user on the login page which will allow them to request an email.
This API does not require authentication.
### Request
#### Request Headers
The IP address of a client requesting authentication. If the IP address is provided it will be stored for login history of the user. It is
generally preferred to specify the IP address in the request body. If it is not provided in the request body this header value will be used
if available, the request body value will take precedence.
#### Request Cookies
The Two Factor Trust identifier returned by the Two Factor Login API response. This value may be provided to bypass the Two Factor challenge when a User has Two Factor enabled. When this cookie exists on the request it will take precedence over the twoFactorTrustId if provided in the request body.
#### Request Parameters
The unique Id of the Application you are requesting to log into. If omitted, no application-specific settings such as lambdas or templates will be applied.
The unique code sent via email used to complete the login request.
The IP address of the end-user that is logging into FusionAuth. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. The IP address will
be stored in the User login history.
A human readable description of the device used during login. This meta data is used to describe the refresh token that may be generated for this login request.
A human readable name of the device used during login. This meta data is used to describe the refresh token that may be generated for this login request.
The type of device represented by the `device` parameter. This meta data is used to describe the refresh token that may be generated for this login request.
Prior to version 1.46.0, this value was restricted to the following types:
In version `1.46.0` and beyond, this value can be any string value you'd like, have fun with it!
When this value is set to true a JWT will not be issued as part of this request. The response body will not contain the `token` or `refreshToken` fields, and the `access_token` and `refresh_token` cookies will not be written to the HTTP response.
This optional parameter may be helpful when performing high volume authentication requests and the JWT is not being utilized, in this scenario removing the additional latency required to issue and sign the JWT may have a measurable cumulative effect on performance.
The Two Factor Trust identifier returned by the Two Factor Login API response. This value may be provided to bypass the Two Factor challenge when a User has Two Factor enabled.
### Response
#### Response Cookies
The encoded access token. This cookie is written in the response as an HTTP Only session cookie.
The refresh token. This cookie is written in the response as an HTTP only persistent cookie. The cookie expiration is configured in the JWT
configuration for the application or the global JWT configuration.
###
# Reactor
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import ReactorMetricsResponseBody from 'src/content/docs/apis/_reactor-metrics-response-body.mdx';
import ReactorStatusResponseBody from 'src/content/docs/apis/_reactor-status-response-body.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
## Overview
This page contains the APIs for Reactor, FusionAuth's license system. Reactor is used to activate features based upon your licensing tier. Here are the APIs:
## Activate Reactor license
This API is used to activate a Reactor license.
### Request
#### Request Body
The license Id to activate.
The Base64 encoded license value. This value is necessary in an [air-gapped](/docs/get-started/download-and-install/air-gapping) configuration where outbound network access is not available.
### Response
This API does not return a JSON response body.
## Retrieve Reactor metrics
This API is used to retrieve the metrics of Reactor features.
### Request
### Response
## Retrieve Reactor status
This API is used to retrieve the status of Reactor features.
### Request
### Response
## Regenerate Reactor license
This API is used to make requests from FusionAuth to the License server to regenerate a license. This is particularly useful if it is suspected that the license key has been compromised and a new one is needed.
Regenerating the license will cause any other instance using the license to revert to Community plan features. All configuration will be maintained, but any paid plan functionality will be disabled. The instance of FusionAuth that makes this API request will be updated to use the new license key, but each additional instance requiring a license will need the updated license key.
### Request
### Response
This API does not return a JSON response body.
## Deactivate Reactor license
This API is used to deactivate a Reactor license.
If [Breached Password Detection](/docs/operate/secure/breached-password-detection/) was being used it will no longer work, licensed features can no longer be enabled, and existing configurations may no longer work if they use licensed features.
### Request
### Response
This API does not return a JSON response body.
# User Registrations
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import DeprecatedSince from 'src/components/api/DeprecatedSince.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import UserRegistrationRequestBody from 'src/content/docs/apis/_user-registration-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import UserRegistrationResponseBody from 'src/content/docs/apis/_user-registration-response-body.mdx';
import XFusionauthTenantIdHeaderCreateOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-create-operation.mdx';
import UserRegistrationCombinedRequestBody from 'src/content/docs/apis/_user-registration-combined-request-body.mdx';
import UserRegistrationCombinedResponseBody from 'src/content/docs/apis/_user-registration-combined-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import InlineField from 'src/components/InlineField.astro';
import JSON from 'src/components/JSON.astro';
## Overview
This page contains the APIs that are used to manage User Registrations. A registration is the association between a User and an Application that they log into. Here are the APIs:
## Create a User Registration (for an existing user)
This API is used to create a new User Registration for an existing User. If the User has already created their global account but is now creating an account for an Application, this is the API you will use to create the new account. You must specify the User Id being registered on the URI. The Id of the Application the User is registering for is sent in the request body.
### Request
#### Request Parameters
The Id of the User that is registering for the Application.
### Response
The response for this API contains the User Registration that was created. Security sensitive fields will not be returned in the response.
## Create a User and Registration (combined)
This API is used to create a new User and a User Registration in a single request. This is useful if for example you have a main website that User's create their account on initially. The User is technically creating their global User object and a User Registration for that website (i.e. that Application). In this case, you will want to create the User and the User Registration in a single step. This is the API to use for that. You can optionally still provide an Id for the new User on the URI. If you don't specify an Id for the User, FusionAuth will create one for you.
### Request
#### Request Parameters
The Id to use for the new User. If you don't specify this, FusionAuth will generate a random UUID.
### Response
The response for this API contains the User and the User Registration that were created. Security sensitive fields will not be returned in the response.
## Retrieve a User Registration
This API is used to retrieve a single User Registration. This is the information about a User for a single Application.
### Request
#### Request Parameters
The Id of the Application that the User is registered for.
The Id of the User whose registration is being retrieved.
### Response
The response for this API contains the User Registration.
## Update a User Registration
### Request
#### Request Parameters
The Id of the Application for which the User is registered.
While required, this parameter may be provided in the request body as well. If the `applicationId` is provided in both the URL and the request body, the value on the URL will take precedence. Prior to version `1.25.0` this value must be provided in the request body.
The Id of the User that is updating their User Registration for the Application.
### Response
The response for this API contains the User Registration that was updated. Security sensitive fields will not be returned in the response.
## Delete a User Registration
This API is used to delete a single User Registration.
### Request
#### Request Parameters
The Id of the Application for which the User will no longer be registered.
The Id of the User whose registration is being removed.
### Response
The response for this API does not contain a body. It only contains one of the status codes listed below.
## Verify a User Registration
This API is used to mark a User Registration as verified. This is usually called after the User receives the registration verification email after they register and they click the link in the email.
### Request
#### Request Parameters
The verification Id generated by FusionAuth used to verify the User's registration is valid by ensuring they have access to the provided email address.
This value can still be provided on the URL segment as shown in the above example, but it is recommended you send this value in the request body instead using the verificationId field. If the value is provided in the URL segment and in the request body, the value provided in the request body will be preferred.
#### Request Body
The short code used to verify the User's registration is valid by ensuring they have access to the provided email address. This field is required when the registration verification strategy on the Application is set to `FormField`.
This field is required when the registration verification strategy on the Application is set to `Form field`.
The verification Id generated by FusionAuth used to verify the User's registration is valid by ensuring they have access to the provided email address.
When using the `Form field` strategy for registration verification, this value is used along with the `oneTimeCode` as a pair to verify the registration.
If the verificationId is provided in the URL segment and in the request body, the value provided in the request body will be preferred.
### Response
The response does not contain a body. It only contains one of the status codes below.
_Response Codes_
| Code | Description |
|------|------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 404 | The User does not exist or is not registered to the requested Application. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
## Resend a User Registration Verification Email
This API is used to resend the registration verification email to a User. This API is useful if the User has deleted the email, or the verification Id has
expired. By default, the verification Id will expire after 24 hours.
### Request
#### Request Parameters
The unique Id of the Application for this User registration.
The email address used to uniquely identify the User.
#### Request Parameters
The unique Id of the Application for this User registration.
The email address used to uniquely identify the User.
If you would only like to generate a new `verificationId` and return it in the JSON body without FusionAuth attempting to send the User an email
set this optional parameter to `false`.
This may be useful if you need to integrate the Registration Verification process using a third party messaging service.
### Response
When authenticated using an API key a response body will be provided. If an API key was not used to authenticate the request no body is returned.
#### Response Body
The Registration Verification Id that was generated by this API request. This identifier may be used by the [Verify a User Registration](#verify-a-user-registration) API.
This field is only returned in the JSON response body if the request was authenticated using an API key, if an API key is not used no response body is returned.
# Reports
import Report from 'src/content/docs/apis/_report.mdx';
import API from 'src/components/api/API.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import JSON from 'src/components/JSON.astro';
## Overview
This page contains the APIs for retrieving the reports available in FusionAuth. Here are the APIs:
## Retrieve Daily Active Users Report
## Retrieve Login Report
## Retrieve Monthly Active Users Report
## Retrieve Registration Report
## Retrieve Totals Report
The Report Totals API is used to retrieve the number users currently registered and how many login requests have been serviced by FusionAuth globally as well as broken down by each Application.
### Request
### Response
The response for this API contains the totals report.
#### Response Body
A map where the key is the Id of the Application and the value is an object that contains the totals for that Application.
The total number of logins (all time) for the Application.
The current number of registrations for the Application. This doesn't include registrations for user's that have been deleted from FusionAuth.
The total number of registrations (all time) for the Application.
The current number of registered users. This value is incremented each time a new user is added to FusionAuth, and this value is decremented when a user is deleted from FusionAuth.
The total number of registrations (all time). When a user is removed from FusionAuth this number is not decremented.
# OAuth Scopes
import AdvancedPlanBlurb from 'src/content/docs/_shared/_advanced-plan-blurb.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import API from 'src/components/api/API.astro';
import Aside from 'src/components/Aside.astro';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import ScopeRequestBody from 'src/content/docs/apis/_scope-request-body.mdx';
import ScopeResponseBody from 'src/content/docs/apis/_scope-response-body.mdx';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
## Overview
This page contains the APIs for managing the OAuth Scopes of an Application.
## Create an OAuth Scope
This API is used to create an OAuth Scope for an Application. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the OAuth Scope. Otherwise, FusionAuth will generate an Id for the OAuth Scope.
### Request
#### Request Parameters
The Id of the Application.
The Id to use for the new OAuth Scope. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the information for the OAuth Scope that was created.
## Retrieve an OAuth Scope
This API is used to retrieve a single OAuth Scope for an Application by unique Id.
### Request
#### Request Parameters
The Id of the Application.
The Id of the OAuth Scope to retrieve.
### Response
The response for this API contains a single OAuth Scope.
## Update an OAuth Scope
### Request
#### Request Parameters
The Id of the Application.
The Id of the OAuth Scope to update.
### Response
The response for this API contains the information for the OAuth Scope that was updated.
## Delete an OAuth Scope
This API is used to permanently delete an OAuth Scope.
### Request
#### Request Parameters
The Id of the Application.
The Id of the OAuth Scope to delete.
### Response
This API does not return a JSON response body.
# System
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import SystemConfigurationResponseBody from 'src/content/docs/apis/_system-configuration-response-body.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import SystemConfigurationRequestBody from 'src/content/docs/apis/_system-configuration-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import SystemLogsRequestBody from 'src/content/docs/apis/_system-logs-request-body.mdx';
import JSON from 'src/components/JSON.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import ReindexRequestBody from 'src/content/docs/apis/_reindex-request-body.mdx';
import PrometheusJvmGauges from 'src/content/docs/_shared/_prometheus-jvm-gauges.mdx';
## Overview
This page contains the APIs that are used for retrieving and updating the system configuration.
## Retrieve the System Configuration
This API is used to retrieve the System Configuration.
### Request
### Response
The response for this API contains the System Configuration.
## Update the System Configuration
### Request
### Response
The response for this API contains the System Configuration.
## Export System Logs
This API is used to export the System Logs, the response will be a compressed zip archive containing the logs from the configured log directory. When running FusionAuth on Docker or other container service where logs are written to `stdout` and not written to the file system, this API will return an empty archive.
### Request
When calling the API using a `GET` request you will send the export criteria on the URL using request parameters.
#### Request Parameters
When calling the API using a `POST` request you will send the export criteria in a JSON request body.
#### Request Body
### Response
The response for this API will contain a compressed zip of the system logs.
## Retrieve the Logging Level
The Logger API is used to retrieve the current log level for a particular logger by name.
### Request
#### Request Parameters
The logger name for which you are requesting to retrieve the current logging level.
### Response
#### Response Body
The name of the logger.
The current logging level. Possible values are:
* `error`
* `warn`
* `info`
* `debug`
* `trace`
* `off`
## Update the Logging Level
This API is used to update the log level for a particular FusionAuth package.
### Request
#### Request Headers
The request body is expected to be sent using form encoded data. Ensure your HTTP client sends the `Content-Type` request header set to `application/x-www-form-urlencoded`.
#### Request Parameters
The logger name for which you are requesting to update the current logging level.
The requested logging level. Possible values are:
* `error`
* `warn`
* `info`
* `debug`
* `trace`
* `off`
### Response
#### Response Body
The logging level. If the request was successful, this value should be equal to the request value. Possible values are:
* `error`
* `warn`
* `info`
* `debug`
* `trace`
* `off`
## Rebuild the Elasticsearch index
This API is used to rebuild the Elasticsearch index. In general you do not need to rebuild the search index at runtime, and doing will cause additional CPU and I/O overhead to FusionAuth until the request has completed. Please be careful with this API.
This API may be useful if you are building a new FusionAuth environment from an existing database w/out moving over an existing search index. In this scenario you will need to rebuild the search index from the database in order see the Users show up in the UI or use any of the Search APIs.
Beginning in version `1.48.0`, index aliases are used to minimize any disruption to API requests utilizing the search index. In practice this should not affect you, but please be aware that FusionAuth will use the configured index name as an alias, and the actual index name will be suffixed with `_a` or `_b`.
For example, the default name for the user index is `fusionauth_user`. You can expect to see the actual index to be created as `fusionauth_user_a` with an alias added named `fusionauth_user`. Using this same example, when a reindex request is started, a new index named `fusionauth_user_b` will be created, and when the re-index operation is complete the alias `fusionauth_user` will be changed to point to `fusionauth_user_b` and the `fusionauth_user_a` will be deleted.
### Request
### Response
## Retrieve the status of an index rebuild
This API is used to retrieve the status of a reindex request. This may be useful to identify if an existing re-index operation has been completed.
### Request
### Response
## Retrieve System Status
The Status API is used to retrieve the current status and metrics for FusionAuth. This is useful for monitoring. For health checks, prefer [the Health API](/docs/apis/system#retrieve-system-health).
By default, this API requires authentication to return full results. If you prefer to allow unauthenticated access to this endpoint from local scrapers, you may set `fusionauth-app.local-metrics.enabled=true`. See the [configuration reference](/docs/reference/configuration) for more info.
If you call this API without an API key, you will receive a status response only.
### Request
### Response
This JSON response body varies based on whether you:
* provide an API key
* do not provide an API key
* configure local bypass
When no API key is used and local bypass is not enabled, the response will only include the `status` property.
```json
{
"status": "ok"
}
```
When retrieved with an API key or if local bypass is enabled, the JSON response from the Status API is complex and subject to change. The only exception is the `version` key.
The `version` key will not change and will be returned as below. As a reminder, an API key is required to obtain this value unless explicitly allowed from `localhost`.
```json
{
"version": "1.59.0"
}
```
The specific contents of the JSON body are not documented here. If you choose to use this API for monitoring purposes you should primarily use the response code to indicate server health. If you receive a `200` you may consider FusionAuth in a healthy state. The response body is intended for use by FusionAuth support.
_Response Codes_
| Code | Description |
|------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | FusionAuth is functioning properly |
| 452 | FusionAuth is failing to make a JDBC connection to the configured database. |
| 453 | The FusionAuth database connection pool connectivity is below the healthy threshold. This means requests are waiting too long to obtain a connection to the database. Additional information may be available in the JSON response which is retrieved when using an API key. |
| 454 | The FusionAuth database connection pool connectivity is below the healthy threshold. Additional information may be available in the JSON response which is retrieved when using an API key.
As of version `1.51.1` this status code will no longer be returned based upon the connectivity health check. In practice you only need to monitor for `452` to ensure FusionAuth is able to connect to the database. {/* eslint-disable-line */} |
| 460 | FusionAuth is using Elasticsearch and the search service is reporting an unhealthy cluster status. In a cluster with 2+ nodes, this means the cluster status is being reported as `yellow` or `red`. In a single-node Elasticsearch configuration this means the cluster status is `red.`
As of version `1.51.1` this status code will no longer be returned based upon the Elasticsearch health check. If you are using an external Elasticsearch or OpenSearch service, you will want to monitor that separately from FusionAuth. {/* eslint-disable-line */} |
| 500 | FusionAuth is not functioning properly. This could indicate that the database connectivity failed or one or more services within FusionAuth failed. Consult the FusionAuth [Troubleshooting](/docs/operate/troubleshooting/troubleshooting) to learn more about the failure or contact FusionAuth support for assistance. |
## Retrieve System Health
The Health API is used to monitor the health of the FusionAuth service. This endpoint is specifically intended for use by a load balancer to understand when FusionAUth is available, live and ready for requests. Prefer this endpoint to the Status API when using it for a load balancer or a Kubernetes readiness check.
This API does not require an API key.
### Request
### Response
This API does not return a JSON response body.
_Response Codes_
| Code | Description |
|------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | FusionAuth is functioning properly and can accept requests. |
| 500 | FusionAuth is not functioning properly. This will generally indicate that FusionAuth is not able to communicate with the database or complete I/O operations. |
## Retrieve System Version
The Version API is used to retrieve the current version of FusionAuth.
### Request
### Response
#### Response Body
The version of the running FusionAuth instance.
```json title="Example JSON Response"
{
"version": "1.27.0"
}
```
## Retrieve System Metrics Using Prometheus
This page contains the API that is used for retrieving FusionAuth application metrics to be used with Prometheus. Please refer to the [Prometheus setup](/docs/operate/monitor/prometheus) guide to understand how to set up Prometheus with the FusionAuth metrics endpoint.
By default, this API requires authentication. If you prefer to allow unauthenticated access to this endpoint from local scrapers, you may set `fusionauth-app.local-metrics.enabled=true`. See the [configuration reference](/docs/reference/configuration) for more info.
### Request Parameters
There are no request parameters required with this API.
### Response
The response to this API call contains currently available metrics. The metrics in this response are subject to change.
```plaintext title="Example Prometheus Response"
# HELP jvm_memory_heap_committed Generated from Dropwizard metric import (metric=jvm.memory.heap.committed, type=com.codahale.metrics.jvm.MemoryUsageGaugeSet$8)
# TYPE jvm_memory_heap_committed gauge
jvm_memory_heap_committed 5.36870912E8
# HELP jvm_memory_non_heap_used Generated from Dropwizard metric import (metric=jvm.memory.non-heap.used, type=com.codahale.metrics.jvm.MemoryUsageGaugeSet$11)
# TYPE jvm_memory_non_heap_used gauge
jvm_memory_non_heap_used 1.66423384E8
# HELP jvm_memory_pools_CodeHeap__non_profiled_nmethods__used Generated from Dropwizard metric import (metric=jvm.memory.pools.CodeHeap-'non-profiled-nmethods'.used, type=com.codahale.metrics.jvm.MemoryUsageGaugeSet$17)
# TYPE jvm_memory_pools_CodeHeap__non_profiled_nmethods__used gauge
jvm_memory_pools_CodeHeap__non_profiled_nmethods__used 3.0334336E7
# HELP prime_mvc___admin_group_index__requests Generated from Dropwizard metric import (metric=prime-mvc.[/admin/group/index].requests, type=com.codahale.metrics.Timer)
# TYPE prime_mvc___admin_group_index__requests summary
prime_mvc___admin_group_index__requests{quantile="0.5",} 0.0
prime_mvc___admin_group_index__requests{quantile="0.75",} 0.0
prime_mvc___admin_group_index__requests{quantile="0.95",} 0.0
prime_mvc___admin_group_index__requests{quantile="0.98",} 0.0
prime_mvc___admin_group_index__requests{quantile="0.99",} 0.0
prime_mvc___admin_group_index__requests{quantile="0.999",} 0.0
prime_mvc___admin_group_index__requests_count 1.0
```
# Tenants
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import API from 'src/components/api/API.astro';
import Aside from 'src/components/Aside.astro';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import JSON from 'src/components/JSON.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import TenantCopyRequestBody from 'src/content/docs/apis/_tenant-copy-request-body.mdx';
import TenantPasswordValidationRulesResponseBody from 'src/content/docs/apis/_tenant-password-validation-rules-response-body.mdx';
import TenantRequestBody from 'src/content/docs/apis/_tenant-request-body.mdx';
import TenantResponseBody from 'src/content/docs/apis/_tenant-response-body.mdx';
import TenantResponseBodyBase from 'src/content/docs/apis/_tenant-response-body-base.mdx';
import TenantsResponseBody from 'src/content/docs/apis/_tenants-response-body.mdx';
import TenantSearchRequestParameters from 'src/content/docs/apis/_tenant-search-request-parameters.mdx';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
## Overview
A FusionAuth Tenant is a named object that represents a discrete namespace for Users, Applications and Groups. A user is unique by email
address or username within a tenant.
Tenants may be useful to support a multi-tenant application where you wish to use a single instance of FusionAuth but require the ability to
have duplicate users across the tenants
in your own application. In this scenario a user may exist multiple times with the same email address and different passwords across tenants.
Tenants may also be useful in a test or staging environment to allow multiple users to call APIs and create and modify users without
possibility of collision.
The following APIs are provided to manage Tenants.
The following APIs provide a subset of the Tenant configuration without an API Key.
## Create a Tenant
This API is used to create a new Tenant.
### Request
#### Request Parameters
The Id to use for the new Tenant. If not specified a secure random UUID will be generated.
#### Request Parameters
The Id to use for the new Tenant. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the Tenant that was created.
## Retrieve a Tenant
This API is used to retrieve a single Tenant by unique Id or all of the configured Tenants.
### Request
#### Request Parameters
The unique Id of the Tenant to retrieve.
### Response
The response for this API contains either a single Tenant or all of the Tenants. When you call this API with an Id the response will
contain a single Tenant. When you call this API without an Id the response will contain all of the Tenants. Both response types are
defined below along with an example JSON response.
## Search for Tenants
This API is used to search for Tenants and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
**Note:** API key authentication must be made using a global API key. The request may not contain the `X-FusionAuth-TenantId` request header. Requests made using an API key scoped to a specific tenant, or containing the `X-FusionAuth-TenantId` request header will fail with a `401` status code.
### Request
#### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
### Response
The response for this API contains the Tenants matching the search criteria in paginated format.
#### Response Body
## Update a Tenant
### Request
#### Request Parameters
The Id of the Tenant to update.
### Response
The response for this API contains the Tenant that was updated.
## Delete a Tenant
This API is used to permanently delete a Tenant. Deleting a Tenant will delete all Users, Applications and Groups that belong to this
tenant. Proceed with caution.
### Request
#### Request Parameters
The unique Id of the Tenant to delete.
Set this value to `true` to perform this request asynchronously, this means the API will return a response indicating the request has been accepted and will not wait for the operation to complete.
### Response
This API does not return a JSON response body.
## Retrieve the Password Validation Rules
This API is used to retrieve the Password Validation Rules. This configuration is a subset of the Tenant configuration.
### Request
#### Request Parameters
The Id of the tenant.
### Response
The response for this API contains the Password Validation Rules.
*Response Codes*
|Code |Description
| --- | --- |
|200 |The request was successful. The response will contain a JSON body. |
|500 |There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
# Multi-Factor
import Aside from 'src/components/Aside.astro';
import AvailableSince from 'src/components/api/AvailableSince.astro';
import InlineField from 'src/components/InlineField.astro';
import TwoFactorTotpLimits from 'src/content/docs/_shared/_two-factor-totp-limits.mdx';
import PlanBlurb from 'src/content/docs/_shared/_plan-blurb.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import TwoFactorEnableRequestBody from 'src/content/docs/apis/_two-factor-enable-request-body.mdx';
import TwoFactorEnableResponse from 'src/content/docs/apis/_two-factor-enable-response.mdx';
import TwoFactorDisableRequestParameters from 'src/content/docs/apis/_two-factor-disable-request-parameters.mdx';
import TwoFactorDisableRequestBody from 'src/content/docs/apis/_two-factor-disable-request-body.mdx';
import JSON from 'src/components/JSON.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import TwoFactorStartRequestBody from 'src/content/docs/apis/_two-factor-start-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import TwoFactorStartResponseBody from 'src/content/docs/apis/_two-factor-start-response-body.mdx';
Email and SMS multi-factor methods are only available in a paid plan of FusionAuth. Please visit [our pricing page](/pricing) to learn more about paid plans.
## Overview
This API controls [multi-factor authentication (MFA)]((/docs/lifecycle/authenticate-users/multi-factor-authentication) options.
## Authentication
Some of these operations can use JWT authentication instead of API key authentication. In some cases, when you have a valid twoFactorId, neither a JWT nor an API key is required.
Learn more about [JWT authentication and see examples here](/docs/apis/authentication#jwt-authentication).
## TOTP Implementation
Support for Authy, Google Authenticator and other time based one-time password solutions are not premium features and are included in the Community plan.
## Enable Multi-Factor
This API is used to enable Multi-Factor authentication for a single User. To use this API the User must provide a valid
Multi-Factor verification code.
If using message based delivery, you may [Send a Multi-Factor Code When Enabling MFA](#send-a-multi-factor-code-when-enabling-mfa) to deliver a
code to the User. The User will then provide this code as input.
### Request
#### Request Parameters
The Id of the User for whom to enable Multi-Factor authentication.
### Response
_Response Codes_
| Code | Description |
|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. Multi-Factor has been enabled for the User. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. This status will also be returned if a paid FusionAuth license is required and is not present. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
| 404 | The User does not exist. The response will be empty. |
| 421 | The `code` request parameter is not valid. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
## Disable Multi-Factor
This API is used to disable Multi-Factor authentication for a single User. To use this API the User must provide a valid
Multi-Factor verification code or recovery code.
If using message based delivery, you may [Send a Multi-Factor Code When Disabling MFA](#send-a-multi-factor-code-when-disabling-mfa) to deliver a
code to the User. The User will then provide this code as input.
If a recovery code is provided, all methods will be removed.
### Request
### Response
_Response Codes_
| Code | Description |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. Multi-Factor has been disabled for the User. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
| 404 | The User does not exist. The response will be empty. |
| 421 | The `code` request parameter is not valid. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
## Generate a Secret
This API is used to generate a new multi-factor secret for use when enabling multi-factor authentication for a User. This is provided
as a helper to assist you in enabling multi-factor authentication.
If this secret will be used with a QR code to allow the User to scan the value, use the Base32 encoded value returned in the response.
### Request
### Response
The response for this API contains a Multi-Factor secret suitable for an authenticator like Google Authenticator.
#### Response Body
A Base64 encoded secret that may be used to enable Multi-Factor authentication.
A Base32 encoded form of the provided secret. This is useful if you need to provide a QR code to the User to enable Multi-Factor authentication.
## Start Multi-Factor
Starts an multi-factor request. This would be used for only step up auth, such as when sensitive data is requested.
If you want to provide your own code and/or deliver the code out of band using your own delivery mechanism, this is the right API call. Do not combine this with a [Send a Multi-Factor Code During Login or Step Up](#send-a-multi-factor-code-during-login-or-step-up) call, as calling that API will invalidate all other codes associated with the twoFactorId, including any you provide.
To require additional factors during login, [Enable Multi-Factor](#enable-multi-factor) for the User. Then FusionAuth will handle MFA code collection automatically, if you are using the hosted login pages, or send a status code in response to the login API if you are not.
### Request
### Response
## Retrieve Multi-Factor Status
Retrieves a user's multi-factor status. This is helpful to understand if a user has multi-factor authentication enabled, and if the user will be required to perform a multi-factor challenge during the next login request.
This API may also be used to identify if an existing multi-factor trust value obtained during a multi-factor login is expired, or valid for a specific application when configured to restrict multi-factor trust.
### Request
#### Request Parameters
A unique application Id. When Application multi-factor configuration is enabled, providing this parameter will ensure the returned status applies to the expected result when attempting to login into this application.
The existing multi-factor trust obtained by completing a multi-factor login. This is the value that allows you to bypass multi-factor during the next login attempt.
The unique Id of the user for which to retrieve multi-factor status.
#### Request Body
The action the user is attempting to perform. This value may be used by an MFA requirement lambda to determine if multi-factor authentication should be required.
Valid values are:
* `changePassword`
* `login`
* `stepUp`
A unique application Id. When Application multi-factor configuration is enabled, providing this parameter will ensure the returned status applies to the expected result when attempting to login into this application.
An access token (not an Id token) returned by FusionAuth as the result of a successful authentication. The encoded access token will be available in `context.accessToken` in an MFA requirement lambda function. See the [MFA requirement lambda](/docs/extend/code/lambdas/mfa-requirement) documentation. This must be a valid token that was issued and signed by FusionAuth.
The existing multi-factor trust obtained by completing a multi-factor login. This is the value that allows you to bypass multi-factor during the next login attempt.
The unique Id of the user for which to retrieve multi-factor status.
### Response
Response Codes
| Code | Description |
|------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The user does not have multi-factor enabled, a challenge is not required, or the provided trust is still valid for the next login. |
| 242 | The user has multi-factor authentication enabled. Since version `1.42.0`, this status code is also returned when multi-factor authentication is required. The user will be required to complete a multi-factor challenge during the next login attempt. This status code can also be used to determine whether step up is required.|
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
#### Response Body
An array of one or more trust configurations.
The value provided in the twoFactorTrustId on the request.
## Send a Multi-Factor Code During Login or Step Up
This operation allows you to send a message with a code to finish a Multi-Factor flow, and requires an existing twoFactorId. No API key is required.
This should only be used if you want FusionAuth to send the code. Do not use this if you are sending a code out of band or are using a TOTP based authentication method.
You can use this to re-send a code with the same or a different method. Using this API will invalidate all other codes previously associated with the provided twoFactorId.
Sending a code invalidates all previous codes for the provided `twoFactorId`.
### Request
#### Request Parameters
The twoFactorId returned by the Login API or the Start multi-factor request.
#### Request Body
The Id of the MFA method to be used.
### Response
This API does not return a JSON response body.
## Send a Multi-Factor Code When Enabling MFA
You are enabling MFA for a user. You must provide an API key or a valid JWT for the User you are modifying. This should only be used if you want FusionAuth to send the code. Do not use this if you are using a TOTP based authentication method.
### Request
#### Request Body
An optional Application Id. When this value is provided, it will be used to resolve an application-specific email or message template and make `application` available as a template variable.
If not provided, only the tenant configuration will be used when resolving templates, and `application` will not be available as a template variable.
The email to which send Multi-Factor codes. If the method is equal to `email`, this is required.
The type of the MFA method which will be added. The value provided here must be allowed in the Tenant MFA configuration as well.
Valid values are:
* `email`
* `sms`
The mobile phone to which send Multi-Factor codes. If the method is equal to `sms`, this is required.
The User Id.
#### Request Body
An optional Application Id. When this value is provided, it will be used to resolve an application-specific email or message template and make `application` available as a template variable.
If not provided, only the tenant configuration will be used when resolving templates, and `application` will not be available as a template variable.
The email to which send Multi-Factor codes. If the method is equal to `email`, this is required.
The type of the MFA method which will be added. The value provided here must be allowed in the Tenant MFA configuration as well.
Valid values are:
* `email`
* `sms`
The mobile phone to which send Multi-Factor codes. If the method is equal to `sms`, this is required.
### Response
This API does not return a JSON response body.
## Send a Multi-Factor Code When Disabling MFA
You are disabling MFA for a user. You must provide an API key or a valid JWT for the User you are modifying. This should only be used if you want FusionAuth to send the code. Do not use this if you are using a TOTP based authentication method.
### Request
#### Request Body
An optional Application Id. When this value is provided, it will be used to resolve an application-specific email or message template and make `application` available as a template variable.
If not provided, only the tenant configuration will be used when resolving templates, and `application` will not be available as a template variable.
The Id of the MFA method which will be removed.
The User Id of the User to send a Multi-Factor verification code. This User is expected to already have Multi-Factor enabled.
#### Request Body
An optional Application Id. When this value is provided, it will be used to resolve an application-specific email or message template and make `application` available as a template variable.
If not provided, only the tenant configuration will be used when resolving templates, and `application` will not be available as a template variable.
The Id of the MFA method which will be removed.
### Response
This API does not return a JSON response body.
## Generate Recovery Codes
This API is used to generate a list of Recovery Codes. When creating new codes, any existing Recovery Codes will be cleared and the new set will become the current values.
### Request
#### Request Parameters
The unique Id of the user to assign the generated Recovery Codes to.
### Response
The response for this API contains an array of size 10 of Recovery Codes that were created.
#### Response Body
The array of Recovery Codes.
## Retrieve Recovery Codes
This API is used to retrieve Recovery Codes for a User.
### Request
#### Request Parameters
The Id of the User to retrieve Recovery Codes for.
### Response
The response for this API contains the remaining Recovery Codes that are assigned to the User. Each time one is used it is removed, so this response will contain between 0 and 10 codes.
#### Response Body
The array of Recovery Codes.
# User Action Reasons
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import UserActionReasonRequestBody from 'src/content/docs/apis/_user-action-reason-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import UserActionReasonResponseBody from 'src/content/docs/apis/_user-action-reason-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import UserActionReasonsResponseBody from 'src/content/docs/apis/_user-action-reasons-response-body.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
## Overview
This page contains the APIs that are used to manage user action reasons. Here are the APIs:
## Create a User Action Reason
This API is used to create an User Action Reason. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the User Action Reason. Otherwise, FusionAuth will generate an Id for the User Action Reason.
### Request
#### Request Parameters
The Id to use for the new User Action Reason. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the information for the User Action Reason that was created.
## Retrieve a User Action Reason
This API is used to retrieve one or all of the configured User Action Reasons. Specifying an Id on the URI will retrieve a single User Action Reason. Leaving off the Id will retrieve all of the User Action Reasons.
### Request
#### Request Parameters
The Id of the User Action Reason to retrieve.
### Response
The response for this API contains either a single User Action Reason or all of the User Action Reasons. When you call this API with an Id the response will contain just that User Action Reason. When you call this API without an Id the response will contain all of the User Action Reasons. Both response types are defined below along with an example JSON response.
## Update a User Action Reason
### Request
#### Request Parameters
The Id of the User Action Reason to update.
### Response
The response for this API contains the new information for the User Action Reason that was updated.
## Delete a User Action Reason
This API is used to delete an User Action Reason. You must specify the Id of the User Action Reason on the URI.
### Request
#### Request Parameters
The Id of the User Action Reason to delete.
### Response
This API does not return a JSON response body.
# User Actions
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import UserActionRequestBody from 'src/content/docs/apis/_user-action-request-body.mdx';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import UserActionResponseBody from 'src/content/docs/apis/_user-action-response-body.mdx';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import UserActionsResponseBody from 'src/content/docs/apis/_user-actions-response-body.mdx';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
## Overview
This page contains the APIs for managing user actions. This API does not cover actually actioning users. Instead, this is the CRUD API to manage the user action definitions.
If you want to apply an existing user action to a user, see the [Actioning Users API](/docs/apis/actioning-users) and the guide on [how to use User Actions](/docs/lifecycle/manage-users/user-actions).
Here are the APIs:
## Create a User Action
This API is used to create an User Action. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the User Action. Otherwise, FusionAuth will generate an Id for the User Action.
### Request
#### Request Parameters
The Id to use for the new User Action. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the information for the User Action that was created.
## Retrieve a User Action
This API is used to retrieve one or all of the configured User Actions. Specifying an Id on the URI will retrieve a single User Action. Leaving off the Id will retrieve all of the User Actions.
### Request
#### Request Parameters
The Id of the User Action to retrieve.
### Response
The response for this API contains either a single User Action or all of the User Actions. When you call this API with an Id the response will contain just that User Action. When you call this API without an Id the response will contain all of the User Actions. Both response types are defined below along with an example JSON response.
## Update a User Action
### Request
#### Request Parameters
The Id of the User Action to update.
### Response
The response for this API contains the new information for the User Action that was updated.
## Delete a User Action
This API is used to delete an User Action. You must specify the Id of the User Action on the URI.
### Request
#### Request Parameters
The Id of the User Action to delete.
Whether or not the User Action is soft or hard deleted.
### Response
This API does not return a JSON response body.
## Reactivate a User Action
This API is used to reactivate an inactive User Action. You must specify the Id of the Application on the URI.
### Request
#### Request Parameters
The Id of the User Action to reactivate.
### Response
The response for this API contains the information for the User Action that was reactivated.
# User Comments
import API from 'src/components/api/API.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import JSON from 'src/components/JSON.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import Aside from 'src/components/Aside.astro';
import UserCommentSearchRequestParameters from 'src/content/docs/apis/_user-comment-search-request-parameters.mdx';
import InlineField from 'src/components/InlineField.astro';
## Overview
This page contains the APIs that are used for managing comments left by admins on user accounts.
## Add a Comment to a User
This API is used to add a User Comment to a User's account. User Comments are used to allow administrators and moderators the ability to take notes on Users.
### Request
#### Request Body
The text of the User Comment.
The Id of the User that wrote the User Comment.
The Id of the User that the User Comment was written for.
### Response
The response for this API contain the User Comment that was added to the User's account.
#### Response Body
The text of the User Comment.
The Id of the User that wrote the User Comment.
The [instant](/docs/reference/data-types#instants) when the comment was written. This was deprecated in 1.18.0. Use `insertInstant` instead.
The [instant](/docs/reference/data-types#instants) when the comment was written.
The Id of the User Comment.
The Id of the User that the User Comment was written for.
## Retrieve a User's Comments
This API is used to retrieve all of the User Comments on a User's account. User Comments are used to allow administrators and moderators the ability to take notes on Users.
### Request
#### Request Parameters
The Id of the User to retrieve the User Comments for.
### Response
The response for this API contains all of the User Comments for the User.
#### Response Body
The list of User Comment objects.
The text of the User Comment.
The Id of the User that wrote the User Comment.
The [instant](/docs/reference/data-types#instants) when the comment was written. This was deprecated in 1.18.0. Use `insertInstant` instead.
The Id of the User Comment.
The [instant](/docs/reference/data-types#instants) when the comment was written.
The Id of the User that the User Comment was written for.
## Search for User Comments
This API is used to search for User Comments and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
### Request Body
### Response
The response for this API contains the User Comments matching the search criteria in paginated format and the total number of results matching the search criteria.
#### Response Body
The total number of User Comments matching the search criteria. Use this value along with the numberOfResults and startRow in the search request to perform pagination.
The list of User Comment objects.
The text of the User Comment.
The Id of the User that wrote the User Comment.
The Id of the User Comment.
The [instant](/docs/reference/data-types#instants) when the comment was written.
The Id of the User that the User Comment was written for.
# Users
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import API from 'src/components/api/API.astro';
import Aside from 'src/components/Aside.astro';
import DeprecatedSince from 'src/components/api/DeprecatedSince.astro';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import ImportUsersRequestBody from 'src/content/docs/apis/_import-users-request-body.mdx';
import InlineField from 'src/components/InlineField.astro';
import LoginIdField from 'src/content/docs/apis/_login-id-field.mdx';
import LoginIdTypeField from 'src/content/docs/apis/_login-id-type-field.mdx';
import LoginMetadataDevice from 'src/content/docs/apis/_login-metadata-device.mdx';
import JSON from 'src/components/JSON.astro';
import PremiumPlanBlurbApi from 'src/content/docs/_shared/_premium-plan-blurb-api.astro';
import EnterprisePlanBlurbApi from 'src/content/docs/_shared/_enterprise-plan-blurb-api.astro';
import {RemoteCode} from '@fusionauth/astro-components';
import SearchPreprocessingWarning from "src/content/docs/_shared/_search-preprocessing-warning.mdx";
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardPutResponseCodes from 'src/content/docs/apis/_standard-put-response-codes.astro';
import UserBulkDeleteRequestBody from 'src/content/docs/apis/_user-bulk-delete-request-body.mdx';
import UserBulkDeleteResponseBody from 'src/content/docs/apis/_user-bulk-delete-response-body.mdx';
import UsersRefreshTokensRequestBody from 'src/content/docs/apis/_users-refresh-tokens-request-body.mdx';
import UserRequestBody from 'src/content/docs/apis/_user-request-body.mdx';
import UserResponseBody from 'src/content/docs/apis/_user-response-body.mdx';
import UserSearchRequestBodyDatabaseExamples from 'src/content/docs/apis/_user-search-request-body-database-examples.mdx';
import UserSearchRequestBodyElasticsearchExamples from 'src/content/docs/apis/_user-search-request-body-elasticsearch-examples.mdx';
import UserSearchRequestParameters from 'src/content/docs/apis/_user-search-request-parameters.mdx';
import UsersResponseBody from 'src/content/docs/apis/_users-response-body.mdx';
import XFusionauthTenantIdHeaderAmbiguousOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-ambiguous-operation.mdx';
import XFusionauthTenantIdHeaderCreateOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-create-operation.mdx';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import ChangePassPostResponseCodes from 'src/content/docs/apis/_change-pass-post-response-codes.astro';
import ChangePassGetResponseCodes from 'src/content/docs/apis/_change-pass-get-response-codes.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
This page contains all of the APIs for managing users.
## Create a User
This API is used to create a new User.
### Request
#### Request Parameters
The Id to use for the new User. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the User that was just created. The password, salt and other sensitive fields will not be returned on the API response.
## Retrieve a User
This API is used to retrieve the information about a single User. You can use the User's Id, username or email address to retrieve the User. The Id is specified on the URI and the username or email are specified as URL parameters.
### Request
#### Request Parameters
The unique Id of the User to retrieve.
#### Request Parameters
The unique Id of the User to retrieve. The loginId can be either the email or username.
#### Request Parameters
#### Request Parameters
The email of the User to retrieve.
#### Request Parameters
The username of the User to retrieve.
#### Request Parameters
The change password Id associated with the user when the Forgot Password workflow has been started.
#### Request Parameters
The verification Id associated with the user when the Email or Phone number verification process has been started.
### Response
The response for this API contains the User.
## Update a User
If you specify a new password for the User, it will be encrypted and stored. However, if you do not provide a new password, the User's old password will be preserved. This is the only field that is merged during an update using the `PUT` method.
### Request
#### Request Parameters
The Id of the User to update.
### Response
The response for this API contains the User that was updated. The password hash and other sensitive fields are never returned on the API response.
## Delete a User
This API is used to delete a User. You must specify the Id of the User on the URI. You can also specify whether or not the User is soft or hard deleted. A soft delete deactivates the User. A hard delete permanently deletes a User's data.
Soft deleted users are marked as inactive but not deleted from FusionAuth. Deactivated users have their data retained but they are unable to authenticate. Users who have been deactivated can be reactivated; see [Reactivate a User](#reactivate-a-user) for more.
The data of a User who has been hard deleted is permanently removed from FusionAuth. The User's data cannot be restored via the FusionAuth API or the administrative user interface. If you need to restore the User's data, you must retrieve it from a database backup.
### Request
#### Request Parameters
The Id of the User to delete.
To Permanently delete a user from FusionAuth set this value to `true`. Once a user has been permanently deleted, the action cannot be undone. When this value is set to `false` the user is marked as inactive and the user will be unable log into FusionAuth. This action may be undone by reactivating the user.
### Response
This API does not return a JSON response body.
## Bulk Delete Users
This API is used to deactivate or delete multiple users in a single request.
### Request
#### Request Parameters
To preview the user Ids to be deleted by the request without applying the requested action set this value to `true`.
To Permanently delete a user from FusionAuth set this value to `true`. Once a user has been permanently deleted, the action cannot be undone. When this value is set to `false` the user is marked as inactive and the user will be unable log into FusionAuth. This action may be undone by reactivating the user.
The maximum number of users to delete in one call.
You may use this parameter to process deletes in batches in order to limit individual request processing time and the number of user Ids on the response.
The raw JSON Elasticsearch query that is used to search for Users. The userId, query, and queryString parameters are mutually exclusive, they are listed here in order of precedence.
It is necessary to use the query parameter when querying against `registrations` in order to achieve expected results, as this field is defined as a [nested datatype](https://www.elastic.co/guide/en/elasticsearch/reference/6.3/nested.html) in the Elasticsearch mapping.
The Elasticsearch query string that is used to search for Users to be deleted. The userId, query, and queryString parameters are mutually exclusive, they are listed here in order of precedence.
The Id of the User to delete. Repeat this parameter for each user to be deleted. The userId, query, and queryString parameters are mutually exclusive, they are listed here in order of precedence.
### Response
The response for this API contains the information for the Users that were affected by the request.
## Reactivate a User
This API is used to reactivate an inactive Users. You must specify the Id of the User on the URI.
### Request
#### Request Parameters
The Id of the User to reactivate.
### Response
The response for this API contains the information for the User that was reactivated.
## Import Users
This API is used to bulk import multiple Users into FusionAuth. Each User must have at least an **email** or a **username**, and a **password** (plaintext or hash). If you don't have the User's password, you can set this field to a long random string and require the User to reset their password at their next login. This request is useful for migrating data from an existing database into FusionAuth. Additionally, you can provide an Id for each User inside the JSON User object of the request body. When using this API, the recommended batch size per request is dependent on deployment scale (note: 100,000 users per request is a reasonable batch size for a production capable deployment). After completing an import, you should [reindex the Elasticsearch database](/docs/lifecycle/manage-users/search/search#reindexing-elasticsearch) as well.
You should not make multiple calls to this API in parallel. Multiple sequential calls to this API are fine.
### Request
### Response
Only a status code is available on the Import API, no JSON body will be returned.
## Password Hashes
Password hashes can be imported into FusionAuth. This allows users to transparently use their old passwords while at no time exposing the plaintext password. This section contains details about importing specific password hashes.
You can also learn more about hashes in the [password hashing reference](/docs/reference/password-hashes), and you can [implement your own custom hash](/docs/extend/code/password-hashes/custom-password-hashing) as well.
### Encoding
The standard FusionAuth password hashing schemes require the password hash to be a base64 encoded string. If your password hashes are encoded in a different format, they will need to either be converted and imported as base64, or you can create a custom plugin using an alternative encoding. You can see an example of converting below.
It is recommended to use a base64 encoded string, but if importing hashes from a legacy system that uses base16, base32, or another encoding, import the hash in the same format the plugin produces.
### Bcrypt
When importing a bcrypt hash, you may have a value such as:
`$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
This single string represents the bcrypt version, factor, salt and hash.
The number before the final `$` is the factor, the 22 characters after the final `$` is the salt and the last 31 characters are the hash.
For the above bcrypt hash, `10` is the factor and should be placed in the factor field. `N9qo8uLOickgx2ZMRZoMye` is the salt and should be placed in the salt field. `IjZAgcfl7p92ldGxad68LJZdL17lhWy` is the hash value and should be placed in the password field.
### MD5
When importing an MD5 password hash, you may not have a salt. If this is the case, use the empty string, `''`, as the salt. You may still use the salted MD5 plugin provided by FusionAuth.
MD5 is commonly stored in hexadecimal format, such as `25d55ad283aa400af464c76d713c07ad`. The FusionAuth Import Users API requires imported password hashes to be base64 encoded. Convert any hexadecimal values to base64 before importing, or the import will not work.
Here is an example ruby script to convert hexadecimal values to base64 encoded:
## Import Refresh Tokens
This API is used to import refresh tokens from an external system, this would generally be done during an initial user import or as an auxiliary step during a migration strategy.
Before using this API, create the Users, Applications and User Registrations. A validation error will be returned if the user does not exist, or is not registered for the application.
### Request
### Response
The response does not contain a body, the HTTP status code will indicate the result of the request.
## Search for Users
This API is used to search for Users.
This API may be called using the `GET` or `POST` HTTP methods, examples of each are provided below.
The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL.
Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
Which search query parameters are available and how they behave depends on the search engine type. Read more about [the different types of search engines](/docs/get-started/core-concepts/users#user-search).
### Database Search Engine
This is a good choice for [smaller installs, embedded scenarios, or other places where the additional capability of Elasticsearch is not required](/docs/get-started/core-concepts/users#database-search-engine).
#### Request Parameters
#### Request Body
##### Request Body Examples
### Elasticsearch Search Engine
The Elasticsearch engine has [advanced querying capabilities and better performance](/docs/get-started/core-concepts/users#elasticsearch-search-engine). You can also review the [Elasticsearch search guide](/docs/lifecycle/manage-users/search/user-search-with-elasticsearch) for more examples.
#### Request Parameters
#### Request Body
##### Request Body Examples
### Response
The response contains the User objects that were found as part of the lookup or search. Both the database and Elasticsearch search engines return the response in the same format.
## Flush the Search Engine
This API is used to issue a flush request to the FusionAuth Search. This will cause any cached data to be written to disk. In practice it is unlikely
you'll find a need for this API in production unless you are performing search requests immediately following an operation that modifies the index and
expecting to see the results immediately.
### Request
### Response
The response does not contain a body. It only contains one of the status codes below.
## Retrieve Recent Logins
This API is used to retrieve recent logins.
### Request
#### Request Parameters
This parameter indicates the maximum amount of logins to return for a single request.
This parameter provides the offset into the result set. Generally speaking if you wish to paginate the results, you will increment this parameter on subsequent API request by the size of the `limit` parameter.
This parameter will narrow the results to only logins for a particular user. When this parameter is omitted, the most recent logins for all of FusionAuth will be returned.
### Response
The response will contain recent logins containing no more than the value set by the `limit` parameter. By design, this API does not return the total number of results and only lets paginate through the results from newest to oldest.
#### Response Body
A list of recent logins.
The unique Id of the application that is represented by this login record.
The name of the application at the time this record was created.
The [instant](/docs/reference/data-types#instants) this login occurred.
The IP address if provided during the login request.
The city where the login request originated.
The country where the login request originated.
The latitude where the login request originated.
The longitude where the login request originated.
The geographic location where the login request originated.
The zipcode where the login request originated.
The User's email address or username at the time of the login request.
The unique Id of the user that is represented by this login record.
## Verify a User's Email
This API is used to mark a User's email as verified. This is usually called after the User receives the verification email after they register and they click the link in the email. To verify a User's phone number identity, see the [Identity Verify API](/docs/apis/identity-verify).
### Request
#### Request Parameters
The verification Id generated by FusionAuth used to verify the User's registration is valid by ensuring they have access to the provided email address.
This value can still be provided on the URL segment as shown in the above example, but it is recommended you send this value in the request body instead using the verificationId field. If the value is provided in the URL segment and in the request body, the value provided in the request body will be preferred.
#### Request Body
The short code used to verify the User's account is valid by ensuring they have access to the provided email address. This field is required when the email verification strategy on the Tenant is set to `Form field`.
The verification Id generated by FusionAuth used to verify the User's account is valid by ensuring they have access to the provided email address.
When using the `Form field` strategy for Email verification, this value is used along with the `oneTimeCode` as a pair to verify the email address.
If the verificationId is provided in the URL segment and in the request body, the value provided in the request body will be preferred.
This API can be used to mark a user as verified without requiring the user to actually complete a verification process.
#### Request Body
The unique Id of the user to mark verified.
### Response
The response does not contain a body. It only contains one of the status codes below.
## Resend Verification Email
This API is used to resend the verification email to a User. This API is useful if the User has deleted the email, or the verification Id has expired. By default, the verification Id will expire after 24 hours. You can modify this duration in the Tenant settings.
### Request
#### Request Parameters
The Id of the application. If valid, the email or message template configured in the Application settings will be used, if present. If not present, the template configured in the Tenant settings will be used. In either case, the corresponding Application object will be available to the template.
The email address used to uniquely identify the User.
#### Request Parameters
The Id of the application. If valid, the email or message template configured in the Application settings will be used, if present. If not present, the template configured in the Tenant settings will be used. In either case, the corresponding Application object will be available to the template.
The email address used to uniquely identify the User.
If you would only like to generate a new verificationId and return it in the JSON body without FusionAuth attempting to send the User an email
set this optional parameter to `false`.
This may be useful if you need to integrate the Email Verification process using a third party messaging service.
### Response
When authenticated using an API key a response body will be provided. If an API key was not used to authenticate the request no body is returned.
#### Response Body
The email verification Id that was generated by this API request. This identifier may be used by the [Verify a User's Email](#verify-a-users-email) API.
This field is only returned in the JSON response body if the request was authenticated using an API key, if an API key is not used no response body is returned.
Depending on your tenant configuration, this may be returned. The verification One Time Code is used with the gated Email Verification workflow. The user enters this code to verify their email.
## Start Forgot Password Workflow
This API is used to start the forgot password workflow for a single User.
For example, on your login form you may have a button for _Forgot your password_. This would be the API you would call to initiate the request for the user. If the email configuration is complete, the user will be sent the forgot password email containing a link containing the `changePasswordId`. The provided link should take the user to a form that allows them to change their password. This form should contain a hidden field for the `changePasswordId` generated by this API.
By default the `changePasswordId` is valid to be used with the [Change Password](#change-a-users-password) API for 10 minutes. If a `404` is returned when using this Id to change the password, the workflow
will need to be started again to generate a new identifier. This duration can be modified using the Tenant API or in the FusionAuth UI.
You may optionally authenticate this request with an API key to allow for some additional request parameters and the generated `changePasswordId` will be returned in the JSON body. This may be helpful if you wish to use your own email system or you have an alternative method to call the [Change Password](#change-a-users-password) API.
### Request
Calling this API without an API key always attempts to send a message to the user. If FusionAuth is unable to deliver a message based on the resolved identity and tenant configuration, a forgot password workflow will not be started.
#### Request Body
The Id of the application. If valid, the email or message template configured in the Application settings will be used, if present. If not present, the template configured in the Tenant settings will be used. In either case, the corresponding Application object will be available to the template.
An optional object that will be returned un-modified when you complete the forgot password request using the [Change a User's Password API](#change-a-users-password). This may be useful to return the user to particular state once they complete the password change.
#### Request Body
The Id of the application. If valid, the email or message template configured in the Application settings will be used, if present. If not present, the template configured in the Tenant settings will be used. In either case, the corresponding Application object will be available to the template.
The optional change password Id to be used on the [Change a User's Password](#change-a-users-password) API.
It is recommended to omit this parameter and allow FusionAuth to generate the identifier. Use this parameter only if you must supply your own value for integration into existing systems.
Whether or not calling this API should attempt to send the user an email using the configured Forgot Password email template. Setting this to `false` will begin the Forgot Password workflow without sending an email and only create the `changePasswordId`, this may be useful if you want to send an email outside of FusionAuth, or complete this workflow without the use of email.
Prefer using the new sendForgotPasswordMessage field.
Determines whether a forgot password message is sent to the user. Setting this to `true` will cause a message to be sent. Setting this to `false` will begin the Forgot Password workflow without sending a message and only create the `changePasswordId`, which may be useful if you want to send a message outside of FusionAuth, or complete this workflow without the use of email/SMS.
The template and delivery method are based on the type of the identity resolved by the request.
* FusionAuth will attempt to deliver the message via SMS when the provided login Id and type resolve to a phone number identity. This requires tenant.phoneConfiguration.forgotPasswordTemplateId to be configured, otherwise the request will fail.
* If the provided login Id and type resolve to an email or username identity, FusionAuth will attempt to deliver the message via email. This requires tenant.emailConfiguration.forgotPasswordEmailTemplateId to be configured, otherwise the request will fail.
An optional object that will be returned un-modified when you complete the forgot password request. This may be useful to return the user to particular state once they complete the password change.
### Response
{/*
this 'response codes' header has extra spacing, but to fix we'd have to convert the below table into a HTML table inside an astro component, like we did with astro/src/content/docs/apis/_change-pass-response-codes.astro
*/}
__Response Codes__
|Code |Description |
| --- | --- |
|200 |The request was successful. A JSON response body will be provided when authenticated using an API key, when the API key has been omitted from the request, no response body is provided. |
|400 |The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
|401 |You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
|403 |The forgot password functionality has been disabled. This is caused by an administrator setting the Forgot Password Email Template to the option _Feature Disabled. No template selected._ in the Tenant Email configuration. See Tenants -> Email -> Template settings in the FusionAuth admin UI. |
|404 |The User could not be found. |
|422 |The User does not have an email address, this request cannot be completed. Before attempting the request again add an email address to the user. |
|500 |There was an internal error. A stack trace is provided and logged in the FusionAuth log files. |
|503 |The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body.| |
#### Response Body
The change password Id that was generated by this API request. This identifier may be used by the [Change a User's Password](#change-a-users-password) API. This field is only returned in the JSON response body if the request was authenticated using an API key, if an API key is not used no response body is returned.
## Validate a password change
### Request
This API is used to validate whether a request to [change a user's password](#change-a-users-password) will require MFA (via a `trustToken`). There are 3 ways to call the endpoint:
1. Validate a `changePasswordId` without authentication
2. Validate user password change using a JWT
3. Validate user password change using a `loginId` with API key
The first case will also verify that a `changePasswordId` is valid. This usage is generally intended to be part of an email or SMS workflow and does not require authentication. The `changePasswordId` used on this API request will have been previously generated by the [Start Forgot Password API](#start-forgot-password-workflow) or by using the Forgot Password workflow on the FusionAuth login page. Use this API to validate the `changePasswordId` before requesting a password change.
#### Request Parameters
The `changePasswordId` that is used to identify the user after the [Start Forgot Password workflow](#start-forgot-password-workflow) has been initiated.
The IP address of the end-user that is changing their password. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. This value may be used by an MFA requirement lambda to determine if multi-factor authentication should be required.
The "Validate user password change using a JWT or `loginId`" cases are used to verify whether MFA is required to change a user's password based solely on the user's JWT or `loginId`. It does not validate a specific `changePasswordId` and is instead meant to validate whether MFA is required before [changing the user's password](#change-a-users-password) using a JWT or `loginId`.
#### Request Parameters
The IP address of the end-user that is changing their password. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. This value may be used by an MFA requirement lambda to determine if multi-factor authentication should be required.
#### Request Parameters
The IP address of the end-user that is changing their password. If this value is omitted FusionAuth will attempt to obtain the IP address of
the client, the value will be that of the `X-Forwarded-For` header if provided or the last proxy that sent the request. This value may be used by an MFA requirement lambda to determine if multi-factor authentication should be required.
### Response
This JSON response body will only be returned when a validation error occurs.
A successful response will not contain a response body.
## Change a User's Password
This API is used to change the User's password.
This API may be used as the second part of the [Start Forgot Password workflow](#start-forgot-password-workflow). For example, after the User is sent an email or SMS message that contains a link to a web form that allows them to update their password you will call this API with the `changePasswordId` and their updated password. If the `changePasswordId` is valid then the User's password will be updated.
This API may also be used separately from the [Start Forgot Password workflow](#start-forgot-password-workflow) by omitting the `changePasswordId` and using the `loginId` instead.
By default the `changePasswordId` is valid for 10 minutes after it was generated. If a `404` is returned when using the change password Id, the workflow will need to be started again to generate a new identifier. This duration can be modified using the [Tenant API](/docs/apis/tenants) or in the admin UI.
### Request
This usage is generally intended to be part of an email or SMS workflow and does not require authentication. The `changePasswordId` used on this API request will have been previously generated by the [Start Forgot Password workflow](#start-forgot-password-workflow) or by using the Forgot Password workflow on the FusionAuth login page.
#### Request Parameters
The `changePasswordId` that is used to identify the user after the [Start Forgot Password workflow](#start-forgot-password-workflow) has been initiated.
If this `changePasswordId` was sent via an email to the User by FusionAuth during User create in order to set up a new password, or as part of a Forgot Password request, then successful use of this identifier to change the User's password will implicitly complete Email Verification if not already verified and the Tenant configuration has enabled implicit email verification.
This value can still be provided on the URL segment as shown in the above example, but it is recommended you send this value in the request body instead using the changePasswordId field. If the value is provided in the URL segment and in the request body, the value provided in the request body will be preferred.
#### Request Body
The `changePasswordId` that is used to identify the user after the [Start Forgot Password workflow](#start-forgot-password-workflow) has been initiated.
If this `changePasswordId` was sent via an email to the User by FusionAuth during User create in order to set up a new password, or as part of a Forgot Password request, then successful use of this identifier to change the User's password will implicitly complete Email Verification if not already verified and the Tenant configuration has enabled implicit email verification.
If the changePasswordId is provided in the URL segment and in the request body, the value provided in the request body will be preferred.
The User's current password. When this parameter is provided the current password will be verified to be correct.
The User's new password.
This field is marked optional because it is only required when the user has enabled two-factor authentication, and a `trustChallenge` was provided on the Two-Factor Start API request. When a user has enabled two-factor authentication this field becomes required if a `trustChallenge` was provided on the Two-Factor Start API request. When required, this value must be equal to the value provided to the Two-Factor Start API.
This field is marked optional, because it is only required when the user has enabled two-factor authentication. When a user has enabled two-factor authentication this field becomes required when attempting to change a password using the `changePasswordId`.
This usage requires an API key and allows you to change any user's password if you have a unique login Id.
#### Request Body
An optional Application Id. When this value is provided, it will be used to resolve an application specific email or message template if you have configured transactional notifications such as setup password, email verification and others.
If not provided, only the tenant configuration will be used when resolving templates.
The User's current password. When this parameter is provided the current password will be verified to be correct.
When this value is provided it should be in place of the `changePasswordId` request parameter. If both the `changePasswordId` and `loginId` are provided on the request, the `changePasswordId` will take precedence.
}
/>
The User's new password.
This field is marked optional because it is only required when the user has enabled two-factor authentication, and a `trustChallenge` was provided on the Two-Factor Start API request. When a user has enabled two-factor authentication this field becomes required if a `trustChallenge` was provided on the Two-Factor Start API request. When required, this value must be equal to the value provided to the Two-Factor Start API.
This field is marked optional, because it is only required when the user has enabled two-factor authentication. When a user has enabled two-factor authentication this field becomes required when attempting to change a password using the `changePasswordId`.
This API will use a JWT as authentication. See [JWT Authentication](/docs/apis/authentication#jwt-authentication) for examples of how you can send the JWT to FusionAuth.
A common use case for using this API with a JWT will be if you want to allow the user to change their own password. Specifically if you are attempting to perform this request in a frontend browser that cannot store an API key.
Because changing a User's password will revoke all existing refresh tokens if you allow the user to change their password they will need to re-authenticate to stay logged into your application if you are utilizing JWTs and Refresh Tokens.
For this reason, this API will return a `oneTimePassword` that is intended to be used programatically after a Change Password request completes to keep the user logged in and provide a better user experience. A successful login will return you a new access token (JWT) and a refresh token. This will allow you to make the change password workflow seamless to the user.
#### Request Body
The User's current password. This is required when using a JWT to change your password.
The User's new password.
The user's existing refresh token. If you have access to your current refresh token, it can be provided in the request body using this parameter. If the `refresh_token` cookie also exists and is present on the request it will take precedence over this parameter.
This parameter is used to determine if the `oneTimePassword` that is returned from this API will be eligible to request a refresh token when used by the Login API. If this parameter is not provided and no cookie is found on the request, a refresh token will not be provided on the Login response when using the returned `oneTimePassword`.
This field is marked optional because it is only required when the user has enabled two-factor authentication, and a `trustChallenge` was provided on the Two-Factor Start API request. When a user has enabled two-factor authentication this field becomes required if a `trustChallenge` was provided on the Two-Factor Start API request. When required, this value must be equal to the value provided to the Two-Factor Start API.
This field is marked optional, because it is only required when the user has enabled two-factor authentication. When a user has enabled two-factor authentication this field becomes required when attempting to change a password using the `changePasswordId`.
### Response
#### Response Body
This JSON response body will only be returned when using a `changePasswordId` parameter or a JWT to change the password.
When calling this API with an API key no response body will be returned.
A one time password that can be used as a substitute for your `loginId` and `password` on the Login API.
An optional object that is returned un-modified when the forgot password request is completed. This may be useful to return the user to particular state once they complete the password change.
# WebAuthn
import LicensedPlanBlurb from 'src/content/docs/_shared/_licensed-plan-blurb.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import API from 'src/components/api/API.astro';
import Aside from 'src/components/Aside.astro';
import ImportWebauthnRequestBody from 'src/content/docs/apis/_import-webauthn-request-body.mdx';
import InlineField from 'src/components/InlineField.astro';
import LoginResponseCodes from 'src/content/docs/apis/_login-response-codes.mdx';
import {RemoteCode} from '@fusionauth/astro-components';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import UserResponseBody from 'src/content/docs/apis/_user-response-body.mdx';
import WebauthnAuthenticateCompleteRequestBody from 'src/content/docs/apis/_webauthn-authenticate-complete-request-body.mdx';
import WebauthnAuthenticateStartRequestBody from 'src/content/docs/apis/_webauthn-authenticate-start-request-body.mdx';
import WebauthnAuthenticateStartResponseBody from 'src/content/docs/apis/_webauthn-authenticate-start-response-body.mdx';
import WebauthnRegisterCompleteRequestBody from 'src/content/docs/apis/_webauthn-register-complete-request-body.mdx';
import WebauthnRegisterStartRequestBody from 'src/content/docs/apis/_webauthn-register-start-request-body.mdx';
import WebauthnRegisterStartResponseBody from 'src/content/docs/apis/_webauthn-register-start-response-body.mdx';
import WebauthnResponseBody from 'src/content/docs/apis/_webauthn-response-body.mdx';
import WebauthnsResponseBody from 'src/content/docs/apis/_webauthns-response-body.mdx';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import XFusionauthTenantIdRequired from 'src/content/docs/apis/_x-fusionauth-tenant-id-required.mdx';
## Overview
This page contains all of the APIs for managing WebAuthn passkeys, sometimes referred to as credentials, and starting and completing WebAuthn ceremonies.
The following APIs are provided to manage WebAuthn passkeys.
## Retrieve a Passkey
This API is used to retrieve information about a single WebAuthn passkey or all of a user's registered passkeys.
### Request
#### Request Parameters
The unique Id of the WebAuthn passkey to retrieve.
#### Request Parameters
The unique Id of the User to retrieve WebAuthn passkeys for.
### Response
The response for this API contains either a single Passkey or all of the Passkeys belonging to a User. When you call this API with an Id, the response will contain just that Passkey. When you call this API without an Id and provide a User Id in the query string, the response will contain all of the Passkeys belonging to that User. Both response types are defined below along with an example JSON response.
## Delete a Passkey
This API is used to delete a single WebAuthn passkey or all of a user's registered passkeys.
### Request
#### Request Parameters
The unique Id of the WebAuthn passkey to delete.
#### Request Parameters
The unique Id of the User to delete WebAuthn passkeys for.
### Response
This API does not return a JSON response body.
## Import Passkeys
This API is used to bulk import multiple passkeys into FusionAuth. Reasonable defaults are provided for optional fields. This request is useful for migrating data from an existing database into FusionAuth.
### Request
### Response
Only a status code is available on the Import API, no JSON body will be returned.
## WebAuthn JavaScript API Binary Format
The [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) `navigator.credentials.create()` and `navigator.credentials.get()` expect to receive fields containing binary data on the `options` object as a JavaScript [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) and will return binary fields as ``ArrayBuffer``s. In order to prevent encoding issues on the FusionAuth API, these fields are passed over the network as base64url-encoded strings.
Select fields on the `options` JSON object that is passed to the [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) must be converted from base64url-encoded strings to ``ArrayBuffer``s after receiving `options` from the FusionAuth API. Likewise, certain fields on [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) responses must be converted from ``ArrayBuffer``s to base64url-encoded strings before calling FusionAuth's APIs to complete the ceremony.
### Converting base64url-encoded String to `ArrayBuffer`
Converting a base64url-encoded strings to ``ArrayBuffer``s is required before the `options` JSON object from [Start a WebAuthn Passkey Registration](#start-a-webauthn-passkey-registration) or [Start a WebAuthn Passkey Assertion or Authentication](#start-a-webauthn-passkey-assertion-or-authentication) responses are passed to the [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API). The FusionAuth hosted pages will perform this conversion as necessary. If you need to perform this conversion yourself, you can use the following JavaScript function.
Fields that require this conversion are documented in the [Start a WebAuthn Passkey Registration](#start-a-webauthn-passkey-registration) and [Start a WebAuthn Passkey Assertion or Authentication](#start-a-webauthn-passkey-assertion-or-authentication) response sections.
### Converting `ArrayBuffer` to base64url-encoded String
Converting ``ArrayBuffer``s to base64url-encoded strings is required before the responses from the [WebAuthn JavaScript APIs](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) are sent to FusionAuth's [Complete a WebAuthn Passkey Registration](#complete-a-webauthn-passkey-registration), [Complete a WebAuthn Passkey Authentication](#complete-a-webauthn-passkey-authentication), or [Complete a WebAuthn Passkey Assertion](#complete-a-webauthn-passkey-assertion) APIs. The FusionAuth hosted pages will perform this conversion as necessary. If you need to perform this conversion yourself, you can use the following JavaScript function.
Fields that require this conversion are documented in the [Complete a WebAuthn Passkey Registration](#complete-a-webauthn-passkey-registration), [Complete a WebAuthn Passkey Authentication](#complete-a-webauthn-passkey-authentication), and [Complete a WebAuthn Passkey Assertion](#complete-a-webauthn-passkey-assertion) request sections.
## Start a WebAuthn Passkey Registration
This API is used to start a WebAuthn registration ceremony by providing some details about the current user and the new passkey. The response is a JSON object which is suitable to be passed to the [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) `navigator.credentials.create()` function and includes a one-time challenge unique to the current registration ceremony.
### Request
### Response
## Complete a WebAuthn Passkey Registration
This API is used to complete a WebAuthn registration ceremony by providing the values returned from the [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) call. The API will validate the request against configured passkey requirements for the workflow and the one-time challenge generated and returned by [Start a WebAuthn Passkey Registration](#start-a-webauthn-passkey-registration).
### Request
### Response
## Start a WebAuthn Passkey Assertion or Authentication
This API is used to start a WebAuthn authentication ceremony by providing some details about the current user and the new passkey. The response is a JSON object which is suitable to be passed to the [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) `navigator.credentials.get()` function and includes a one-time challenge unique to the current ceremony. This same API is used to start a WebAuthn assertion that validates a passkey signature without authenticating the user.
### Request
### Response
## Complete a WebAuthn Passkey Authentication
This API is used to complete a WebAuthn authentication ceremony by providing the values returned from the [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) call. The API will validate the request against configured passkey requirements for the workflow and the one-time challenge generated and returned by [Start a WebAuthn Passkey Assertion or Authentication](#start-a-webauthn-passkey-assertion-or-authentication).
### Request
#### Request Cookies
The Multi-Factor Trust identifier returned by the Multi-Factor Login API response. This value may be provided to bypass the Multi-Factor challenge when a User has Multi-Factor enabled. When this cookie exists on the request it will take precedence over the twoFactorTrustId if provided in the request body.
### Response
The response for this API contains the User object.
## Complete a WebAuthn Passkey Assertion
This API is used to validate a WebAuthn authentication ceremony by providing the values returned from the [WebAuthn JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) call, but it does not authenticate the user. This API can be used to confirm that a user has access to a particular passkey without authenticating them.
### Request
### Response
The response for this API contains the WebAuthn passkey used to complete the assertion.
# Webhook Event Logs
import API from 'src/components/api/API.astro';
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 JSON from 'src/components/JSON.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import WebhookAttemptLogResponseBody from 'src/content/docs/apis/_webhook-attempt-log-response-body.mdx';
import WebhookEventLogResponseBody from 'src/content/docs/apis/_webhook-event-log-response-body.mdx';
import WebhookEventLogSearchResponseBody from 'src/content/docs/apis/_webhook-event-log-search-response-body.mdx';
## Overview
The Webhook Event Log contains a record of [Events](/docs/extend/events-and-webhooks/events) sent by FusionAuth, including request payloads. It also records attempts to send the event payload to [Webhook](/docs/extend/events-and-webhooks) and [Kafka](/docs/extend/events-and-webhooks/kafka) endpoints.
Test events sent through the FusionAuth admin UI are not recorded in the Webhook Event Log.
This page contains the APIs that are used to retrieve Webhook Event Logs and associated attempt details. Here are the APIs:
## Retrieve a Webhook Event Log
### Request
#### Request Parameters
The unique Id of the Webhook Event Log to retrieve.
### Response
## Retrieve a Webhook Attempt Log
### Request
#### Request Parameters
The unique Id of the Webhook Attempt Log to retrieve.
### Response
## Search Webhook Event Logs
### Request
When calling the API using a `GET` request you will send the search criteria on the URL using request parameters. In order to simplify the example URL above, not every possible parameter is shown, however using the provided pattern you may add any of the documented request parameters to the URL.
#### Request Parameters
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
If the current time is 2:01:01, this default would be 2:02:00.
Prior to version `1.57.0` this field did not have a default.
The string to search in the Webhook Event Log request body for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The overall result of a [transactional](/docs/extend/events-and-webhooks/events#transaction-compatibility) event. Possible values are:
* `Running` - The default state after an event is fired.
* `Succeeded` - The transactional event was successful, and pending database changes were committed. Non-transactional events are transitioned to this state immediately after the event payload is sent to all recipients regardless of the response.
* `Failed` - The transactional event was unsuccessful, and pending database changes were rolled back.
The event type.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `eventResult` - the overall result of the event
* `eventType` - the event type
* `id` - the unique Id of the Webhook Event Log
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Webhook Event Log was created
* `lastAttemptInstant` - the [instant](/docs/reference/data-types#instants) when the last attempt was made to deliver the event
* `linkedObjectId` - the unique Id of the object associated with this event
* `sequence` - the system-assigned event sequence
For example, to order the results by the insert instant in a descending order, the value would be provided as `insertInstant DESC`. The final string is optional can be set to `ASC` or `DESC`.
Prior to version `1.57.0` this defaults to `sequence DESC`.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
If the current time is 2:01:01, this default would be 1:01:00.
Prior to version `1.57.0` this field did not have a default.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
#### Request Body
The end [instant](/docs/reference/data-types#instants) of the date/time range to search within.
If the current time is 2:01:01, this default would be 2:02:00.
Prior to version `1.57.0` this field did not have a default.
The string to search in the Webhook Event Log request body for. This can contain wildcards using the asterisk character (`*`). If no wildcards are present, this parameter value will be interpreted as `*value*`.
The overall result of a [transactional](/docs/extend/events-and-webhooks/events#transaction-compatibility) event. Possible values are:
* `Running` - The default state after an event is fired.
* `Succeeded` - The transactional event was successful, and pending database changes were committed. Non-transactional events are transitioned to this state immediately after the event payload is sent to all recipients regardless of the response.
* `Failed` - The transactional event was unsuccessful, and pending database changes were rolled back.
The event type.
The number of results to return from the search.
The database column to order the search results on plus the order direction.
The possible values are:
* `eventResult` - the overall result of the event
* `eventType` - the event type
* `id` - the unique Id of the Webhook Event Log
* `insertInstant` - the [instant](/docs/reference/data-types#instants) when the Webhook Event Log was created
* `lastAttemptInstant` - the [instant](/docs/reference/data-types#instants) when the last attempt was made to deliver the event
* `linkedObjectId` - the unique Id of the object associated with this event
* `sequence` - the system-assigned event sequence
For example, to order the results by the insert instant in a descending order, the value would be provided as `insertInstant DESC`. The final string is optional can be set to `ASC` or `DESC`.
Prior to version `1.57.0` this defaults to `sequence DESC`.
The start [instant](/docs/reference/data-types#instants) of the date/time range to search within.
If the current time is 2:01:01, this default would be 1:01:00.
Prior to version `1.57.0` this field did not have a default.
The offset row to return results from. If the search has 200 records in it and this is 50, it starts with row 50.
### Response
The response for this API contains the Webhook Event Logs matching the search criteria in paginated format.
# Webhooks
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import API from 'src/components/api/API.astro';
import Aside from 'src/components/Aside.astro';
import GenericUpdateExplanationFragment from 'src/content/docs/apis/_generic-update-explanation-fragment.mdx';
import StandardDeleteResponseCodes from 'src/content/docs/apis/_standard-delete-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import WebhookRequestBody from 'src/content/docs/apis/_webhook-request-body.mdx';
import WebhookResponseBody from 'src/content/docs/apis/_webhook-response-body.mdx';
import WebhooksResponseBody from 'src/content/docs/apis/_webhooks-response-body.mdx';
import WebhookSearchRequestParameters from 'src/content/docs/apis/_webhook-search-request-parameters.mdx';
## Overview
A FusionAuth Webhook is intended to consume JSON events emitted by FusionAuth. Creating a Webhook allows you to tell
FusionAuth where you would like to receive these JSON events.
Webhooks provides a publish - subscribe style integration with FusionAuth. Creating a Webhook is the subscribe portion
of this common messaging pattern. If you're already using Kafka for consuming messages in your infrastructure, see our
[Kafka](/docs/extend/events-and-webhooks/kafka) integration as well.
These APIs that are used to manage Webhooks.
## Create a Webhook
This API is used to create a Webhook. Specifying an Id on the URI will instruct FusionAuth to use that Id when creating the Webhook. Otherwise, FusionAuth will create a Id for the Webhook automatically.
### Request
#### Request Parameters
The Id to use for the new Webhook. If not specified a secure random UUID will be generated.
### Response
The response for this API contains the information for the Webhook that was created.
## Retrieve a Webhook
This API is used to retrieve one or all of the configured Webhooks. Specifying an Id on the URI will retrieve a single Webhook. Leaving off the Id will retrieve all of the Webhooks.
### Request
#### Request Parameters
The Id of the Webhook to retrieve.
### Response
The response for this API contains either a single Webhook or all of the Webhooks. When you call this API with an Id the response will contain just that Webhook. When you call this API without an Id the response will contain all of the Webhooks. Both response types are defined below along with an example JSON response.
## Update a Webhook
### Request
#### Request Parameters
The Id of the Webhook to update.
### Response
The response for this API contains the new information for the Webhook that was updated.
## Delete a Webhook
This API is used to delete a Webhook.
### Request
#### Request Parameters
The Id of the Webhook to delete.
### Response
This API does not return a JSON response body.
## Search for Webhooks
This API is used to search for Webhooks and may be called using the `GET` or `POST` HTTP methods. Examples of each are provided below. The `POST` method is provided to allow for a richer request object without worrying about exceeding the maximum length of a URL. Calling this API with either the `GET` or `POST` HTTP method will provide the same search results given the same query parameters.
### Request
### Request Parameters
When calling the API using a `POST` request you will send the search criteria in a JSON request body.
### Request Body
### Response
The response for this API contains the Webhooks matching the search criteria in paginated format and the total number of results matching the search criteria.
# Pre 1.26 Two Factor APIs (Deprecated)
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import XFusionauthTenantIdHeaderScopedOperation from 'src/content/docs/apis/_x-fusionauth-tenant-id-header-scoped-operation.mdx';
import InlineField from 'src/components/InlineField.astro';
import JSON from 'src/components/JSON.astro';
import StandardPostResponseCodes from 'src/content/docs/apis/_standard-post-response-codes.astro';
import StandardGetResponseCodes from 'src/content/docs/apis/_standard-get-response-codes.astro';
## Overview
## Enable Two Factor
This API is used to enable Two Factor authentication for a single User. To use this API the User must provide a valid
Two Factor verification code.
To enable using `TextMessage` delivery, you may use the [Two Factor Send](/docs/apis/two-factor#send-a-multi-factor-code-when-enabling-mfa) API to deliver a
code to the User, the User will then provide this code as input.
### Request
#### Request Parameters
The Id of the User to enable Two Factor authentication.
#### Request Body
A valid Two Factor verification code. This value should be provided by the User to verify they are able to produce codes using
an application or receive them using their mobile phone.
The User's preferred delivery for verification codes during a two factor login request.
The possible values are:
* `None`
* `TextMessage`
When using `TextMessage` the User will also need a valid `mobilePhone`. The User's mobile phone is not validated during this request. Because the `code` is provided on this request it is assumed the User has been able to receive a `code` on their mobile phone when setting the delivery to `TextMessage`.
A base64 encoded secret.
You may optionally use the secret value returned by the [Two Factor Secret](/docs/apis/two-factor#generate-a-secret) API instead of generating this value yourself. This value is a secure random byte array that is Base-64 encoded.
If you omit this field, then secretBase32Encoded is required.
A base32 encoded secret.
You may optionally use the secretBase32Encoded value returned by the [Two Factor Secret](/docs/apis/two-factor#generate-a-secret) API instead of generating this value yourself. This value is a secure random byte array that is Base-32 encoded.
If you omit this field, then secret is required.
### Response
_Response Codes_
| Code | Description |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. Two Factor has been enabled for the User. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
| 404 | The User does not exist. The response will be empty. |
| 421 | The `code` request parameter is not valid. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
## Disable Two Factor
This API is used to disable Two Factor authentication for a single User. To use this API the User must provide a valid
Two Factor verification code.
If the User has configured `TextMessage` delivery, you may use the [Two Factor Send](/docs/apis/two-factor#send-a-multi-factor-code-when-enabling-mfa) API to deliver a
code to the User, the User will then provide this code as input.
### Request
#### Request Parameters
The Id of the User to enable Two Factor authentication.
The time based one time use password, also called a Two Factor verification code.
#### Request Parameters
The time based one time use password, also called a Two Factor verification code.
### Response
_Response Codes_
| Code | Description |
|------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 200 | The request was successful. Two Factor has been disabled for the User. |
| 400 | The request was invalid and/or malformed. The response will contain an [Errors](/docs/apis/errors) JSON Object with the specific errors. |
| 401 | You did not supply a valid Authorization header. The header was omitted or your API key was not valid. The response will be empty. See [Authentication](/docs/apis/authentication). |
| 404 | The User does not exist. The response will be empty. |
| 421 | The `code` request parameter is not valid. The response will be empty. |
| 500 | There was an internal error. A stack trace is provided and logged in the FusionAuth log files. The response will be empty. |
| 503 | The search index is not available or encountered an exception so the request cannot be completed. The response will contain a JSON body. |
## Send a Two Factor Code
This API is used to send a Two Factor verification code to a User. This may be useful during Two Factor authentication if the initial
code is no longer valid. It may be also used to send a code to a User to assist in enabling or disabling Two Factor authentication.
To send a code to a User that already has Two Factor enabled, it is not required they have `TextMessage` set as their preferred delivery.
As long as the User has a mobile phone defined you may send the User a code.
This API requires that the [Twilio](/docs/customize/email-and-messages/deprecated/twilio) integration is enabled and configured properly.
### Request
This request is intended to be used to send a Two Factor code to a User that already has enabled Two Factor authentication to assist in disabling Two Factor authentication. The User must already have Two Factor enabled and have a valid mobile phone for this to succeed.
#### Request Body
The User Id of the User to send a Two Factor verification code. This User is expected to already have Two Factor enabled.
This request is intended to be used to send a Two Factor code to a User to assist in enabling Two Factor authentication.
#### Request Body
A mobile phone to send the Two Factor verification code.
The Two Factor secret used to generate a Two Factor verification code to send to the provided mobile phone.
You may optionally use value provided in the `secret` field returned by the [Two Factor Secret](/docs/apis/two-factor#generate-a-secret) API instead of generating this value yourself.
This request is intended to send additional messages to the User's mobile phone during login.
#### Request Parameters
The `twoFactorId` returned by the Login API.
This request is intended to be used to send a Two Factor code to a User that already has enabled Two Factor authentication to assist
in disabling Two Factor authentication. When using JWT authentication the User's Id is retrieved from the JWT. The User must already have
Two Factor enabled and have a valid mobile phone for this to succeed.
### Response
## Generate a Secret
This API is used to generate a new Two Factor secret for use when enabling Two Factor authentication for a User. This is provided
as a helper to assist you in enabling Two Factor authentication.
If this secret will be used with a QR code to allow the User to scan the value it will need utilize the Base32 encoded value returned in
the response.
### Request
### Response
The response for this API contains the a Two Factor secret.
#### Response Body
A Base64 encoded secret that may be used to enable Two Factor authentication.
A Base32 encoded form of the provided secret. This useful if you need to provide a QR code to the User to enable Two Factor authentication.
# Configure The SMTP Server
import Aside from 'src/components/Aside.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
## Overview
Before you can use email templates and other email features in FusionAuth, you must first enable and configure a Simple Mail Transfer Protocol (SMTP) server.
This guide briefly explains SMTP security and SMTP providers, describes in detail how to configure the most popular SMTP providers with FusionAuth, and lists best practices to consider when working with email.
SMTP providers handle two types of email: marketing (like newsletters and sale advertisements) and transactional (like account notifications and password resets). FusionAuth is concerned only with transactional email.
## Understand Email Security
Email service providers (ESPs) such as Gmail, Yahoo Mail, and Proton Mail rely on several methods to prevent spam and phishing emails from being sent to their users. As of 2024, these methods have become even stricter. Google [requires SMTP providers to allow users to send only from their own registered domains](https://help.brevo.com/hc/en-us/articles/14925263522578-Prepare-for-Gmail-and-Yahoo-s-new-requirements-for-email-senders) to reduce spam.
Here are the ways ESPs implement email security:
- **Rate limits:** Emails that are received too frequently or show sudden spikes in volume are blocked.
- **IP address block lists:** Emails received from dynamic IP addresses, those known to send spam, or those with a low reputation are added to lists that receivers use to reject mail.
- **DNS records of email senders:** Emails must have valid records for Sender Policy Framework (SPF) (RFC 7208), Domain Keys Identified Mail (DKIM) (RFC 6376), and Domain-based Message Authentication, Reporting, and Conformance (DMARC) (RFC 7489).
SPF, DKIM, and DMARC are TXT records you need to add to the DNS records for your domain. Your SMTP provider will tell you what records to add.
- An SPF record looks like `v=spf1 ip4:129.6.100.200 ip6:2610:20:6005:100::20 -all` and lists the IP addresses permitted to send email on behalf of the domain. ESPs should reject emails arriving from an IP address other than these.
- A DKIM record looks like `k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQ8c7wIDAQAB` and specifies a public key. The SMTP provider will sign the sender address of an email with the corresponding private key. ESPs should reject emails with an invalid sender address signature.
- A DMARC record looks like `v=DMARC1; p=none; rua=mailto:rua@dmarc.brevo.com` and specifies the policies supported by the email sender and where to send rejected email for analysis by the sender.
Together, these three records allow an ESP to know that the email server and sender are valid and what responses the sender supports if an invalid email is received.
You might also encounter the term Author Domain Signing Practices (ADSP), an optional extension to DKIM that enables a domain to publish the signing practices it adopts when relaying mail on behalf of associated authors.
## Which Provider To Choose?
An SMTP provider is an online service that sends email on your behalf. In return for payment, an SMTP provider guarantees you a service that provides IP addresses with a high reputation.
Some providers are easy to test, requiring nothing more than registering with an email address. Others require comprehensive company details, your verified phone number, domain verification, having a professional business website, and communicating with support agents. The easiest providers to configure are:
- MailerSend — Requires only an email address.
- Gmail — Requires phone verification, and email is intended only for small tests. Not for production use.
- AWS SES — Requires email and domain verification.
- Postmark — Requires email and domain verification.
- Resend — Requires email and domain verification.
Postmark had especially clear documentation and an easy setup experience.
The more difficult providers are:
- Brevo
- Mailgun (Sinch)
- SendGrid (Twilio)
These providers automatically disable your account on signup and require you to contact their support to have it activated. This involves having a business website ready for review, explaining what your purpose in sending email is, and explaining how you obtained your recipients' email addresses. However, Mailgun and Brevo support were friendly and quick, and unlocked the FusionAuth test account after reasonable discussion. SendGrid is the most onerous provider, with full company details needed for every sender address.
The worst provider is Mailchimp (Mandrill). Mailchimp was the only SMTP provider that refused to provide FusionAuth an account, giving no explanation and accusing us of sharing prohibited content. Mailchimp support was poor — entirely automated, and no human could be contacted.
Be aware that providers can cancel your account at any time, without explanation or a chance to appeal. This can cripple your business.
Choose an SMTP provider that you feel is trustworthy. At the time of writing, these were the scores on https://www.trustpilot.com for each provider in this guide:
| Provider | Score | Link |
|----------------------|-----------|-----------------------------------------------------|
| Mailgun (Sinch) | 4.4 | https://www.trustpilot.com/review/mailgun.com |
| Brevo | 4.2 | https://www.trustpilot.com/review/www.brevo.com |
| Postmark | 3.5 | https://www.trustpilot.com/review/postmarkapp.com |
| Resend | 3.2 | https://www.trustpilot.com/review/resend.com |
| MailerSend | 2.8 | https://www.trustpilot.com/review/mailersend.com |
| Mailchimp (Mandrill) | 1.3 | https://www.trustpilot.com/review/www.mailchimp.com |
| SendGrid (Twilio) | 1.2 | https://www.trustpilot.com/review/sendgrid.com |
| AWS SES | No review | |
These scores, especially the low ones for Mailchimp and SendGrid, are consistent with the experiences we had writing this guide.
When comparing pricing, note that some providers charge a flat monthly fee, and some charge only for the number of emails you send. One provider might be cheaper than another for small volumes of email, but more expensive for large volumes.
## Can You Use A Self-Hosted SMTP Server?
It is possible to send email through an SMTP server hosted on your server using an application like [Postfix](https://www.postfix.org/documentation.html), [Haraka](https://haraka.github.io/getting_started), [mailcow](https://docs.mailcow.email/), or [Mail-in-a-Box](https://mailinabox.email/guide.html). Hosting your own server will cost you nothing more than a few dollars a month for a cloud server, or nothing if you already have a server for other applications.
However, over time, hosting your own SMTP server will almost certainly cost you more time and money than paying a dedicated email company to handle mail for you. Below are some things you'll need to handle if you want to self-host:
- Deliverability: Email service providers block or filter emails from dynamic IP addresses and untrusted servers. You need to maintain IP reputation, implement SPF, DKIM, and DMARC properly, and handle feedback loops with ESPs (bounces and spam requests).
- Scalability: As email volume grows, you need to scale your infrastructure.
- Technical expertise: Properly configuring and maintaining an email server requires understanding both the software and the network infrastructure. You need to continuously monitor your server and ensure it is available with 100% uptime.
- Security: Your server must be secured against unauthorized access and data must be protected against breaches, requiring regular security audits and updates.
Using your own SMTP server is appropriate if you are using FusionAuth for a hobby project or a small team where all users know to check their spam folders.
## SMTP Settings
Below are descriptions of the SMTP settings you will configure in FusionAuth in the following section.
The hostname of the SMTP server. This will be provided by your SMTP provider.
The port of the SMTP server. This will be provided by your SMTP provider. Ports `25`, `465`, and `587` are well-known ports used by SMTP, but your provider may use a different port.
In most cases, you will use TLS to connect to your SMTP server and the port will be `587` or `465`.
The username used to authenticate with the SMTP server. This will be provided by your SMTP provider.
When enabled, you may modify the password used to authenticate with the SMTP server. When the Password field is not displayed, the current password cannot be modified.
The new password to use for outgoing SMTP mail server authentication. This field is only required when Change password is checked.
The security type when using an SSL connection to the SMTP server. This value should be provided by your SMTP provider.
Generally, you will select `None` if using port `25`, `SSL` if using port `465`, and `TLS` if using port `587`. Your provider may be different; follow your provider's instructions.
* `None`
* `SSL`
* `TLS`
The default `From Address` used when sending emails if a from address is not provided for an individual email template. This is an email address (for example, **jared@piedpiper.com**).
The default `From Name` used when sending emails if a from name is not provided on an individual email template. This is the display name part of the email address (for example, **Jared Dunn** <jared@piedpiper.com>).
One or more line-separated SMTP headers to be added to each outgoing email. The header name and value should be separated by an equals sign, for example, `X-SES-CONFIGURATION-SET=Value`.
When enabled, SMTP and JavaMail debug information will be output to the Event Log.
## How To Configure SMTP Providers In FusionAuth
To enable and configure the FusionAuth SMTP server, navigate to Tenants -> Edit -> Email.
Enable email by clicking on the *Enabled* toggle, and save your settings once you have completed your configuration.
To avoid disrupting your application's current DNS records, you may want to point FusionAuth SMTP fields to a temporary subdomain. For example, if your application is hosted at `myapp.com`, you can create `testemail.myapp.com`, and point the SMTP service and FusionAuth there while testing.
Strict SMTP providers require you to have a trustworthy-looking domain and website before they activate your account.
There is a troubleshooting section below this one if you encounter errors while trying to send a test email.
The SMTP providers are presented in alphabetical order below.
### AWS SES
- Create an account at https://aws.amazon.com.
- In your account dashboard, search for SES and start the account setup wizard by clicking Get set up on the left sidebar.
- Add your email and domain.
- Verify your email when AWS emails you a link.
- Add the DNS records AWS SES gives you to your domain's DNS settings.
- After a few minutes, the SES Verify sending domain status should change from `Verification pending` to `Verified`.
- Browse to SMTP settings in the AWS sidebar.
- Click Create SMTP credentials and note the created SMTP credentials.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `email-smtp.eu-west-1.amazonaws.com` (use your host from the SMTP settings page)
- Port: `587`
- Username: Your username from the SMTP credentials page
- Password: Your SMTP password from the credentials page
- Security: `TLS`
- Default from address: `me@myapp.com` (use your verified domain)
- Click Send test email to test that the settings work. You must send to an email address verified with SES. Use the address you gave when creating your SES account.
- Click the save icon at the top right.
SES is more complicated than the other SMTP services. If the troubleshooting section at the bottom of this article does not help you, please consult the [SES documentation](https://docs.aws.amazon.com/ses/latest/dg/troubleshoot-verification.html).
### Brevo (Previously Sendinblue)
- Create an account at https://app.brevo.com.
- If Brevo suspends your account for violating the terms of service, contact support on [this page](https://www.brevo.com/contact) to activate it.
- Browse to https://app.brevo.com/senders/domain/list.
- Add your domain name.
- In your website domain manager, add the DNS records from the domain authentication page.
- Once you have entered the DNS records and saved, start the verification process on the Brevo page. It should take a minute.
- Browse to https://app.brevo.com/senders/list.
- Add sender: `me@myapp.com` (use your domain name).
- In Brevo, authenticate your email address.
- Browse to https://app.brevo.com/settings/keys/smtp and note your SMTP settings.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp-relay.brevo.com`
- Port: `587`
- Username: Your Brevo SMTP login from the settings page
- Password: Your SMTP key value from the settings page
- Security: `TLS`
- Default from address: Any address is allowed
- Click Send test email to test that the settings work, then click the save icon at the top right.
### Gmail
As well as being a popular ESP, Gmail can be used by programs to send email through SMTP. Gmail is not recommended for production use, since it has a [number of limits](https://support.google.com/a/answer/166852). However, it can be useful to test email functionality.
For Gmail, use [application passwords](https://support.google.com/accounts/answer/185833) or you may get a generic `Unable to send email via JavaMail / Prime Messaging Exception` error. The application passwords support article says you need to enable two-factor authentication, then create an app password on the security tab. However, there is no `App password` setting on the tab. You need to browse to https://myaccount.google.com/apppasswords manually to create one.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp.gmail.com`
- Port: `587`
- Username: Your full Gmail address (including @gmail.com)
- Password: Your app password (including spaces)
- Security: `TLS`
- Default from address: Your full Gmail address
- Click Send test email to test that the settings work, then click the save icon at the top right.
### Mailchimp (Previously Mandrill)
Mailchimp is currently integrating its transactional email marketing plugin, Mandrill, into its main brand. At the time of writing, you need to create an account with Mailchimp, then log in to Mandrill afterwards.
Mailchimp refused to provide FusionAuth with an account while writing this article. The steps below should work, but we were unable to send a test email to be certain.
- Sign up for an account at https://login.mailchimp.com/signup/?entrypoint=mandrill&locale=en.
- If Mailchimp suspends your account for violating the terms of service, click View issues at the top of the Mailchimp website, then Resolve at the bottom of the page to contact support.
- Log in to https://mandrillapp.com/settings/sending-domains and add your domain name in the text field at the bottom of the page.
- At the bottom of the page click View details for each record that needs to be verified.
- In your website domain manager, add the DNS records from the domain authentication page.
- Once you have entered the DNS records and saved, start the verification process on the Mailchimp page. It should take a minute.
- Browse to https://mandrillapp.com/settings/index and note your SMTP settings. Create a new API key at the bottom of the page.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp.mandrillapp.com`
- Port: `587`
- Username: Enter anything
- Password: Your API key
- Security: `TLS`
- Default from address: Use an address at your domain
- Click Send test email to test that the settings work, then click the save icon at the top right.
### MailerSend
- Create an account at https://app.mailersend.com.
- Browse to [Email -> Domains](https://app.mailersend.com/domains) and click Manage on the trial domain MailerSend created for you.
- Under SMTP, click Generate new user and then enter the SMTP name for the user.
- MailerSend will generate the user credentials and you can save them.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp.mailersend.net`
- Port: `587`
- Username: Your username from the User page
- Password: Your password from the User page
- Security: `TLS`
- Default from address: Use your MailerSend trial, such as `fa@trial-o89qngkvfrwlwr32.mlsender.net`
- Click Send test email to test that the settings work, then click the save icon at the top right.
- To use your real domain, browse to [Email -> Domains](https://app.mailersend.com/domains).
- Click Add domain.
- On the Domain verification page, you are given DNS records to add to your domain.
- In your domain manager website, add these records.
- Once you have entered the DNS records and saved, start the verification process at the bottom of the MailerSend page. It should take a minute and you will be emailed when verification is done.
- Click Generate new user for this domain and use the SMTP details in FusionAuth.
### Mailgun (Sinch)
- Create an account at https://signup.mailgun.com/new/signup.
- If you are only testing Mailgun, you can use the sandbox domain name Mailgun creates for you to send emails. If you have paid for an account, you should add and verify your company's real domain.
- Add your domain name under Sending -> Add new domain in the Mailgun dashboard at https://app.mailgun.com/mg/sending/new-domain.
- In your domain manager website, add the DNS records from the domain authentication page.
- Once you have entered the DNS records and saved, start the verification process on the Mailgun page. It should take a minute.
- If you are using an unpaid account, you need to add authorized email receivers. Browse to Domains -> Overview and ensure the sandbox domain is selected. Add the email address where you want to receive a test email from FusionAuth.
- Click the verification link in the email you receive to authorize your address.
- Browse to https://app.mailgun.com/mg/sending/domains. Click the gear icon to the right of your domain name and select Settings to browse to a page like https://app.mailgun.com/app/sending/domains/myapp.com/settings. Select the SMTP credentials tab.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp.mailgun.org`
- Port: `587`
- Username: Your login name. If using an unpaid account you must use the sandbox domain.
- Password: Get this by pushing Reset password in Mailgun and copying the value you are given.
- Security: `TLS`
- Default from address: Use your Username value from above
- Click Send test email to test that the settings work, then click the save icon at the top right. Enter your authorized email address for the test email, so you can test it arrives.
### Postmark
- Create an account at https://account.postmarkapp.com/sign_up and enter your domain name.
- Verify your email address.
- Browse to https://account.postmarkapp.com/signature_domains.
- Click DNS Settings above your domain name.
- In your domain manager website, add the DNS records from the domain authentication page.
- Once you have entered the DNS records and saved, start the verification process on the Postmark page. It should take a minute.
- To see your SMTP settings, browse to https://account.postmarkapp.com/servers, then click My First Server -> Default Transactional Stream -> Setup Instructions -> SMTP.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp.postmarkapp.com`
- Port: `587`
- Username: Your username from the settings page
- Password: Your password from the settings page
- Security: `TLS`
- Default from address: Any address is allowed
- Click Send test email to test that the settings work, then click the save icon at the top right.
While in the Postmark sandbox mode before account approval, you may not send emails to addresses outside your domain. These addresses will be shown in the Activity tab of your server on Postmark.
### Resend
- Create an account at https://resend.com.
- Browse to https://resend.com/domains.
- In your website domain manager, add the records from Resend at the link above.
- You need to set only the DKIM and SPF fields for testing. The DMARC field is optional and required only for your production server.
- Once you have entered the DNS records and saved, return to https://resend.com/domains and start the verification process. It should take a few minutes.
- Browse to https://resend.com/api-keys and create a key with sending access only.
- Browse to https://resend.com/settings/smtp and note your SMTP details.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp.resend.com`
- Port: `587`
- Username: `resend`
- Password: Your API key
- Security: `TLS`
- Default from address: Use an email address at your domain
- Click Send test email to test that the settings work, then click the save icon at the top right.
For an overview of all the records Resend asks you to set on your domain, please read their [documentation](https://resend.com/docs/dashboard/domains/introduction). For more general information, read the [Resend documentation on SMTP](https://resend.com/docs/send-with-smtp).
### SendGrid (Twilio)
- Create an account at https://signup.sendgrid.com.
- Verify your email address.
- Browse to https://app.sendgrid.com/settings/sender_auth/senders/new and create a new sender.
- Enter all company details and click Create.
- Verify your sender email address.
- Browse to https://app.sendgrid.com/settings/sender_auth and under Authenticate Your Domain, click Get Started.
- In your domain manager website, add the DNS records from the domain authentication page.
- Once you have entered the DNS records and saved, start the verification process on the SendGrid page. It should take a minute.
- To see your SMTP settings, browse to https://app.sendgrid.com/guide/integrate/langs/smtp.
- Create an API key.
- In your tenant's email tab in the FusionAuth web interface, set the following values:
- Host: `smtp.sendgrid.net`
- Port: `587`
- Username: apikey
- Password: Your API key from the settings page
- Security: `TLS`
- Default from address: Your verified sender created earlier
- Click Send test email to test that the settings work, then click the save icon at the top right.
## Troubleshoot
Below are some common errors you might get when configuring SMTP and how to fix them.
### Authentication Error
```text
Unable to send email via JavaMail
Prime Messaging Exception
535 Authentication failed.
```
This error indicates that your username or password is incorrect. Re-enter them carefully with no excess whitespace and try again.
If the error looks like the one below, you need to set up a [Google application password](https://support.google.com/accounts/answer/185833).
```text
Prime Messaging Exception
535-5.7.8 Username and Password not accepted. For more information, go to
535 5.7.8 https://support.google.com/mail/?p=BadCredentials
```
### Account Suspended
```text
Unable to send email via JavaMail
Prime Messaging Exception
502 5.7.0 Your SMTP account is not yet activated. Please contact us at contact@sendinblue.com to request activation.
```
Some providers automatically disable your account at registration. Contact support at your provider to have it activated.
### Socket Timeout
```text
Error:
Unable to send email via JavaMail
Prime Messaging Exception
Exception reading response
Cause: SocketTimeoutException: Read timed out
```
You may need to change the port number. Try `587`.
### Domain Not Verified
```text
Unable to send email via JavaMail
Prime Messaging Exception
450 The resend.com domain is not verified. Please, add and verify your domain on https://resend.com/domains
```
You need to verify your domain with your SMTP provider by setting DNS records on your web host.
Be aware that DNS records take time to change. If you make a change to a record that your SMTP provider needs to validate, you may have to wait an hour to a day for caches to refresh before you can use the new value.
### Email Address Not Verified
```text
Unable to send email via JavaMail
Prime Messaging Exception
554 Message rejected: Email address is not verified. The following identities failed the check in region EU-WEST-1: address/fa@simplelogin.com
```
```text
Unable to send email via JavaMail
Prime Messaging Exception
421 Domain fa.dns-dynamic.net is not allowed to send: Free accounts are for test purposes only. Please upgrade or add the address to authorized recipients in Account Settings.
```
This error is only likely if you use AWS or Mailgun, which require your sender address to be verified when testing until your service leaves the testing sandbox. To fix this error, send the FusionAuth test email to the same address that you verified when creating the SES service in AWS or add the address to the list of authorized recipients in Mailgun.
### Email Doesn't Arrive
Try the following:
- Wait longer.
- Check that you entered the receiver email address correctly.
- Email an address that is authorized and verified by your SMTP provider, such as the one on your authenticated domain that you used to register your account. Check if the provider has an authorized recipient section and add the address there.
- Check if your SMTP provider received the request and the status is not `Bounced`.
- Check your spam folder in your email client, or other folders if you have filters enabled.
- Disable webhooks in FusionAuth, in case a failed webhook is causing complications.
## SMTP Best Practices
This section lists some recommendations by SMTP providers for transactional emails. Your primary aim should be to keep your sender reputation high to avoid emails being marked as spam.
- Ensure that you add all SPF, DKIM, DMARC, and MX records to your DNS records.
- For extra trustworthiness and brand building, set up Brand Indicators for Message Identification (BIMI), which enables email inboxes to display a brand’s logo next to the company’s authenticated email messages.
- Send emails only to people who have requested to receive them. Always first send a confirmation link to confirm their address is valid.
- Follow your SMTP provider's documentation to configure analytics for your emails (click tracking).
- Track your emails and adjust your sending based on feedback from ESPs and recipients. Don't send emails to recipients who have unsubscribed or complained of spam. Monitor the results of email sending on your SMTP provider's analytics web page.
- Send as few emails to users as possible to avoid emails being marked as spam. Keep your email content as short as possible to avoid wasting your users' time.
- Always include a link to unsubscribe in your emails.
- Always test new email templates by emailing them to yourself on a test FusionAuth server before enabling them in production. Check that fields are populated correctly.
- Send multipart emails using both text and HTML or text only. ESPs do not trust HTML-only email and block images by default. Preview how your emails look with tools like [Litmus](https://www.litmus.com/email-testing).
- Too many links and images trigger spam flags at ESPs. Misspellings and spammy words ("buy now!", "Free!") are spam flags, as are ALL CAPS AND EXCLAMATION MARKS!!!!!!!!!!!!!
- Don't use URL shortening services for links. Use your domain's full URL.
- The domains in the `from` field, `return-path`, and `message-id` should match the domain you are sending from.
- Send transactional and marketing emails through different IP addresses, as marketing email is more likely to be marked as spam. FusionAuth uses only transactional email.
- For similar reasons, send your transactional email and your marketing email through different subdomains. Your domain and your IP address both have reputations with ESPs.
- Do not use a `noreply` email address as your sender. Instead, route all customer replies to your support team.
### Shared IP Addresses
Most SMTP providers allow you to send through an individual IP address dedicated to your account or an IP address (or pool of addresses) shared by multiple SMTP accounts. If you are sending low volumes of email (less than 5000 per day), a shared IP address is a good choice. Shared addresses are less expensive than dedicated addresses. The address is already known and trusted by ESPs, so your emails are unlikely to be sent to spam folders.
If an SMTP account starts sending spam and decreases the address's reputation, the SMTP provider will take action, either canceling the client's account or moving them to a lower-reputation IP address pool.
Mailgun recommends one dedicated IP address for every million messages sent per month.
# Application Email Templates
import PremiumPlanBlurb from 'src/content/docs/_shared/_premium-plan-blurb.astro';
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import ChangePasswordHTML from 'src/content/docs/_shared/email/_change-password-html.mdx';
import ChangePasswordText from 'src/content/docs/_shared/email/_change-password-txt.mdx';
## Prerequisites
In order for you to get the most value from this guide, you should have a FusionAuth instance, with an email provider and an application set up for a user to log in with.
If you don't have this set up yet, please review the following links:
* [5 minute setup guide](/docs/quickstarts/5-minute-setup-guide) - get a FusionAuth instance up and running with a simple application
* [Configure Email](/docs/customize/email-and-messages/configure-email) - Configure an email provider. You can also use mailcatcher as a local SMTP client. This is [documented for a docker install](/docs/get-started/download-and-install/docker#other-services).
## Custom Application Email Templates
In FusionAuth, a Tenant can be configured to send transactional emails for various workflows. Each Tenant can fire off emails based on certain events using the default Email Templates that ship with FusionAuth, such as `Email Update`, `Forgot Password`, and `Suspicious login`. Each email template can be customized and localized.
In this guide, you'll learn how to customize these templates at the application level.
To begin, you'll configure your email template at the Tenant level to ensure it is sent when a user that is registered for your application starts the [Forgot Password Workflow](/docs/apis/users#start-forgot-password-workflow).
First, navigate to Tenant -> Email -> Template Settings -> Forgot Password. select Forgot Password from the dropdown, then click the blue save icon.
If you don't see a `Forgot Password` email template, go to Customizations -> Emails Templates and click the light green + icon. Fill in `Forgot Password` for the Name, and for the Default Subject, From Email, Default from Name fields, whatever values you require. Paste in the following code for HTML Template and Text Template, respectively.
Both of these templates assume FusionAuth is running at `localhost:9011`. If you are running it at a different address, update the templates with the correct hostname.
Save your template by clicking the blue save icon.
When a user clicks the `Forgot your password?` link on the login page or calls the [forgot password API](/docs/apis/users#start-forgot-password-workflow), this template will be used to build the email sent to the user. This is the start of the workflow to change their password. This template is used so long as the application doesn't have a `Forgot Password` template configured.
Now you need to send an email using the default email template.
Make sure you've created an Application in the Application overview. Then navigate to your application login page by clicking on Applications in the navigation sidebar, selecting the green magnifying glass icon, and copying and pasting the [Login URL](/docs/get-started/core-concepts/applications) into an incognito browser.
Click the Forgot your password? link, enter your email in the form, and the `Forgot Password` email should be sent to the user's email inbox.
## Configuring Application Email Templates
Finally, override the generic Tenant Email Template just configured with a custom application specific template for a fictitious company called Pied Piper.
Navigate to Customizations -> Emails Templates and click the blue edit icon for the Forgot Password email template and copy the HTML Template and Text Template sections into a text file for easier editing.
Create a new email template by going to Customizations -> Emails Templates and click the green + icon.
Fill out the Name, Default Subject, From Email, Default from Name fields.
Click on HTML Template in the bottom right corner, and paste your default template from above into the Default HTML and Default Text sections. Feel free to edit these templates based on the needs of your application.
Save your template by clicking the blue save icon in the top right corner.
Now configure the email template by navigating to Applications -> Your Application. Click the green edit icon, then navigate to Email -> Templates -> Forgot password and select your application email template. This option will have the same Name field as above. Click the blue save icon in the top right corner.
## Test the Custom Template
For our demo application Pied Piper, call the [Start Forgot Password Workflow](/docs/apis/users#start-forgot-password-workflow) for a user to start the forgot password flow. You can also use the link on the login page, as previously demonstrated.
```shell
curl --request POST \
YOUR_FUSIONAUTH_INSTANCE/api/user/forgot-password \
--header 'Authorization: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"applicationId": "85a03867-dccf-4882-adde-1a79aeec50df",
"loginId": "dinesh@piedpiper.com",
"sendForgotPasswordEmail": true
}'
```
Modify the curl command. You'll need to update a number of values.
* Replace `YOUR_API_KEY` with a valid FusionAuth API key.
* Replace `YOUR_FUSIONAUTH_INSTANCE` with the URL to your instance. If running locally this will be `http://localhost:9011`.
* Replace the value of `applicationId` with the Id of your application.
* Replace the value of `loginId` with the email address of the account for which the password is being reset. Remember this user must be registered for the application before the email can be sent.
Once successfully executed, you will see an application specific email sent to the above user's email address.
# Email Variables
import Aside from 'src/components/Aside.astro';
import API from 'src/components/api/API.astro';
import EmailTemplateBaseUrlNote from 'src/content/docs/customize/email-and-messages/_template-base-url-note.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import EnterprisePlanBlurb from 'src/content/docs/_shared/_enterprise-plan-blurb.astro';
import ConfirmChildHTML from 'src/content/docs/_shared/email/_confirm-child-html.mdx';
import ConfirmChildText from 'src/content/docs/_shared/email/_confirm-child-txt.mdx';
import TwoFactorRemoveHTML from 'src/content/docs/_shared/email/_two-factor-remove-html.mdx';
import TwoFactorRemoveText from 'src/content/docs/_shared/email/_two-factor-remove-txt.mdx';
import COPPANoticeHTML from 'src/content/docs/_shared/email/_coppa-notice-html.mdx';
import COPPANoticeText from 'src/content/docs/_shared/email/_coppa-notice-txt.mdx';
import ParentRegistrationHTML from 'src/content/docs/_shared/email/_parent-registration-html.mdx';
import ParentRegistrationText from 'src/content/docs/_shared/email/_parent-registration-txt.mdx';
import RegistrationVerificationHTML from 'src/content/docs/_shared/email/_registration-verification-html.mdx';
import RegistrationVerificationText from 'src/content/docs/_shared/email/_registration-verification-txt.mdx';
import PasswordlessLoginTemplates from 'src/content/docs/_shared/_passwordless-login-templates.mdx';
import SetupPasswordTemplates from 'src/content/docs/_shared/_set-password-templates.mdx';
import BreachedPasswordHTML from 'src/content/docs/_shared/email/_breached-password-html.mdx';
import BreachedPasswordText from 'src/content/docs/_shared/email/_breached-password-txt.mdx';
import COPPAEmailPlusNoticeHTML from 'src/content/docs/_shared/email/_coppa-email-plus-notice-html.mdx';
import COPPAEmailPlusNoticeText from 'src/content/docs/_shared/email/_coppa-email-plus-notice-txt.mdx';
import ChangePasswordHTML from 'src/content/docs/_shared/email/_change-password-html.mdx';
import ChangePasswordText from 'src/content/docs/_shared/email/_change-password-txt.mdx';
import TwoFactorLoginHTML from 'src/content/docs/_shared/email/_two-factor-login-html.mdx';
import TwoFactorLoginText from 'src/content/docs/_shared/email/_two-factor-login-txt.mdx';
import EmailVerificationHTML from 'src/content/docs/_shared/email/_email-verification-html.mdx';
import EmailVerificationText from 'src/content/docs/_shared/email/_email-verification-txt.mdx';
import ThreatDetectedHTML from 'src/content/docs/_shared/email/_threat-detected-html.mdx';
import ThreatDetectedText from 'src/content/docs/_shared/email/_threat-detected-txt.mdx';
import TwoFactorAddHTML from 'src/content/docs/_shared/email/_two-factor-add-html.mdx';
import TwoFactorAddText from 'src/content/docs/_shared/email/_two-factor-add-txt.mdx';
{/* MAKE SURE YOU UPDATE astro/src/content/docs/_shared/email/template_url_list if you add any templates */}
## Templates & Replacement Variables
The email template body (both HTML and text values), subject, and from name fields support replacement variables. This means placeholders can be inserted and the value will be calculated at the time the email template is rendered and sent to a user.
Most templates will contain the User object as returned on the Retrieve User API. This means you can utilize any value found on the User object such as email, first name, last name, etc.
Below you will find each stock template that FusionAuth ships for reference. The available replacement values will be outlined below for each template.
### Retrieving Default Templates
In order to version control the templates or customize them, you can use the admin UI. But you can also pull retrieve them all by using the following command:
```
wget -i https://raw.githubusercontent.com/FusionAuth/fusionauth-site/main/astro/src/content/docs/_shared/email/template_url_list
```
This will place all the email templates in the current working directory.
## Using Replacement Variables
Below are some basic examples of using replacement values in your email templates.
Consider the following User represented by this condensed JSON object.
```json
{
"email": "monica@piedpiper.com",
"firstName": "Monica",
"id": "1c592f8a-59c6-4a09-82f8-f4257e3ea4c8",
"lastName": "Hall"
}
```
The following are example usages with a rendered output based upon the above mentioned example User. The replacement variables are rendered
using [Apache FreeMarker](https://freemarker.apache.org/docs/index.html) which is an HTML template language.
A default value should be provided for variables that may be undefined at runtime such as `firstName`. See `firstName` in the example below
is followed by a bang `!` and then the string `Unknown User`. This indicates that if `firstName` is undefined when the template is rendered the value
of `Unknown User` should be used as a default value.
*Template Source*
```html
Hi ${user.firstName!'Unknown User'}, welcome to Pied Piper.
Please verify your email address ${user.email} by following the provided link.
https://piedpiper.fusionauth.io/email/verify/${verificationId}
- Admin
```
*Rendered Output*
```html
Hi Monica, welcome to Pied Piper.
Please verify your email address monica@piedpiper.com by following the provided link.
https://piedpiper.fusionauth.io/email/verify/YkQY5Gsyo4RlfmDciBGRmvfj3RmatUqrbjoIZ19fmw4
- Admin
```
## Custom Replacement Variables
In addition to the variables mentioned in the previous section, when defining your own email templates to be used by the [Send Email](/docs/apis/emails#send-an-email) API
custom data may be provided on the API request to be used in the email template.
On Send Email API request the contents of the `requestData` field will be made available to you when the template is rendered.
For example, consider the following request to the Send API to send email template Id `1bc118ae-d5fa-4cdf-a90e-e8ef55c3e11e` to the User by Id `ce485a91-906f-4615-af75-81d37dc71e90`.
```json title="Example Request JSON"
{
"requestData": {
"paymentAmount": "$9.99",
"product": "party hat",
"quantity": "12"
},
"userIds": [
"ce485a91-906f-4615-af75-81d37dc71e90"
]
}
```
*Template Source*
```html
Hello ${user.firstName!''},
Thank you for your purchase! We value your business, please come again!
Product: ${requestData.product!'unknown'}
Quantity: ${requestData.quantity!'unknown'}
- Pied Piper Customer Success
```
*Rendered Output*
```html
Hello Kelly,
Thank you for your purchase! We value your business, please come again!
Product: party hat
Quantity: 12
- Pied Piper Customer Success
```
## Available Email Templates
Below is an overview of each email template that ships with FusionAuth.
### Breached Password
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The breach result matching loginIds. This is an array of zero or more email addresses or usernames found in the breach result matching this user. A length of zero means only the password was matched.
The breach result match type determined by the FusionAuth Reactor. Possible values include:
* `ExactMatch` The User's loginId and password were found exactly as entered.
* `SubAddressMatch` The User's loginId and password were matched, but the email address was a sub-address match. For example, `joe+test@example.com` is a sub-address match for `joe@example.com`.
* `PasswordOnly` Only the password found, the loginId and password combination were not matched.
* `CommonPassword` The User's password was found to be one of the most commonly known breached passwords.
The Tenant object, see the Tenant API for field definitions.
The User object, see the User API for field definitions.
### Confirm Child
#### Replacement Variables
The child User object, see the User API for field definitions of a User.
The parent User object, see the User API for field definitions of a User.
The Tenant object, see the Tenant API for field definitions.
The parent User object. This field has been deprecated, please use the `parent` object instead.
### COPPA Email Plus Notice
#### Replacement Variables
The User Consent object, see the Consent API for field definitions of a User consent.
The Tenant object, see the Tenant API for field definitions of a Tenant.
The User giving consent, see the User API for field definitions of a User.
### COPPA Notice
#### Replacement Variables
The Tenant object, see the Tenant API for field definitions of a Tenant.
The User giving consent, see the User API for field definitions of a User.
### Email Verification
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The Tenant object, see the Tenant API for field definitions of a Tenant.
The User object, see the User API for field definitions of a User.
The verification Id intended to be used by the [Verify Email](/docs/apis/users#verify-a-users-email) API.
The verification One Time Code (OTP) to be used with the gated Email Verification workflow. The user enters this code to verify their email.
### Forgot Password
This is also known as the "Change Password" template.
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The change password Id intended to be used by the [Change a User's Password](/docs/apis/users#change-a-users-password) API.
If the `state` was provided during the Forgot Password request, it will be available to you in the email template.
The Tenant object, see the Tenant API for field definitions.
The User object, see the User API for field definitions of a User.
### Parent Registration Request
#### Replacement Variables
The child User object, see the User API for field definitions of a User.
The Tenant object, see the Tenant API for field definitions of a Tenant.
### Passwordless Login
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The unique code intended to be used by the [Complete a Passwordless Login](/docs/apis/passwordless#complete-a-passwordless-login) API.
If the `state` was provided when the Passwordless request was initiated, it will be available to you in the email template.
The Tenant object, see the Tenant API for field definitions of a Tenant.
The User object, see the User API for field definitions of a User.
### Registration Verification
#### Replacement Variables
The Application object, see the Application API for field definitions.
The User Registration object, see the Registration API for field definitions of a User.
The Tenant object, see the Tenant API for field definitions of a Tenant.
The User object, see the User API for field definitions of a User.
The verification Id intended to be used by the [Verify a User Registration](/docs/apis/registrations#verify-a-user-registration) API.
The verification One Time Code to be used with the Gated Registration workflow. The user enters this code to verify their email.
### Set Up Password
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The change password Id intended to be used by the [Change a User's Password](/docs/apis/users#change-a-users-password) API.
The Tenant object, see the Tenant API for field definitions of a Tenant.
The User object, see the User API for field definitions of a User.
### Threat Detected
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
The EventInfo object, see the [User Login Suspicious](/docs/extend/events-and-webhooks/events/user-login-suspicious) event definition for example field definitions.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Two Factor Authentication
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined. You can check for this variable safely in FreeMarker using the missing value test operator and an `if` statement:
```html
[#if application??]
[#-- Use application here --]
[/#if]
```
This object is not available on the email template when:
* The multi-factor workflow was [started](/docs/apis/two-factor#start-multi-factor) without providing the `applicationId` on that request.
* Multi-factor authentication is required during a call to the [login API](/docs/apis/login#authenticate-a-user) without providing the `applicationId` parameter. That documentation points out that there is likely no production use case where calling the API without the `applicationId` parameter is useful.
* The message is being sent to [enable](/docs/apis/two-factor#send-a-multi-factor-code-when-enabling-mfa) or [disable](/docs/apis/two-factor#send-a-multi-factor-code-when-disabling-mfa) a multi-factor method without providing the `applicationId` on the request.
A code that the user must provide to complete multi-factor authentication.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Two Factor Authentication Method Added
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined. You can check for this variable safely in freemarker by wrapping the variable as such: `${(application)!""}`.
The Event object for a two factor add event. See the [Webhooks & Events section](/docs/extend/events-and-webhooks/events/user-two-factor-method-add) for field definitions.
The two-factor method that was added. See the [Multi Factor/Two Factor APIs](/docs/apis/two-factor) for property definitions and example JSON.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Two Factor Authentication Method Removed
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined. You can check for this variable safely in freemarker by wrapping the variable as such: `${(application)!""}`.
The Event object for a two factor remove event. See the [Webhooks & Events section](/docs/extend/events-and-webhooks/events/user-two-factor-method-remove) for field definitions.
The two-factor method that was removed. See the [Multi Factor/Two Factor APIs](/docs/apis/two-factor) for property definitions and example JSON.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
# Email Templates
import TemplateContentLimits from 'src/content/docs/_shared/_template-content-limits.mdx';
import EmailTemplateBaseUrlNote from 'src/content/docs/customize/email-and-messages/_template-base-url-note.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
FusionAuth will use email templates to send a Forgot Password request, and other built in workflows. You may also create your own email templates and send them to Users via the [Send Email](/docs/apis/emails#send-an-email) API.
## Allowed Content
## Managing Templates
FusionAuth ships with several templates to support Forgot Password, Setup Password, Verify Email and other workflows. You will want to modify these templates prior to using them in production.
Apart from modifying them to be more cosmetically pleasing or to match your brand, you will need to ensure the URL used in the template is correct. You will need to ensure the URL is publicly accessible.
When you first log into FusionAuth and navigate to Customizations -> Email Templates you will see the following templates.
For example, below is the email body of the Email Verification template as it is shipped with FusionAuth.
At a minimum, you will need to update this URL to a publicly accessible URL that can reach FusionAuth.
If you will be handling Email Verification yourself, you will need to update this URL to be that of your own. You will notice the one replacement variable in this template named `${verificationId}`. See the Replacement Variables section below for additional detail, but these variables will be replaced when the template is rendered.
### Base Information
The unique Id of the email template. The template Id may not be changed and will be used to interact with the template when using the Email APIs.
The name of the template. This value is for display purposes only and can be changed at any time.
The default subject of the email. The default value will be used unless a localized version is found to be a better match based upon the User's preferred locales.
This field supports replacement variables.
The from email address used to send this template. As of version 1.16.0, this field is optional.
The default from name of the email. The default value will be used unless a localized version is found to be a better match based upon the User's preferred locales.
This field supports replacement variables.
## Localization
The email template body (both HTML and text values), subject, and from name fields can be localized.
You can associate these values with a locale. If a user has a preferred language, the localized template will be used when this email is sent.
# Generic Messenger
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Aside from 'src/components/Aside.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
import JSON from 'src/components/JSON.astro';
import SecuringHttpRequests from 'src/content/docs/_shared/_securing_http_requests.mdx';
## Set Up a Generic Messenger
Currently, built-in messengers are only provided to send messages via Twilio or email. If you need to connect to a messaging provider other than Twilio, whether you want to send SMS messages or use a different transport layer such as push notifications, you can use the Generic messenger configuration.
The generic messenger allows for a simple JSON REST API integration which allows you to receive a message from FusionAuth to an arbitrary URL. The Generic Message Receiver at this URL may then make an API call to any third party messaging provider.
To create a new generic messenger, navigate to Settings -> Messengers. Click Add Generic Messenger from the dropdown in the upper right.
### Add Generic Messenger
Complete the following fields:
#### Form Fields
A unique UUID is auto generated if left blank.
For display only. Name of this generic messenger.
This is the URL of the messaging service you wish to connect to.
In milliseconds, how long to keep the socket open when connecting to the messenger.
Must be an integer and greater than 0.
In milliseconds, how long to keep the socket open when reading to the messenger.
Must be an integer and greater than 0.
When enabled, each message sent using this messenger will generate a new Debug Event Log which can be viewed using the Event Log API or from the admin UI by navigating to System -> Event Log.
### Security
#### Form Fields
Username used to authenticate with the generic messenger
Password used to authenticate with the generic messenger
The SSL certificate in PEM format to be used when connecting to the messenger API endpoint. When provided an in memory keystore will be generated in order to complete the HTTPS connection to the messenger API endpoint.
### Headers
#### Form Fields
In these fields, you can add custom key and value pairs. These will be sent as headers on the request.
### Testing Your Configuration
You also can test your generic messenger configuration. By hitting `Test generic configuration` FusionAuth will fire a JSON message to the messenger to ensure everything is set up correctly.
## Writing the Generic Message Receiver
You need to write a server side component, a receiver, which will be deployed at a URL to consume the message sent from FusionAuth. At that point, it can proxy the request to any third party messaging service. In other words, a FusionAuth Generic Messenger is a thin coordination layer between FusionAuth and other messaging services. An application with the proper permissions, code and configuration to relay a message must exist at the configured URL. This receiver component may be written in any language that can consume a JSON message.
The request to your endpoint will be delivered as JSON.
When your application receives this message from FusionAuth, it should take whatever steps necessary to send the message, such as:
* call into a SDK provided by the third party
* make an API request to a vendor provided endpoint
* call multiple internal APIs
* anything else that may be required
### Request
The phone number of the user to which this message should be sent.
The message text to send. This is built from the configured [message template](/docs/customize/email-and-messages/message-templates) and is localized.
The type of the message. This will always be `SMS`.
### Response
If the message was processed successfully, return a status code in the `200` to `299` range. No further processing will be performed by FusionAuth.
If the receiver is unsuccessful at sending the message, for whatever reason, return a status code outside of that range.
## Securing the Generic Message Receiver
# Message Variables
import TemplateBaseUrlNote from 'src/content/docs/customize/email-and-messages/_template-base-url-note.mdx';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import EnterprisePlanBlurb from 'src/content/docs/_shared/_enterprise-plan-blurb.astro';
import TwoFactorRemovePhone from 'src/content/docs/_shared/message/_two-factor-remove-txt.mdx';
import PasswordlessLoginTemplates from 'src/content/docs/_shared/message/_passwordless-txt.mdx';
import SetupPasswordTemplates from 'src/content/docs/_shared/message/_setup-password-txt.mdx';
import ForgotPasswordPhone from 'src/content/docs/_shared/message/_forgot-password-txt.mdx';
import TwoFactorLoginPhone from 'src/content/docs/_shared/message/_two-factor-login-txt.mdx';
import PhoneVerification from 'src/content/docs/_shared/message/_phone-verification-txt.mdx';
import ThreatDetectedPhone from 'src/content/docs/_shared/message/_threat-detected-txt.mdx';
import TwoFactorAddPhone from 'src/content/docs/_shared/message/_two-factor-add-txt.mdx';
{/* MAKE SURE YOU UPDATE astro/src/content/docs/_shared/message/template_url_list if you add any templates */}
## Templates & Replacement Variables
The message template body supports replacement variables. This means place holders can be inserted and the value will be calculated at the time the message template is rendered and sent to a user.
Most templates will contain the User object as returned on the Retrieve User API. This means you can utilize any value found on the User object such as email, first name, last name, etc.
Below you will find each stock template that FusionAuth ships for reference. The available replacement values will be outlined below for each template.
## Previewing Message Templates
FusionAuth provides the capability to preview message templates via the [Message Template API](/docs/apis/message-templates) or the administrative user interface by navigating to Customizations -> Message Templates -> Edit -> Preview. The following sample values are used when rendering the template.
| Parameter | Sample Value | Purpose |
|------------------------------|-----------------------------------------------------------------------------|-------------------------------------------------------------------------|
| `${application}` | `{ "name": "My Application", "oauthConfiguration": { "clientId": "123456" } }` | Application name, `oauthConfiguration.clientId` for themed message links |
| `${changePasswordId}` | `1234567890` | Embedded in change password and set password URLs |
| `${code}` | `123456` | Embedded in MFA/Two Factor messages |
| `${event}` | `{ "type": "UserLoginSuspicious", "info": {...} }` | Embedded in User Event messages |
| `${method}` | `{ "id" : "FQLM", "method" : "email" }` | Embedded in Two Factor Add/Remove event messages |
| `${oneTimeCode}` | `88888` | Embedded in passwordless login messages |
| `${tenant}` | `{ "name": "My Tenant", "id": "78910" }` | `tenant.id` allows links embedded in messages to render using the correct theme for that tenant. |
| `${user}` | `{ "firstName": "John", "lastName": "Doe" }` | User information and `user.tenantId` for themed message links |
| `${verificationId}` | `987654` | Embedded in phone number verification messages |
| `${verificationOneTimeCode}` | `abcdef` | Embedded in phone number verification messages |
## Retrieving Default Templates
In order to version control the templates or customize them, you can use the admin UI. But you can also pull retrieve them all by using the following command:
```
wget -i https://raw.githubusercontent.com/FusionAuth/fusionauth-site/main/astro/src/content/docs/_shared/message/template_url_list
```
This will place all the message templates in the current working directory.
## Using Replacement Variables
Below are some basic examples of using replacement values in your message templates.
Consider the following User represented by this condensed JSON object.
```json
{
"phoneNumber": "+15555551234",
"firstName": "Monica",
"id": "1c592f8a-59c6-4a09-82f8-f4257e3ea4c8",
"lastName": "Hall"
}
```
The following are example usages with a rendered output based upon the above mentioned example User. The replacement variables are rendered
using [Apache FreeMarker](https://freemarker.apache.org/docs/index.html) which is an HTML template language.
A default value should be provided for variables that may be undefined at runtime such as `firstName`. See `firstName` in the example below
is followed by a bang `!` and then the string `Unknown User`. This indicates that if `firstName` is undefined when the template is rendered the value
of `Unknown User` should be used as a default value.
*Template Source*
```html
Hi ${user.firstName!'Unknown User'}, welcome to Pied Piper.
Please verify your phone number ${user.phoneNumber} by following the provided link.
https://piedpiper.fusionauth.io/identity/verify/${verificationId}
- Admin
```
*Rendered Output*
```html
Hi Monica, welcome to Pied Piper.
Please verify your phone number +15555551234 by following the provided link.
https://piedpiper.fusionauth.io/identity/verify/YkQY5Gsyo4RlfmDciBGRmvfj3RmatUqrbjoIZ19fmw4
- Admin
```
## Available Message Templates
Below is an overview of each message template that ships with FusionAuth.
### Forgot Password
This is also known as the "Change Password" template.
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The change password Id that must be included as a path segment in the `/password/change` link. See the [theme variables](/docs/customize/look-and-feel/template-variables) documentation for more information on how this value is used.
If the `state` was provided during the Forgot Password request, it will be available to you in the message template.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Passwordless Login
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The unique code intended to be used by the [Complete a Passwordless Login](/docs/apis/passwordless#complete-a-passwordless-login) API.
If the `state` was provided when the Passwordless request was initiated, it will be available to you in the template.
The Tenant object, see the Tenant API for field definitions of a Tenant.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Phone Verification
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
The verification Id intended to be used by the [Identity Verify](/docs/apis/identity-verify) API.
The verification One Time Code (OTP) to be used with the gated Phone Verification workflow. The user enters this code to verify their phone number.
### Set Up Password
#### Replacement Variables
The Application object, see the Application API for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined.
The change password Id intended to be used by the [Change a User's Password](/docs/apis/users#change-a-users-password) API.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Threat Detected
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
The EventInfo object, see the [User Login Suspicious](/docs/extend/events-and-webhooks/events/user-login-suspicious) event definition for example field definitions.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Two Factor Authentication
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined. You can check for this variable safely in FreeMarker using the missing value test operator and an `if` statement:
```html
[#if application??]
[#-- Use application here --]
[/#if]
```
This object is not available on the message template when:
* The multi-factor workflow was [started](/docs/apis/two-factor#start-multi-factor) without providing the `applicationId` on that request.
* Multi-factor authentication is required during a call to the [login API](/docs/apis/login#authenticate-a-user) without providing the `applicationId` parameter. That documentation points out that there is likely no production use case where calling the API without the `applicationId` parameter is useful.
* The message is being sent to [enable](/docs/apis/two-factor#send-a-multi-factor-code-when-enabling-mfa) or [disable](/docs/apis/two-factor#send-a-multi-factor-code-when-disabling-mfa) a multi-factor method without providing the `applicationId` on the request.
A code that the user must provide to complete multi-factor authentication.
Email address associated with the `user`.
Mobile phone number associated with the `user`.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Two Factor Authentication Method Added
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined. You can check for this variable safely in freemarker by wrapping the variable as such: `${(application)!""}`.
The Event object for a two factor add event. See the [Webhooks & Events section](/docs/extend/events-and-webhooks/events/user-two-factor-method-add) for field definitions.
The two-factor method that was added. See the [Multi Factor/Two Factor APIs](/docs/apis/two-factor) for property definitions and example JSON.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
### Two Factor Authentication Method Removed
#### Replacement Variables
The Application object, see the [Application API](/docs/apis/applications) for field definitions.
*Note*:
This object may not be available depending upon when this template is constructed. If you utilize this object in your template, ensure you first check to see if it is defined. You can check for this variable safely in freemarker by wrapping the variable as such: `${(application)!""}`.
The Event object for a two factor remove event. See the [Webhooks & Events section](/docs/extend/events-and-webhooks/events/user-two-factor-method-remove) for field definitions.
The two-factor method that was removed. See the [Multi Factor/Two Factor APIs](/docs/apis/two-factor) for property definitions and example JSON.
The Tenant object, see the [Tenant API](/docs/apis/tenants) for field definitions.
The User object, see the [User API](/docs/apis/users) for field definitions of a User.
# Email & Messages Overview
import InlineField from 'src/components/InlineField.astro';
import EmailTroubleshooting from 'src/content/docs/customize/email-and-messages/_email-troubleshooting.mdx';
import { YouTube } from '@astro-community/astro-embed-youtube';
## Overview
This section is designed to review how to utilize email, email templates, and messenger templates in FusionAuth. See [Email APIs](/docs/apis/emails) for additional information on integrating directly with the email APIs and [Messenger Templates](/docs/apis/messengers/) for more information on modifying messenger templates directly.
## Email
Email and Email Templates are a core feature of FusionAuth. [Email Templates](/docs/customize/email-and-messages/email-templates-replacement-variables) allows you to communicate with your Users via email. You can manage these templates using the API, SDKs or manually. FusionAuth
provides [example email templates for workflows](/docs/customize/email-and-messages/email-templates-replacement-variables), but you should plan to revise them to reflect your sites branding.
In order to use email templates and email based workflows, you will need to [configure an SMTP server](/docs/customize/email-and-messages/configure-email).
Here's a brief video covering some aspects of email templates:
## Message Templates
Message templates are used by Messengers. Currently there is only one messenger type: SMS. Just as with emails, these can be customized and localized, but unlike email templates, there are not HTML and text versions of a messenger template.
Here are the topics in this section:
* [Message Templates](/docs/customize/email-and-messages/message-templates)
## Troubleshooting
# Message Templates
import InlineField from 'src/components/InlineField.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
FusionAuth will use message templates to send codes to users who have chosen an SMS MFA method. This is currently the only built-in workflow which uses message templates.
You may also create your own message templates with localized content and manage them using FusionAuth.
## Managing Templates
FusionAuth ships with a default message template to support SMS MFA workflows. However, it isn't assigned to the SMS Multi-Factor settings. To use it, configure the Tenant Multi-Factor settings.
You may also add new templates. Either use the [Message Template API](/docs/apis/message-templates) or the administrative user interface by navigating to Customizations -> Message Templates.
### Base Information
The unique Id of the Message Template. The template Id may not be changed and will be used to interact with the template when using the APIs.
The name of the template. This value is for display purposes only and can be changed at any time.
The type of the template. `SMS` is the only value currently supported.
## Localization
The message template body can be localized.
You can associate the template text values with a locale. If a user has a preferred language, the localized template will be used when this text message is sent.
# Messengers
import Aside from 'src/components/Aside.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Messengers
Messengers are used to send messages from within FusionAuth to other systems.
### Message Transports
In version `1.26.0`, each messenger type is assigned a read-only transport value of `sms`. This tells FusionAuth which configurations the messenger may be assigned to. For example, when configuring `SMS settings` in [multi-factor configuration](/docs/lifecycle/authenticate-users/multi-factor-authentication#tenant-set-up) on a Tenant, we can safely assign only messengers designated with the corresponding transport value.
## Set Up a Messenger
In FusionAuth, you can set up three types of messengers:
- [Set Up a Generic Messenger](/docs/customize/email-and-messages/generic-messenger)
- [Set Up a Twilio Messenger](/docs/customize/email-and-messages/twilio-messenger)
To configure a messenger, navigate to Settings -> Messengers and click on the appropriate messenger type in the top right.
## Create a Messenger Template
Message templates are a powerful way to customize messengers and the communication contained within. FusionAuth uses FreeMarker for all templating.
- [Manage Message Templates](/docs/customize/email-and-messages/message-templates)
To configure a message template, navigate to Customizations -> Message Templates.
# Twilio Messenger
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Aside from 'src/components/Aside.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
## Set Up a Twilio Messenger
Here you can add a Twilio messenger to send SMS messages.
To create a new Twilio messenger, navigate to Settings -> Messengers. Click Add Twilio Messenger from the dropdown in the upper right.
### Add Twilio Messenger
Complete the following fields:
#### Form Fields
A unique UUID is auto generated if left blank.
The name of the messenger. You can have multiple Twilio messengers with different accounts. This is used for display only.
Provided by Twilio. This is the URL of the Twilio messaging service you wish to connect to.
Provided by Twilio.
Provided by Twilio.
The outgoing phone number of your messenger service.
Provided by Twilio and is often used in conjunction with the Copilot service.
When enabled, each message sent using this messenger will generate a new Debug Event Log which can be viewed using the Event Log API or from the admin UI by navigating to System -> Event Log.
### Testing Your Configuration
You also can test your Twilio messenger configuration. By hitting `Send test message` FusionAuth will fire a test SMS message to your Twilio messenger to ensure everything is set up correctly.
# Advanced Theme Editor
import InlineField from 'src/components/InlineField.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import MessagesExample from 'src/content/docs/customize/look-and-feel/_messages-example.mdx';
import ThemeEnvironments from 'src/content/docs/operate/deploy/_theme-environment-management.mdx';
import ThemeTroubleshooting from 'src/content/docs/customize/look-and-feel/_theme-troubleshooting.mdx';
import ThemeUpgrade from 'src/content/docs/customize/look-and-feel/_theme-upgrade.mdx';
import Templates from 'src/content/docs/_shared/_theme_templates.astro';
import Aside from 'src/components/Aside.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
FusionAuth's Advanced Theme Editor allow you to control every aspect of the look and feel of your hosted login pages.
The other option, in version 1.51.0 and later, is to use the [Simple Theme Editor](/docs/customize/look-and-feel/simple-theme-editor) to quickly and easily style FusionAuth with no code.
### Difference From Simple Themes
The Simple Theme Editor allows you to select from a set of pre-built themes and customize them with a few simple options. This is a great way to get started with customizing FusionAuth without needing to write any code.
The Advanced Theme Editor allows editing page templates directly. This allows you to take full control over all of the hosted pages by creating an advanced theme and editing the HTML, CSS, and messages. This is a powerful way to create a fully custom experience, but it can be complex and time-consuming.
## Create a Theme
FusionAuth provides the ability to create and manage themes in the UI as well as a [Themes API](/docs/apis/themes). Any user of the FusionAuth role of `admin` or `theme_manager` may view, edit, update, and delete Themes.
All of the FusionAuth login templates are written in [FreeMarker](https://freemarker.apache.org). FreeMarker provides a very rich template language that will allow you to customize the pages and helpers to suit your needs. You can also define new macros and functions to assist you further.
Below is an example screenshot of the Add Theme panel with each template described below.
### Form Fields
An optional UUID. When this value is omitted a unique Id will be generated automatically.
A unique name to identify the theme. This name is for display purposes only and it can be modified later if desired.
### Templates
{/* ===== */}
{/* To add a new theme template, do the following */}
{/* update site/_date/templates.yaml (further instructions there) */}
{/* update the JSON files in site/docs/src/json/themes/ with the new theme template key */}
{/* touch this file to regenerate (if in dev mode) */}
{/* that's it. the API and the theme form page will be automatically updated. */}
This CSS stylesheet may be used to style the themed pages.
This CSS will be included in the `head` tag in the Helpers `head` macro. You may also choose to include other remote stylesheets by using the `
```
This section allows you to add additional localized messages to your theme. When creating an additional locale it is not required that all messages are defined for each language. If a message key is not defined for the specified locale, the value from the default bundles will be used.
If you intend to localize your login templates, you may find our [community contributed and maintained messages in our GitHub repository](https://github.com/FusionAuth/fusionauth-localization) helpful.
This template contains all of the main helper macros to define the `head`, `body` and `footer`. To begin theming FusionAuth you'll want to start with this template as it will affect all other templates.
See the [Helpers](/docs/customize/look-and-feel/helpers) page for additional information.
## Preview a Theme
If you want to see how your theme works, you can always open a browser with no active FusionAuth session and visit the hosted login pages.
However, at times, you may need to make changes in your theme that you want to view without going through an entire registration process. You can easily do so by previewing the theme via the administrative user interface.
Navigate to Customizations -> Themes. Choose your theme, then click the preview link (the green magnifying glass):
This will open a new tab. Click on any of the pages you've modified in the left hand navigation, for example OAuth register, and you'll see the page as it would be rendered.
## Example Code
### Displaying Messages
You can customize messages by locale. You can also have optional keys.
### Customizing the Authorize Page
Now that you have a good overview of all the templates, macros and helpers, here is an example of customizing the Authorize page.
Let's assume you want to change the header and footer across all of the pages including the Authorize page. This is accomplished by editing the `helpers.header` and `helpers.footer` macros. For the header, let's assume you want to add a `Sign Up` and `Login` link. For the footer, let's assume you want to add a link to your privacy policy. Here are the macros that include these new links:
```html title="Custom header helper"
[#macro header]
[#nested/]
[/#macro]
```
```html title="Custom footer helper"
[#macro footer]
[#nested/]
[/#macro]
```
Once you make these changes, they will take effect on all of the pages listed above.
## Development Tools
When building an advanced theme, the [FusionAuth theme helper project](https://github.com/FusionAuth/fusionauth-theme-helper) is useful.
You can pull down all your templates, edit them locally, and have them transparently uploaded to your FusionAuth instance.
### Managing Many Themes
If you have a large number of themes, you'll want additional tooling to manage them. Best practices include:
* Put your themes under version control and use CI/CD and one of the [client libraries](/docs/sdks) to apply changes.
* Prefer modifying CSS rather than theme templates.
* Leverage `tenant.data` for a small number of attributes that differ between tenants, which allows you to use the same theme with modified templates. See [Environment Management](#environment-management) for an example.
* Consider generating your themes locally using a templating language such as jinja and then uploading them.
* Automatically assign themes to tenants, using one of the [client libraries](/docs/sdks).
There is an [open feature request](https://github.com/FusionAuth/fusionauth-issues/issues/1869) to allow for theme inheritance, but it is not currently on the roadmap.
## Environment Management
## Troubleshooting
## Upgrading
# Application Specific Themes
import InlineField from 'src/components/InlineField.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import PremiumPlanBlurb from 'src/content/docs/_shared/_premium-plan-blurb.astro';
## Overview
Application specific themes allow you to use the power of FusionAuth hosted login pages but use a different theme for each application.
This feature is useful when different applications for which you use FusionAuth have distinct branding. For example, if you are adding an application for a different customer, this feature can be useful to add the customer's logo easily to their login screen.
The alternative theming, which occurs at the tenant level and is included in the Community plan, is [documented as well](/docs/customize/look-and-feel/).
## Enabling Application Specific Themes
You need to make sure you enter a license, as this is a paid feature. [Learn how to install your license](/docs/get-started/core-concepts/licensing).
Next, you need to create a theme. Navigate to Customizations -> Themes and create a new theme.
Next, assign it to the application. Navigate to Applications -> Your Application and choose a theme from the list of themes.
Now, any user accessing a page that belongs to an application will use that theme.
## Additional Information
For application specific theming to work, FusionAuth must know which application is being accessed. This is typically done with the `client_id` parameter, which ties a request to a FusionAuth application. If the `client_id` cannot be determined, FusionAuth will fall back to the tenant theme. Make sure to include `client_id` on any external links you create.
Application specific theming, as with all theming, isn't very useful if you are not using the FusionAuth hosted login pages.
Currently, there is no concept of child themes to ease management if you have a large number of themes. There's an [open feature request](https://github.com/FusionAuth/fusionauth-issues/issues/1869) for this functionality.
# Client-side Password Rule Validation
import {RemoteCode} from '@fusionauth/astro-components';
import RemoteContent from '/src/components/RemoteContent.astro';
FusionAuth checks password rules in server-side validation, but you can also check them in your client. This page shows one method of doing so in JavaScript.
{/*
This page is primarily pulled from a GH subdirectory, ensuring that the code can be ran and updated easily. The README is also in that repo to make sure it stays in sync with the code.
When you change the remote files, there may be a 5 minute or so lag after your push before the changes are available at the `raw` URL, so don't be surprised if your changes don't immediately appear.
*/}
## Client-side Password Validation Example
## JavaScript Code
Here's the example code.
# Theme Examples
import InlineField from 'src/components/InlineField.astro';
## Examples
Want to show off your FusionAuth theming skills? Feel free to send us a few screenshots and you may show up on this page!
### Celery Payroll
https://www.celerypayroll.com
The left image is the login page rendered in English, the right example is the same page in Dutch using FusionAuth localization.
### Gmork Tech
https://dagger.gmork.tech/
### Oryx Software
# Themes Helper Macros
import InlineField from 'src/components/InlineField.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Aside from 'src/components/Aside.astro';
import RecaptchaValues from 'src/content/docs/_shared/_recaptcha-values.mdx';
## Overview
FusionAuth has a template that contains a number of macros used in all of the page templates. This template is located at `../_helpers.ftl` and it contains a number of FreeMarker macros. The rest of the pages use these macros to generate various pieces of the HTML. The macros contained in `_helpers.ftl` are:
## Section Helpers
* `html`
* Renders the `` element
* `head`
* Renders the `` element and everything inside it including the ``, CSS, Java Script, and meta information
* `body`
* Renders the `` element
* `header`
* Renders any type of header for each page. This could be a navigation bar, side bar, or page details
* `main`
* Renders the main content body of each page. If all of your pages will have similar HTML elements like a container, this is the place to put them.
* `footer`
* Renders the footer content of each page. This might contain links, nav, privacy policies, etc.
Here is an example of what one of these helpers looks like:
```html title="HTML helper"
[#macro html]
[#nested/]
[/#macro]
```
The key to these macros is the `[#nested/]` element. This is the location that FreeMarker will insert any nested content when you use the macro. Here is an example of using this macro:
```html title="Example usage of HTML macro"
[@helpers.html]
Hello world!
[/@helpers.html]
```
Everything inside the macro will be place where the `[#nested/]` element is. Therefore, the result of our example would be this HTML:
```html title="Example result"
Hello world!
```
All of the page templates use these macros, which makes it much easier to style all of the pages at one time. You simply edit the macros and your changes will take effect on all of the pages listed above.
## Social (alternative) Login Helpers
In addition to the section helpers, the `_helpers.ftl` template also contains additional macros that can be used to setup social and alternative logins. Currently, FusionAuth supports these social login providers:
* Apple
* Epic Games
* Facebook
* Google
* HYPR
* LinkedIn
* Sony PlayStation Network
* Steam
* Twitch
* Twitter
* Xbox
* Generic OpenID Connect
* Generic SAML v2
* Generic SAML v2 Identity Provider Initiated
This macro can be included on the Authorize or Register page.
* `/oauth2/authorize`
* `/oauth2/register`, available since 1.28.0
Once you have configured your alternative logins (called identity providers in the interface and API), they will appear on the FusionAuth stock login form. This is because our stock login form includes this code:
```html title="Social login code"
[@helpers.head]
[@helpers.alternativeLoginsScript clientId=client_id identityProviders=identityProviders/]
...
[/@helpers.head]
[@helpers.body]
...
[@helpers.alternativeLogins clientId=client_id identityProviders=identityProviders/]
[/@helpers.body]
```
The first macro (`alternativeLoginScripts`) includes the JavaScript libraries that FusionAuth uses to hook up the identity providers. Unless you want to write your own JavaScript or use a third-party library, you will need this JavaScript in the `` tag in order for FusionAuth to leverage external login providers.
The second macro (`alternativeLogins`) produces the login buttons for each of the configured identity providers. These buttons are all hooked up to the JavaScript included in the `` of the page in order to make it all work nicely.
You might want to use your own buttons for social logins. This is possible with FusionAuth, but you will need to do a couple of things to make it all work.
First, you need to remove the `[@helpers.alternativeLogins]` macro call.
Second, you need to use a specific `id` or `class` on your HTML element for the button. Here are the `id` s or `class` es for each identity provider:
* `id="apple-login-button"` is used for Apple
* `id="epicgames-login-button"` is used for Epic Games
* `id="google-login-button"` is used for Google
* `id="facebook-login-button"` is used for Facebook
* `id="linkedin-login-button"` is used for LinkedIn
* `id="sonypsn-login-button"` is used for Sony PlayStation Network
* `id="steam-login-button"` is used for Steam
* `id="twitch-login-button"` is used for Twitch
* `id="twitter-login-button"` is used for Twitter
* `id="xbox-login-button"` is used for Xbox
* `class="openid login-button"` is used for Generic OpenID Connect
* `class="samlv2 login-button"` is used for Generic SAML v2
And finally, you need to ensure that Prime.js is included on your page. This library ships with FusionAuth and you just need to ensure it is included like this:
```html title="Prime.js include"
```
## Alert and Error Helpers
The `_helpers.ftl` template also provides a couple of macros that can be used to output errors and alerts that might occur. The best bet is to include these macros in your `main` macro. Here are the macros and their purpose:
* `printErrorAlerts`
* This outputs any error alerts. These are normally displayed at the top of the page and you might want to make them able to be dismiss (i.e. removed from the page).
* `printInfoAlerts`
* This outputs any informational alerts. These are the same as the errors, but might have different CSS.
* `alert`
* This macro is used by the `printErrorAlerts` and `printInfoAlerts` but you can also use it directly to display an error or info message anywhere on the page.
## Form Helpers
The `_helpers.ftl` template provides a couple of macros that help render form elements and output form errors. Here are the macros you can use:
* `hidden`
* This outputs a hidden input element. Many pieces of the OAuth workflow and the other pages in FusionAuth use hidden form fields to store data. This macro uses the `eval` feature of FreeMarker in order to pull in data that was in the request. You shouldn't edit this macro unless you know what you are doing.
* `input`
* This outputs an input element plus a label and any errors that might have occurred on the form field. You can use this for text, passwords, and other input elements. FusionAuth also leverages `addons` which are icons next to the input field that provide visual cues to the user. This macro allows you to leverage addons as well. Similar to the `hidden` element, you should not edit this unless you know what you are doing.
* `errors`
* This macro is used by the `input` macro to render errors on the field. You can use this if you write your own `input` macros. Otherwise, you likely won't use this.
* `button`
* This macro renders a button that can be used to submit a form. The FusionAuth version of this macro includes an icon and the button text.
* `scopeConsentField`
* This macro renders the appropriate form field for a requested OAuth scope on the OAuth _Consent prompt_ page. It automatically handles the field type and message resolution based on the application's configuration. It requires the `resolveScopeMessaging` function to be defined in `_helpers.ftl`.
## CAPTCHA
The `_helpers.ftl` template provides a macro to embed [CAPTCHA challenges](/docs/get-started/core-concepts/tenants#captcha-settings) into your templates.
* `captchaBadge`
* Macro that adds a CAPTCHA badge to the template. See [template variables](/docs/customize/look-and-feel/template-variables/) for more information on the template variables. The macro's parameters are:
### Parameters
This is the type of CAPTCHA to use. Typically supplied by the `tenant.captchaConfiguration.captchaMethod` template variable. Valid values are:
This determines whether or not to show the CAPTCHA badge. Typically supplied by the `showCaptcha` template variable.
The `data-sitekey` value to use for the CAPTCHA. Typically supplied by the `tenant.captchaConfiguration.siteKey` template variable. Required if using `GoogleRecaptchaV3`.
### Invisible reCAPTCHA
If you wish to enable an [invisible reCAPTCHA](https://developers.google.com/recaptcha/docs/invisible) element so that a CAPTCHA will still challenge a submit without a checkbox on the form you may do so by adding the `data-size` and `data-callback` attributes on the tag with the `g-recaptcha` class. In FusionAuth version 1.46.0 and later these attributes will be present in the default template but commented out.
```html title="Invisible tag"
[#if captchaMethod == "GoogleRecaptchaV2"]
...
```
# Themes Overview
import ListHostedLoginPagesUseCases from 'src/content/docs/_shared/_list-hosted-login-pages-use-cases.mdx';
import PremiumPlanBlurbApi from 'src/content/docs/_shared/_premium-plan-blurb-api.astro';
import ThemeTroubleshooting from 'src/content/docs/customize/look-and-feel/_theme-troubleshooting.mdx';
import Aside from 'src/components/Aside.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
FusionAuth themes allow you to customize the hosted login pages and other user workflows such as forgot password. In FusionAuth you may create one to many themes and assign a theme per tenant or application so that you can customize the user experience for different users.
## Customization Levels
FusionAuth theme customization is only useful if you are using the hosted login pages. Using the hosted login pages has a number of advantages. By doing so, FusionAuth handles the complexity of a number of different auth related use cases. These use cases include, but are not limited to, the following:
If you are not using the hosted login pages, you are responsible for creating the user interface for the login and other experiences.
In contrast, if you are using the hosted login pages, you can customize at two different levels.
The first is the tenant. Learn more in the [Apply a Theme](#apply-a-theme) section.
The second is the application. There are two options for applying a theme at the application level:
* Use a tenant theme and use freemarker to switch on the `client_id` parameter. Review each template and ensure that you serve different content for different applications based on the Id. This is a good option if your needs are simple and you are willing to commit to the maintenance burden.
* Use application themes. This is a paid feature. Learn more about [application specific themes](/docs/customize/look-and-feel/application-specific-themes). This is a better choice if you have more complicated theming needs.
## Create a Theme
You have three options for creating a theme:
* The [Simple Theme Editor](/docs/customize/look-and-feel/simple-theme-editor)
* The [Advanced Theme Editor](/docs/customize/look-and-feel/advanced-theme-editor)
* The [Themes APIs](/docs/apis/themes) or other scripting solution like the [SDKs](/docs/sdks) or [Terraform](/docs/operate/deploy/terraform)
Here's a table with the relative strengths and weaknesses of the different approaches.
| Option | Good For | Challenges | Documentation |
| --------------------- | ------- | ------- | ------- |
| Simple Theme Editor | Quickly creating a customized look and feel. Upgrading to a new version of FusionAuth, which may have additional templates, is simple. | Doesn't allow injecting JavaScript or pixel-perfect control. Limited control of layouts of the page. | [docs](/docs/customize/look-and-feel/simple-theme-editor) |
| Advanced Theme Editor | Full control of every aspect of the look and feel, including moving or reordering fields on the page, adding custom JavaScript, and inserting multiple images | Can be complex to build, though there is some tooling. Complex to upgrade as new versions of FusionAuth come out. Requires knowledge of or willingness to learn Apache Freemarker. | [docs](/docs/customize/look-and-feel/advanced-theme-editor) |
| Theme APIs/SDKs | Automated application of themes across many tenants. Great if you are using a different templating language to generate many related themes and then uploading them. Good for CI/CD systems. | You still need to initially edit and review the templates somehow; that can be done with a local instance. |[docs](/docs/apis/themes) |
## Apply a Theme
You apply a theme by configuring either a Tenant or an Application to use the theme. Each theme may apply to multiple Applications or Tenants; however, each Tenant or Application may have only one theme.
To apply a theme to a Tenant, navigate to Tenants -> Your Tenant, then select the General tab. Select the appropriate theme and save the tenant. This will apply the theme to every application in that tenant, unless there is a theme specified for an application.

To apply a theme to an application, navigate to Applications -> Your Application, then select the appropriate theme.

## Troubleshooting
# Themes And Kickstart
import Aside from 'src/components/Aside.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
## Overview
[FusionAuth Kickstart™](/docs/get-started/download-and-install/development/kickstart) enables you to spin up a reproducible FusionAuth environment using a template file. This guide will walk you through the process of using Kickstart to set up a FusionAuth instance with a custom theme.
We'll apply a dark theme in place of the default application theme presented in the [5-minute Docker installation guide](/docs/extend/examples/5-minute-intro/5-minute-docker). We recommend following the 5-minute Docker installation guide before using this guide to automate the set-up process and apply a custom theme using Kickstart.
## Prerequisites
You'll need to have Node.js and Docker installed to follow this guide and the 5-minute guide. More information can be found [here](/docs/extend/examples/5-minute-intro/5-minute-docker#requirements).
## Getting Started
Once you've completed the steps in the 5-minute guide, we can take a look at the state of the FusionAuth instance you created.
Navigate to Applications and edit the application you created. Go to the OAuth tab to examine the settings that you configured.
In the 5-minute guide, the Authorized redirect URLs, Logout URL, Enabled grants, and Require registration fields were manually entered. We will use Kickstart to automate all of these settings. We will also apply predefined Client Id and Client secret values to make launching the application easier.
Now, navigate to Users -> Manage for the user that you set up in the 5-minute guide.
In the 5-minute guide, you created both the user and the FusionAuth registration by manually filling out the registration form. You then added a registration for the user to the application you created. We are going to automate these steps.
Finally, navigate to Customizations -> Themes and preview the FusionAuth theme. The application you created in the 5-minute guide uses the OAuth authorize and OAuth logout pages.
The OAuth authorize template looks like this:
The OAuth logout template looks like this:
We are going to create a dark theme so these templates that will look like this:
## Creating the Files
To customize our theme, we'll need to create two files:
- A CSS file, which we'll use to define the dark theme.
- A `kickstart.json` file that will enable the automatic configuration of settings.
The requests we add to the `kickstart.json` file will each need a separate JSON file.
If you'd like to skip ahead to the Running Kickstart section, you can [download the completed files here](https://github.com/FusionAuth/fusionauth-example-kickstart/tree/main/theme-css-only).
### The `darkTheme.css` File
The most straightforward way to add a consistent style to your theme is to define a stylesheet using CSS. You can interactively experiment with CSS in your browser to get your application looking the way you want it to.
Let's define one CSS rule together. First, preview the FusionAuth theme and open up the web inspector by right-clicking and selecting "Inspect". Click the Select element button and click the area of the page you would like to style, for example, the `div` element with the class `.panel`.
This element has a `background` property with a value of `#fff`, or pure white.
Let's change the background from white to black. With the element selected, click the plus + icon and type `background: black`.
We've just defined our first `css` rule. Copy the text that you generated, including the part that the browser made for you when you clicked the plus + icon, into a text editor and save it as `darkTheme.css`, like this:
```css
.panel {
background: black
}
```
You can keep using this process to add rules to your `darkTheme.css` file until you've got a fully defined style that you're happy with. Feel free to use [this file](https://github.com/FusionAuth/fusionauth-example-kickstart/blob/main/theme-css-only/darkTheme.css) for this tutorial.
Once you have your `darkTheme.css` file, create a folder called `kickstart` and move your `darkTheme.css` file into it.
### The `kickstart.json` File
The `kickstart.json` file allows us to automatically configure everything we need for our application from the moment we first launch it.
Create a file called `kickstart.json` in the `kickstart` folder and copy the following text into it:
```json
{
"variables":{
"apiKey" : "#{UUID()}",
"themeID" : "#{UUID()}",
"applicationID" : "404e516b-06b8-49da-9c68-c1cd1928c81d",
"clientSecret" : "RBLhJrfRsa0-YxVPrn_aZfzIGccWyncdvHvDNTy-Hrs",
"defaultTenantId": "da025934-3ba7-4a13-83f0-aab68c9919b8",
"userID" : "#{UUID()}"
},
"apiKeys": [
{
"key": "#{apiKey}"
}
],
"requests":[
"&{json/createTheme.json}",
"&{json/updateTheme.json}",
"&{json/createApplication.json}",
"&{json/createUser.json}",
"&{json/registerUser.json}",
"&{json/setDefaultTheme.json}"
]
}
```
There are three sections in this code: `"variables"`, `"apiKeys"`, and `"requests"`.
The `"variables"` section defines identifiers for the key components of our FusionAuth instance. In this section, `"apiKey"`, `"themeId"`, and `"userId"` are randomly generated UUIDs. We'll use the arbitrary values in `"applicationId"`, `"clientSecret"` and `"defaultTenantId"` later on.
The `"apiKeys"` section defines the key through which our requests will be executed. At least one `"apiKey"` is required for every `kickstart.json` file.
The `"requests"` section defines the API requests that perform our API calls. Each request is stored in a JSON file, which we need to define separately. You can also have them inline, but when you are working with a lot of changes, it is easier to have each change in a separate file.
Let's define these files now.
### The API Request JSON Files
Create a subdirectory in the `kickstart` folder called `json`. In the `json` folder, add a file called `createTheme.json` containing the following code:
```json
{
"method" : "POST",
"url" : "api/theme/#{themeID}",
"body" : {
"sourceThemeId" : "75a068fd-e94b-451a-9aeb-3ddb9a3b5987",
"theme" : {
"name" : "Dark Theme"
}
}
}
```
This request creates the dark theme. It uses the `"sourceThemeId"` attribute to copy everything from the default FusionAuth theme, the Id of which is always `75a068fd-e94b-451a-9aeb-3ddb9a3b5987`. It also assigns the UUID initialized and contained in the `#{themeID}` variable as this theme's Id by setting it as the resource Id in the path of the URL.
Create a file called `updateTheme.json` and add the following to it:
```json
{
"method" : "PATCH",
"url" : "api/theme/#{themeID}",
"body" : {
"theme" : {
"stylesheet" : "@{darkTheme.css}"
}
}
}
```
This request applies our `darkTheme.css` stylesheet to the theme we created.
Create a file called `setDefaultTheme.json` and copy the following into it:
```json
{
"method": "PATCH",
"url": "/api/tenant/#{defaultTenantId}",
"body": {
"tenant": {
"themeId": "#{themeID}"
}
}
}
```
This request sets the dark theme as the theme for the default tenant.
Create a file called `createApplication.json` and copy the following into it:
```json
{
"method" : "POST",
"url" : "/api/application/#{applicationID}",
"body" : {
"application":{
"name" : "Kickstart App",
"oauthConfiguration" : {
"authorizedRedirectURLs" : [
"http://localhost:3000/oauth-redirect"
],
"clientId" : "#{applicationID}",
"clientSecret" : "#{clientSecret}",
"logoutURL": "http://localhost:3000/logout",
"enabledGrants": [
"authorization_code",
"refresh_token"
],
"requireRegistration" : "true"
}
}
}
}
```
This request creates the application and configures its OAuth settings as they appear in the 5-minute guide.
Create a file called `createUser.json` containing the following:
```json
{
"method": "POST",
"url": "/api/user/registration/#{userID}",
"body": {
"user": {
"email": "richard@example.com",
"password": "password"
},
"registration": {
"applicationId": "#{FUSIONAUTH_APPLICATION_ID}",
"roles": [
"admin"
]
}
}
}
```
This request creates a user and registers the user to the default FusionAuth application. This is necessary to login to the admin panel.
Finally, create a file called `registerUser.json` containing the following:
```json
{
"method": "POST",
"url": "/api/user/registration/#{userID}",
"body": {
"registration": {
"applicationId": "#{applicationID}"
}
}
}
```
This request adds a registration for the user that we just created to our custom application. This requires a separate request because our initial request used its `"registration"` field for the default application.
With these files, our `kickstart` folder is complete and ready to use. The entire folder can be downloaded [here](https://github.com/FusionAuth/fusionauth-example-kickstart/blob/main/theme-css-only).
## Modifying the Files from the 5-Minute Guide
Next we'll import and modify the files from the 5-minute guide that let us launch and run our FusionAuth instance.
First, download the Docker files.
```bash
curl -o docker-compose.yml https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/main/docker/fusionauth/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/main/docker/fusionauth/.env
```
To enable Kickstart to run from this `docker-compose.yml` file, we must make some modifications. They are described in detail at [this link](/docs/get-started/download-and-install/docker#kickstart) and copied here for your convenience:
- In the `volumes:` section of the FusionAuth service, add `- ./kickstart:/usr/local/fusionauth/kickstart`.
- Modify `.env` and add the Kickstart configuration variable: `FUSIONAUTH_APP_KICKSTART_FILE=/usr/local/fusionauth/kickstart/kickstart.json`. This path should be what the Docker container expects, not the path on the host.
- Configure `docker-compose.yml` to pass the environment variable set by `.env` to the container. Do this by adding `FUSIONAUTH_APP_KICKSTART_FILE: ${FUSIONAUTH_APP_KICKSTART_FILE}` to the `environment` section of the FusionAuth service.
Now download the 5-minute guide files.
```bash
git clone https://github.com/FusionAuth/fusionauth-example-5-minute-guide \
&& cd fusionauth-example-5-minute-guide
```
This folder contains a file called `.env.sample`:
```shell
CLIENT_ID=CHANGEME
CLIENT_SECRET=CHANGEME
BASE_URL=http://localhost:9011
```
Change the `CLIENT_ID` and `CLIENT_SECRET` so that they match the `applicationId` and `clientSecret` variables from your `kickstart.json` file. Then save the file as `.env`
```shell
CLIENT_ID=404e516b-06b8-49da-9c68-c1cd1928c81d
CLIENT_SECRET=RBLhJrfRsa0-YxVPrn_aZfzIGccWyncdvHvDNTy-Hrs
BASE_URL=http://localhost:9011
```
## Running Kickstart
Once you have completed the steps above, you should have a folder that is structured as follows. We call this folder `Kickstart_Theme`, but you can call it whatever you like.
```
+ Kickstart_Theme
|
+-- docker-compose.yml
|
+-- fusionauth-example-5-minute-guide
|
+--+ kickstart
|
+-- kickstart.json
|
+-- darkTheme.css
|
+--+ json
|
+-- createTheme.json
|
+-- updateTheme.json
|
+-- createUser.json
|
+-- registerUser.json
|
+-- createApplication.json
|
+-- setDefaultTheme.json
```
To launch the FusionAuth instance, navigate to the `Kickstart_Theme` folder and run the docker compose command.
```bash
docker compose up
```
Once the execution has finished, the newly created FusionAuth instance will be accessible at `http://localhost:9011`.
Login to the FusionAuth instance. The username and password are configured in `kickstart/json/createUser.json`. You can set them to be anything you like, but for this tutorial, they are defined as follows:
```json
"email": "richard@example.com",
"password": "password"
```
Enter these credentials into the login screen to be taken to the admin dashboard.
You can look at Applications, Users, and Customizations -> Themes to verify that all of the settings have been configured correctly.
## Running the Application
Now that everything is set up and our theme has been applied, we can run the application. Navigate to the `fusionauth-example-5-minute-guide` directory and use `npm` to start the application.
```bash
npm install
npm start
```
Open an incognito window and visit `http://localhost:3000`.
You will be taken to the same landing page that you saw in the 5-minute guide. However, when you click Login this time, you will see your custom theme applied to the OAuth authorize page.
Enter the same credentials you used to login to the admin panel and click Logout to see the OAuth logout page.
## Modifying the Default Messages
Let's take it one step further and assume we want to change the content of some of the messages on the OAuth pages. For example, consider the "Forgot your password?" message, which shows up on the OAuth authorize page.
Let's say we want to change this to say "Forgot your password? Click here." We can do this by adding a `defaultMessages` property to `json/updateTheme.json`.
The `defaultMessages` string requires at least all of the messages defined in the FusionAuth default shipped messages file to be present, as it updates all messages as a single unit. The easiest way to accomplish this is to create a new file called `defaultMessages.txt` in your `kickstart` folder and copy-paste these messages into it.
The messages can be accessed by editing your custom theme, navigating to the Messages page, and clicking the Edit button.
Copy the entire contents of that box into your `defaultMessages.txt` file, find the `forgot-your-password` message (line 65), and modify it to "Forgot your password? Click here."
```json
{
"method" : "PATCH",
"url" : "api/theme/#{themeID}",
"body" : {
"theme" : {
"stylesheet" : "@{darkTheme.css}",
"defaultMessages" : "@{defaultMessages.txt}"
}
}
}
```
Once you have modified `updateTheme.json`, you will need to clear the volumes created when you launched the FusionAuth instance to allow the Kickstart to rerun. You can do this by executing the following command (This will totally destroy all data stored in the instance):
```bash
docker compose down -v
```
When you relaunch the instance using the `docker compose up` command, the result will be as below with the updated message:
## Conclusion
This guide has shown you how to use Kickstart to launch a reproducible FusionAuth instance with a custom theme. The complete set of files for this project can be found [here](https://github.com/FusionAuth/fusionauth-example-kickstart) in the directory called `theme-css-only`.
Some suggestions for further reading are as follows:
- [General documentation on Themes](/docs/customize/look-and-feel/)
- [API-specific documentation on Themes](/docs/apis/themes)
# Theme Localization
import AdvancedPlanBlurb from 'src/content/docs/_shared/_advanced-plan-blurb.astro';
import Aside from 'src/components/Aside.astro';
import MessagesExample from 'src/content/docs/customize/look-and-feel/_messages-example.mdx';
import LocalePrecedence from 'src/content/docs/_shared/_locale_precedence.mdx';
import OAuthScopeMessageLookup from 'src/content/docs/_shared/_oauth-scope-message-lookup.mdx';
## Overview
The FusionAuth theme can be localized to better server your end users. In each theme you may specify one to many language specific message bundles to translate text rendered in a theme into a user's preferred language.
If you're just looking into localizing your theme, take a look at our [community provided and maintained message bundles](https://github.com/FusionAuth/fusionauth-localization).
You may also want to review our [localization and internationalization documentation](/docs/get-started/core-concepts/localization-and-internationalization).
## Messages
In the Messages tab of your theme editor you may specify one to many languages. Once you have specified a key and value the key may be used in any template to display a localized string.
## Locale
The locale is determined by the [locale](/docs/reference/data-types#locales) value. The locale is resolved on each request using the following precedence:
## Identity Provider Login Buttons
The button text displayed in the login pages for identity providers such as Google, Facebook or SAML, is retrieved from the identity provider configuration. The [API documentation](/docs/apis/identity-providers/google) documents how to set and retrieve this value, which is `identityProvider.buttonText`.
This text is used in the default theme like so:
```html title="Login Template Excerpt"
```
The `buttonText` value stored in the identity provider configuration cannot be localized.
However, you can replace this line in the theme template to pull a localized value from the messages bundle.
First, add the translated text to all messages bundles, including the default bundle:
```properties title="English"
google-login=Login With Google
```
```properties title="German"
google-login=Mit Google Einloggen
```
Then, update the relevant templates to display the localized text. Here's an excerpt of an updated login page:
```html title="Updated Login Template Excerpt"
${theme.message('google-login')}
```
## OAuth Scope Consent Prompt
The `OAuth2 consent` template at `/oauth2/consent` has an expanded message lookup policy in order to allow customizing scope consent messages and details without requiring a separate theme.
# Tailwind CSS
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
## Overview
Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces. If you are already using Tailwind CSS in your application, you can integrate it into FusionAuth.
## Prerequisites
* Node.js 18 or later
## Setting up FusionAuth
Create a new theme by navigating to Customization -> Themes and then click the Add button. Enter a Name for the theme and click the Save button.
Create a new API key with permissions to modify the theme. You can do this by going to Settings -> API Keys. Then click the Add button and select `GET` and `PATCH` permissions for `/api/theme/`.
## Installation
To get started, we need to create a new node project with the FusionAuth CLI and Tailwind CSS installed:
```bash
mkdir fusionauth-tailwind
cd fusionauth-tailwind
npm init -y
npm install @fusionauth/cli tailwindcss@3
npx tailwindcss init
```
This will install the dependencies and create the `tailwind.config.js` file in the project root. You can customize the configuration as needed.
Change the `tailwind.config.js` to handle the FreeMarker template files in the `tpl` directory:
```js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./tpl/*.ftl'],
theme: {
extend: {}
},
plugins: []
}
```
Create a new stylesheet `input.css` in the root directory:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
This stylesheet will be used to import the Tailwind CSS base, components, and utilities. Additionally, you can add custom classes to this stylesheet as well.
We can now download the theme from FusionAuth:
```bash
npx fusionauth theme:download -k -h http://localhost:9011
```
Replace `` and `` with the Id of the theme and API key you created in FusionAuth respectively.
Currently, the theme is using the `fusionauth-style.css` hosted in the FusionAuth instance. This could conflict with our Tailwind CSS file. To fix this, we need to remove the following line from the `tpl/helpers.ftl` file. It should be around line number 85:
```html
```
Finally, we add two new scripts to the `package.json` file:
```json
"scripts": {
"watch:tailwind": "tailwindcss -i ./input.css -o ./tpl/stylesheet.css --watch",
"watch:theme": "fusionauth theme:watch -k -h http://localhost:9011"
},
```
At this point, we have prepared the project to build the Tailwind CSS file and upload the theme to FusionAuth. To apply the changes in the `helper.ftl` file, run the following command:
```bash
npx fusionauth theme:upload -k -h http://localhost:9011
```
## Usage
There are now two scripts that can be used to build the Tailwind CSS file and upload the theme to FusionAuth:
* `npm run watch:theme` — watches the template directory for changes and upload the theme to FusionAuth
* `npm run watch:tailwind` — watches the template directory for changes and rebuild the Tailwind CSS file
If you start both scripts in separate terminal windows, you can edit the template files, which rebuild the Tailwind CSS file, and automatically upload the theme to FusionAuth.
Now if we use a Tailwind CSS class in a template, it will be included in the CSS file:
```html
Hello World
```
To preview the changes, open FusionAuth, navigate to Customization -> Themes. Choose your theme, then click Preview.
## Integrate DaisyUI
There are many Tailwind CSS UI component libraries available. In this example, we are going to use DaisyUI.
DaisyUI is a Tailwind CSS plugin that provides a set of pre-built components and utilities to build beautiful and responsive websites. It supports color theming, light and dark mode, and RTL.
To integrate DaisyUI, install the plugin:
```bash
npm install daisyui
```
Then add the plugin to the `tailwind.config.js`:
```js
module.exports = {
content: ['./tpl/*.ftl'],
theme: {
extend: {}
},
plugins: [
require('daisyui')
]
}
```
Now you can use the DaisyUI components in the FreeMarker template files:
```html
Hello World
```
For an example integration, see [FusionAuth + Tailwind + DaisyUI Repository on GitHub](https://github.com/FusionAuth/fusionauth-example-theme-tailwind-daisyui/).
The example repository has light and dark mode setup, and includes updated templates for the following pages:
* Log in
* Log out
* Registration
* Forgot password
In this repository, you could change the color scheme simply by updating the `tailwind.config.js` file:
```js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./tpl/*.ftl'],
theme: {
extend: {
keyframes: {
progressBar: {
"0%": {
width: "0%"
},
"100%": {
width: "100%"
}
}
},
animation: {
progressBar: "progressBar 10s ease-in 1"
}
}
},
plugins: [require("daisyui")],
daisyui: {
themes: [
'corporate',
{
business: {
...require("daisyui/src/colors/themes")["[data-theme=business]"],
'primary': '#c891f2'
}
}
],
darkTheme: 'business'
}
}
```
Or you can even create your own theme with the [DaisyUI Theme Generator](https://daisyui.com/theme-generator/)
## Conclusion
This guide has shown you how to integrate Tailwind CSS into FusionAuth using the FusionAuth CLI. Additionally, we have shown how to integrate DaisyUI to build beautiful and responsive FusionAuth pages.
## References
* [Tailwind CSS](https://tailwindcss.com/)
* [DaisyUI](https://daisyui.com/)
# Simple Theme Editor
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import Aside from 'src/components/Aside.astro';
import Breadcrumb from 'src/components/Breadcrumb.astro';
import Icon from 'src/components/icon/Icon.astro';
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
import ThemeTroubleshooting from 'src/content/docs/customize/look-and-feel/_theme-troubleshooting.mdx';
import { YouTube } from '@astro-community/astro-embed-youtube';
## Overview
The Simple Theme Editor allows you to quickly get up and running with a custom FusionAuth theme by selecting a few styles, and without needing to edit any Freemarker or HTML. If you would rather not use the Admin UI you can also update a theme via the [Themes API](/docs/apis/themes).
The alternative is to use the [Advanced Theme Editor](/docs/customize/look-and-feel/advanced-theme-editor), which lets you control every aspect of the look and feel of your themes but with significantly more complexity.
### Difference From Advanced Themes
FusionAuth allows you to take full control over all of the hosted pages by creating an advanced theme and editing the HTML, CSS, and messages. This is a powerful way to create a fully custom experience, but it can be complex and time-consuming.
Instead of editing the templates directly, the Simple Theme Editor allows you to select from a set of pre-built themes and customize them with a few simple options. This is a great way to get started with customizing FusionAuth without needing to write any code.
## Creating And Editing Themes
To get started with the Simple Theme Editor, navigate to Customizations -> Themes in the FusionAuth admin UI and either select the Add Simple Theme button from the top-right or click the Duplicate button on the default FusionAuth simple theme (the one with the name FusionAuth - Simple). The default simple theme is read-only and can be viewed, but not edited.
To edit an existing simple theme, just click the button next to your theme.
Once inside the Customize theme page there is a section at the top where you can edit the name and Id of the theme, and some panels below where you can change settings and preview your changes.
In the lower part of the editor you'll find three main panels. The leftmost panel contains a set of buttons that control the editing tools that you'll see in the rightmost panel. They are:
* [Pre-built themes](#pre-built-themes)
* [Images](#images)
* [Styles](#styles)
* [Messages](#messages)
* [Pages preview](#pages-preview)
In the center of the editor, you'll see a preview panel, where you can see what your edits will look like on the different theme templates.
### Name And Id
In the top section, you can choose a name and Id for your theme. A unique name is required, but an Id will be assigned automatically if you don't provide one.
An optional UUID. When this value is omitted a unique Id will be generated automatically.
A unique name to identify the theme. This name is for display purposes only and it can be modified later if desired.
### Pre-Built Themes
Out of the box, FusionAuth provides three pre-built themes that you can select from. These provide a starting point, from which you can make changes. They are:
- **Classic** - This theme closely resembles the stock FusionAuth theme that you see with the default FusionAuth advanced theme
- **Dark** - A darker theme featuring FusionAuth brand colors
- **Light** - A lighter theme featuring FusionAuth brand colors
Selecting one of these will change all the styles currently set for the theme. If you have any un-saved changes in the editor when you select one of these, those changes will be discarded. In this case you'll be asked to confirm that you want to lose your changes and load a new pre-built theme.
### Images
In the `Images` section you can provide links to logo and page background images that will be used in the theme. You'll also find settings that control image sizing and placement. FusionAuth does not yet support uploading assets to be hosted, so these must be fully-qualified URLs that link to externally hosted images.
##### Theme logo
This is the image that will be displayed at the top of the panel on most of the FusionAuth hosted pages.
The fully-qualified URL to the image that will be used as the logo.
This slider determines how large the logo image will be. The slider defaults to `rem` units, but you can use `em` or `px` as well if you know what size that the image should be. Required if the Logo image URL is set.
##### Background image
This image will be used as the page background on all hosted pages. This setting supersedes a page background color.
The fully-qualified URL to the image that will be used as the page background.
This dropdown controls the the [background-repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat) and [background-size](https://developer.mozilla.org/en-US/docs/Web/CSS/background-size) properties of the background image.There are three options:
- **Contain** - sets the [background-size](https://developer.mozilla.org/en-US/docs/Web/CSS/background-size) property of the background image to `contain` and the [background-repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat) property to `no-repeat`. This will leave the image in its original aspect ratio and not repeat it, and size it to the width of the screen. Below the image will be the theme background color.
- **Cover** - sets the [background-size](https://developer.mozilla.org/en-US/docs/Web/CSS/background-size) property of the background image to `cover`. This will size the image to cover the entire background, cropping it if necessary to maintain the aspect ratio.
- **Repeat** - sets the [background-repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat) property of the background image to `repeat`. This will repeat the image in both the x and y directions and retain its original size.
### Styles
There are three sub-sections in the Styles section that provide controls for most of the styles in the theme.
##### Fonts
Here you can select from a list of common web fonts for the theme. You may also input a custom font-family value, but be aware that we cannot guarantee a custom font will be available to the browser and the rendered text may be the browser default.
This is the font-family used for the majority of the text in the theme.
This is the optional input for a custom font-family value.
This is the font-family used for monospaced text in the theme, such as with MFA recovery codes.
This is the optional input for a custom font-family value for monospaced text.
##### Miscellaneous
Provides controls that don't belong in other sections.
Toggles the "Powered by FusionAuth" footer on or off. **Note:** You must have a valid license to toggle off the footer.
Sets how rounded the corners of panels and form inputs are in the theme. The slider defaults to `rem` units, but you can use `em` or `px` as well if you know what value of the border radius should be.
##### Colors
Controls for the various colors of the theme. Clicking on the square next to the input field will bring up the browser's color picker and allow you to select any color or use the eye-dropper tool to select a color on the screen. You may put any value into the input field as long as it is a valid hex, hsl, hsla, rgb, or rgba color value. Hovering over a color control will highlight the element on the page that the color applies to. The colors you can set are:
The color of the background in the theme.
The color of the main content panel in the theme.
The color of the alert panels in the theme.
The color of the text in the alert panels in the theme.
The color of the majority of the text in the theme.
The color of monospaced text in the theme, such as with MFA recovery codes.
The color of error text in the theme.
The color of links in the theme.
The color of the icons in the theme.
The color of icon in the info alert panels in the theme.
The color of icon in the error alert panels in the theme.
The color of the icons for the input fields.
The color of the background of the icons for the input fields.
The color of the text in the input fields.
The color of the background of the input fields.
The color of most buttons in the theme.
The color of the text on most buttons in the theme.
The color of the delete buttons in the theme.
The color of the text on the delete buttons in the theme.
### Messages
Allows you to change any of the copy in the theme, and also provide localized versions of messages.
When editing the "Default" locale you will see the full list of the default messages and the comments that explain what they are. However, only properties that you change will be saved to your theme. This ensures only changes you made will be applied and the theme will otherwise always have all of the default text for the theme even after upgrades.
See [Theme Localization](/docs/customize/look-and-feel/localization) for more information.
Any changes made to the messaging will be shown in the preview, but the whole theme must be saved in order to persist those changes.
When creating an additional locale it is not required that all messages are defined for each language.
If you intend to localize your login templates, you may find our [community contributed and maintained messages in our GitHub repository](https://github.com/FusionAuth/fusionauth-localization) helpful.
### Pages Preview
The Pages Preview section allows you to see what the theme will look like on the various FusionAuth hosted pages.
All the hosted pages are ordered into various categories, and you can click on any of them to change what is shown in the preview pane.
Additionally, you can click on the Browser preview button to open the currently selected page in a new browser tab. The page in the new tab will still have the style updates applied as long as the theme editor is active. This allows you to open several pages and once and see your style changes applied in real time.
## Troubleshooting
## Upgrading
With simple themes, upgrading is simple, as the styles you've configured are applied to any new templates that are added.
New messages will automatically be applied to your theme after an upgrade. The only thing stored in your theme are customizations that override the default text.
# Theme Template Variables
import InlineField from 'src/components/InlineField.astro';
import InlineUIElement from 'src/components/InlineUIElement.astro';
import APIBlock from 'src/components/api/APIBlock.astro';
import APIField from 'src/components/api/APIField.astro';
import ThemeTemplateVariables from 'src/content/docs/_shared/_theme_template_variables.astro';
## Overview
Template variables are provided to allow intelligent customization of theme templates. You can use Freemarker to display, hide, or otherwise logically modify what your end users sees based on these values.
Each template has different variables that are available to it. These variables can be used in the template to help with rendering the HTML. There are also a couple of common variables that are available in all of the pages. The common variables and the page specific variables are all listed below.
When the variable is FusionAuth specific, such as the tenant or application, the fields of the variable are the same as the JSON object described in the Retrieve section of the corresponding API documentation.
By default FusionAuth will provide HTML escaping on all values rendered in HTML, this protects you from script injection attacks. If you find a value that is being incorrectly escaped you may need to utilize the FreeMarker built in for no-escape `?no_esc`.
{/* don't update these variables directly. */}
{/* update site/_date/templates.yaml (further instructions there) */}
{/* update the JSON files in site/docs/src/json/themes/ with the new theme template key */}
{/* touch this file to regenerate (if in dev mode) */}
{/* that's it. the API and the theme form page will be automatically updated. */}
## Common Variables
The application resolved by the provided client_id provided on the request. If the request was made without a client_id then this variable will be undefined. Ensure you reference it using a null safe strategy if you are using some of the themed pages without a client_id.
See the [Application API](/docs/apis/applications) for details on this object.
The OAuth v2.0 `client_id` parameter. This is synonymous with FusionAuth's Application Id.
When there is an active SSO session, this variable will contain the currently logged in user. When an SSO session does not yet exist, this variable will be `null`. If the user has not checked the `Keep me signed in` option, there is no SSO session and this variable will be `null`.
See the [User API](/docs/apis/users) for details on this object.
A list of error messages that were generated during the processing of the request.
A map of field messages (usually errors) that were generated during the processing of the request. The key into the map is the name of the form field and the value is a list that contains the errors for that form field.
The locale used to localize messages.
You can find the JavaDoc for this object available here: https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html
The HttpServletRequest object that is part of the Java Servlet specification.
You can find the JavaDoc for this object available here: https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
The tenant that has been resolved for this template. This value has either been specified on the request by providing the `tenantId` request parameter or it has been resolved by other request parameters such as the `client_id`.
If you need to customize the look and feel for different tenants but desire to use the same theme to lower maintenance, store values in tenant.data.
For example, you could set tenant.data.customElements.buttonText and tenant.data.customElements.buttonColor, then retrieve values off these fields in the theme templates.
See the [Tenant API](/docs/apis/tenants) for details on this object.
The unique Tenant identifier, this is equivalent to `tenant.id`.
The theme that has been resolved for this template. This could be resolved based on the tenant or the application.
See the [Themes API](/docs/apis/themes) for details on this object.
The unique Theme identifier, this is equivalent to `theme.id`.
## Template Specific Variables
In addition to the common variables documented above, each template may have additional variables available to that only make sense in the context of this template. For example, the OAuth Authorize page (the login page) can access the `loginId` template variable, but this variable would make no sense on the email verification template.
{/* This displays all the page specific variables, pulled from the src/content/json/themes/templates.json file */}
# Upgrade Notes
import Aside from 'src/components/Aside.astro';
## Overview
New versions of FusionAuth sometimes include new or updated theme templates. If a new template is not part of a custom theme, FusionAuth will render the template from the default theme. Occasionally, modifications to existing templates or [helper macros](/docs/customize/look-and-feel/helpers) introduced in a FusionAuth release will require changes to an existing custom theme in order for it to continue functioning correctly.
This page contains notes on changes in recent versions of FusionAuth that require changes to a customized theme.
## Version 1.62.0
**OPTIONAL - ONLY NEEDED TO USE NEW FEATURE**
To utilize the new pre-verification feature in Advanced Registration Forms, you will need to make the following modifications. No custom theme modifications are required unless you want to use pre-verification.
### OAuth register template
Summary of changes:
* `[#if step == totalSteps]` => `[#if readyToRegister]`
* `[#if fields?has_content]` => `[#if advancedRegistration]`
* Remove `step`, `parentEmailRequired`, and `collectBirthDate` hidden fields
* Add a `
` if `formStep` is set below `passwordValidationRules` to explain pre-verification steps
* Add a `linkButton` for resending verification messages if `formStep?? && formStep.resendMessage??`
## Version 1.61.0 - `prompt` parameter
**OPTIONAL - ONLY NEEDED TO USE NEW FEATURE**
To ensure that FusionAuth is able to forward the `prompt` parameter to third party identity providers, you will need to make the following modifications.
### Helpers template
Update the `oauthHiddenFields`, `link` and `logoutLink` macros to add the `max_age` parameter. When editing a theme in the UI, this page will be shown as `Helpers`, and the API template name is `helpers`.
#### Macro oauthHiddenFields
Add `max_age` to the `oauthHiddenFields` macro.
```title="Add prompt"
[@hidden name="max_age"/]
```
For example, this is a macro that includes `max_age`:
``` title="After"
[#macro oauthHiddenFields]
[@hidden name="captcha_token"/]
[@hidden name="client_id"/]
[@hidden name="code_challenge"/]
[@hidden name="code_challenge_method"/]
[@hidden name="metaData.device.name"/]
[@hidden name="metaData.device.type"/]
[@hidden name="nonce"/]
[@hidden name="oauth_context"/]
[@hidden name="max_age"/]
[@hidden name="pendingIdPLinkId"/]
[@hidden name="prompt"/]
[@hidden name="redirect_uri"/]
[@hidden name="response_mode"/]
[@hidden name="response_type"/]
[@hidden name="scope"/]
[@hidden name="state"/]
[@hidden name="tenantId"/]
[@hidden name="timezone"/]
[@hidden name="user_code"/]
[/#macro]
```
#### Macro link
Add `max_age` to the `link` macro.
```title="Add max_age to the query string"
&max_age=${(max_age?url)!''}
```
``` title="After"
[#macro link url extraParameters=""]
[#nested/]
[/#macro]
```
#### Macro logoutLink
Add `max_age` to the `logoutLink` macro.
```title="Add max_age to the query string"
&max_age=${(max_age?url)!''}
```
``` title="After"
[#macro logoutLink redirectURI extraParameters=""]
[#-- Note that in order for the post_logout_redirect_uri to be correctly URL escaped, you must use this syntax for assignment --]
[#local post_logout_redirect_uri]${redirectURI}?tenantId=${(tenantId)!''}&client_id=${(client_id)!''}&nonce=${(nonce?url)!''}&pendingIdPLinkId=${(pendingIdPLinkId)!''}&redirect_uri=${(redirect_uri?url)!''}&response_mode=${(response_mode?url)!''}&response_type=${(response_type?url)!''}&scope=${(scope?url)!''}&state=${(state?url)!''}&timezone=${(timezone?url)!''}&metaData.device.name=${(metaData.device.name?url)!''}&metaData.device.type=${(metaData.device.type?url)!''}${(extraParameters?no_esc)!''}&code_challenge=${(code_challenge?url)!''}&code_challenge_method=${(code_challenge_method?url)!''}&user_code=${(user_code?url)!''}&prompt=${(prompt?url)!''}&max_age=${(max_age?url)!''}[/#local]
[#t]
[#nested/][#t]
[#t]
[/#macro]
```
## Version 1.61.0 - Multiple identity provider configurations
**OPTIONAL - ONLY NEEDED TO USE NEW FEATURE**
Previously the following [identity provider types](/docs/apis/identity-providers) were limited to a single configuration per FusionAuth instance: Apple, Epic Games, Facebook, Google, HYPR, LinkedIn, Nintendo, Sony PlayStation Network, Steam, Twitch, Twitter, and Xbox.
To enable support for multiple identity provider configurations of these types on a single login page, you will need to make the following modifications. The default theme is available on every FusionAuth instance as a point of comparison or guide to theme upgrades.
### Helpers template
Update the `alternativeLoginsScript`, `alternativeLogins`, and various external identity provider button rendering macros. When editing a theme in the UI, this page will be shown as `Helpers`, and the API template name is `helpers`.
#### Macro alternativeLoginsScript
Remove the `data-app-id` attribute from the `
```
Remove the `data-client-id` attribute from the `
```
Replace the `[#if]` block including Google's GSI client JavaScript and `Google.js`. Only one Google identity provider using the GSI client can be included on the page. See [Google IdP limitations](/docs/lifecycle/authenticate-users/identity-providers/social/google#limitations) for more detail.
```title="The old [#if] block"
[#if identityProviders["Google"]?has_content && identityProviders["Google"][0].lookupLoginMethod(clientId) != "UseRedirect"]
[/#if]
```
Here is the updated `[#if]` block. The updated logic selects the first Google IdP configured to use the GSI client and stores it in a `gsiIdentityProvider` variable to be used later in the `alternativeLogins` macro.
```title="The updated [#if] block"
[#if identityProviders["Google"]?has_content]
[#list identityProviders["Google"] as idp]
[#if idp.lookupLoginMethod(clientId) != "UseRedirect"]
[#-- Only one Google IdP can use the GSI APIs on a page. Assign the IdP for later use and load scripts. --]
[#assign gsiIdentityProvider = idp/]
[#break]
[/#if]
[/#list]
[/#if]
```
#### Macro alternativeLogins
The `alternativeLogins` macro checks for various IdP types in the `identityProviders` Freemarker variable and renders the appropriate button for that type. Several identity provider types now support multiple configurations and need to update rendering a single button to looping over the IdPs of that type.alternativeLogins
Here is an example rendering the "Sign in with Apple" button hard-coded to expect a single Apple IdP configuration.
```title="Single configuration"
[#if identityProviders["Apple"]?has_content]
[/#if]
```
Here is an example that supports rendering zero or more buttons based on available Apple IdP configurations by looping over all Apple IdP configurations and rendering the button with the `identityProvider` for that loop.
```title="Multiple configurations"
[#if identityProviders["Apple"]?has_content]
[#list identityProviders["Apple"] as identityProvider]
[/#list]
[/#if]
```
The above is just one example of several identity provider types requiring updates in `alternativeLogins` to render multiple buttons by replacing the hard-coded single instance with a loop. As you work through the different identity provider types, pay special attention to the key in the `identityProviders` map and the name of the button rendering macro in each case. The following identity provider types require this update in the `alternativeLogins` macro: Apple, Epic Games, Facebook, LinkedIn, Nintendo, Sony PlayStation Network, Steam, Twitch, Twitter, Xbox.
The Google identity provider type requires a bit more modification in the `alternativeLogins` macro in order to render the single button using the GSI client in addition to other Google IdP configurations with the `UseRedirect` login method. Remove the existing `[#if]` block and replace with the updated code below.
```title="Remove the [#if] block"
[#if identityProviders["Google"]?has_content]
[/#if]
```
In its place add two `[#if]` blocks. The first block checks whether it should render a GSI client button using the `gsiIdentityProvider` variable assigned in the `alternativeLoginsScript` macro. The second block calls the `googleButton` macro to render a login button for Google IdPs configured with the `UseRedirect` login method.
```title="Render GSI and UseRedirect Google buttons"
[#-- Check whether a Google IdP was assigned to use GSI APIs and render the button --]
[#if gsiIdentityProvider?has_content]
[/#if]
[#if identityProviders["Google"]?has_content]
[#list identityProviders["Google"] as identityProvider]
[#-- The googleButton macro only renders buttons for IdPs configured with the UseRedirect login methods --]
[@googleButton identityProvider=identityProvider clientId=clientId idpRedirectState=idpRedirectState/]
[/#list]
[/#if]
```
#### Macro appleButton
Replace the opening tag of the `