Files
oidc/example
Marc Alvarez b4dca67d3c fix: consistently handle string-valued boolean fields from non-compliant OIDC providers (#791)
AWS Cognito (and potentially other providers) return `email_verified`
and `phone_number_verified` as strings (`"true"`/`"false"`) instead of
proper JSON booleans, violating the [OIDC
specification](https://openid.net/specs/openid-connect-basic-1_0.html#StandardClaims).

AWS Documentation confirms this:
> Currently, Amazon Cognito returns the values for email_verified and
phone_number_verified as strings.

_Source:
https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html#get-userinfo-response-sample_

### The Problem

The `zitadel/oidc` library currently handles this inconsistently:
  -  `EmailVerified` uses the custom `Bool` type (added in #139)
  -  `PhoneNumberVerified` uses Go's standard `bool`
  
This forces developers to handle semantically identical fields
differently:

```go
// Currently inconsistent code path
userInfo.EmailVerified = oidc.Bool(emailValue)    // Cast
userInfo.PhoneNumberVerified = phoneValue      // No cast
```

Additionally, the existing `Bool.UnmarshalJSON` implementation meant
that false values couldn't overwrite true.

### Solution

Applied `Bool` type consistently to both fields and simplified
`Bool.UnmarshalJSON` using a direct switch statement to:

  - Handle standard JSON booleans (true/false)
  - Handle AWS Cognito string format ("true"/"false")
  - Return errors on invalid input instead of silently failing
  - Allow false to overwrite true

 Updated tests to match codebase conventions, as well.

 ### Impact

`PhoneNumberVerified` changes from `bool` to `Bool` (type alias of
`bool`). Most consumer code should work as-is since `Bool` is just a
type alias. Direct type assertions would need updating.

### Definition of Ready

- [X] I am happy with the code
- [X] Short description of the feature/issue is added in the pr
description
- [ ] PR is linked to the corresponding user story
- [X] Acceptance criteria are met
- [ ] All open todos and follow ups are defined in a new ticket and
justified
- [ ] Deviations from the acceptance criteria and design are agreed with
the PO and documented.
- [X] No debug or dead code
- [X] My code has no repetitions
- [X] Critical parts are tested automatically
- [x] Where possible E2E tests are implemented
- [X] Documentation/examples are up-to-date
- [ ] All non-functional requirements are met
- [x] Functionality of the acceptance criteria is checked manually on
the dev system.

Co-authored-by: Wim Van Laer <wim07101993@users.noreply.github.com>
2026-01-12 09:33:18 +00:00
..