kratos icon indicating copy to clipboard operation
kratos copied to clipboard

Verified status is lost when moving an email address from a string field to an array of string field

Open jletroui opened this issue 1 year ago • 3 comments

Preflight checklist

Ory Network Project

No response

Describe the bug

Let's say we have that kind of schema:

{
  "$id": "https://db.theshifters.org/schemas/kratos/identity.default.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Person",
  "type": "object",
  "properties": {
    "traits": {
      "type": "object",
      "properties": {
        "main_email": {
          "type": "string",
          "format": "email",
          "ory.sh/kratos": {
            "credentials": {
              "password": {
                "identifier": true
              }
            },
            "verification": {
              "via": "email"
            },
            "recovery": {
              "via": "email"
            }
          }
        },
        "secondary_emails": {
          "type": "array",
          "items": [
            {
              "type": "string",
              "format": "email",
              "ory.sh/kratos": {
                "verification": {
                  "via": "email"
                }
              }
            }
          ]
        },
      "required": [
        "main_email"
      ],
      "additionalProperties": false
    }
  }
}

When exchanging a verified "secondary" email with the verified "main email" in a single trait update:

  • Observed: the new "main email" (previously one of the secondary ones) retains its verified status, but the new "secondary email" (previous the main one) loses it.

  • Expected: both email adresses are still verified after the exchange.

This is preventing a smooth user email "promotion", with users having to re verify already verified emails.

Reproducing the bug

  1. Create the above schema
  2. Create an identity for this schema with both a main email, and a secondary one, for example using the Create identity endpoint
  3. Verify both emails using the verification flow
  4. Use the Update identity endpoint to update the trait, simply exchanging the 2 fields
  5. Query the identity using the Get identity endpoint

Observed: the email address initially setup as the main email is not verified anymore.

Relevant log output

No response

Relevant configuration

selfservice:

    flows:
        verification:
            enabled: true   # default false
            use: code       # default code

Version

1.0.0

On which operating system are you observing this issue?

Linux

In which environment are you deploying?

Docker Compose

Additional Context

No response

jletroui avatar Oct 31 '23 21:10 jletroui

It seems Kratos is destroying verifiable addresses before inserting new ones instead of upserting addresses and deleting what's not needed anymore. If the existing addresses status is not well hydrated in the updated identity struct, then that might explain the issue.

jletroui avatar Oct 31 '23 22:10 jletroui

Also, I must mention that the update of the identity at step 4 is trigerring the "after verification" webhook (if one is configured), even though no verification took place at this step. This is not unmanageable, but is a bit surprising.

jletroui avatar Oct 31 '23 22:10 jletroui

Hello! Would there be news on this issue? I also have to add that only the first email address added in an array is trigerring the verification. Other emails are not verified. For example, using the same setup as the description of the issue, this identity has a total of 4 emails:

kratos=# select traits from identities where id='fb590460-1e4e-4230-84ea-cc4b699f2db0';
                                                                                                                  traits
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 {"main_email": "[email protected]", "secondary_emails": ["[email protected]", "[email protected]", "[email protected]"]}
(1 row)

But only the main one and the first of the secondary ones has ever triggerred a verification:

kratos=# select value, status from identity_verifiable_addresses where identity_id = 'fb590460-1e4e-4230-84ea-cc4b699f2db0';
     value      |  status
----------------+-----------
 [email protected] | completed
 [email protected] | completed
(2 rows)

jletroui avatar May 15 '24 23:05 jletroui