kratos icon indicating copy to clipboard operation
kratos copied to clipboard

Bug: Changing an identifier without having another identifier set results in an internal server error

Open dadrus opened this issue 4 years ago • 0 comments

Describe the bug

Kratos allows to define arbitrary traits for an identity. If the identity schema is defined to have two identifiers, e.g. email and username with latter being optional (see the json schema below) and the user is not required to set the username during the registration, there is no way to update the email address without setting the username. An attempt to do so results in an Internal error raised by Kratos with a message "Unable to create identity credentials with missing or empty identifier".

Reproducing the bug Define the identity json schema as follows:

{
  "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Person",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "title": "E-Mail",
          "minLength": 3,
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            },
            "verification": {
              "via": "email"
            },
            "recovery": {
              "via": "email"
            }
          }
        },
        "username": {
          "type": "string",
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            }
          }
        }
      },
      "required": [
        "email"
      ],
      "additionalProperties": false
    }
  }
}

Don't ask for the username during the registration, but enable changing the username, as well as the email using the settings flow. If the user only updates its email, one can see the following request to Kratos:

POST  http://127.0.0.1:4433/self-service/settings?flow=d98e4f89-baac-4c3e-845f-267ab2b6a6e0

csrf_token=<csrf token value>&traits.email=<new email address>&traits.username=&method=profile

As you can see from the above snippet the traits.username is not set (there is no value). The not set username is however not ignored by Kratos. Instead it is unmarshalled as an empty string, resulting in the aforesaid error raised in https://github.com/ory/kratos/blob/9c365eac2561ae4b7eb6e824760b1832261ef226/persistence/sql/persister_identity.go#L143

Expected behavior

Optional identifiers should be treated as such. With other words, Kratos should ignore unset identifiers in the settings flow if another (required) identifier is set.

dadrus avatar Sep 27 '21 08:09 dadrus