Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions bundled/minfraud.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions components/minfraud-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,24 @@ schemas:
The domain of the email address. Do not include the `@`. You do not
need to send this field unless you send the email address as an MD5
hash.
verification_time:
type: string
format: date-time
pattern: "^\\d{4}-\\d{2}-\\d{2}T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?(Z|[+-]([01]\\d|2[0-3]):[0-5]\\d)$"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A pattern next to format: date-time breaks Bean Validation in Java code that openapi-generator makes from this spec. The generator maps the field to OffsetDateTime, but it still copies the pattern into the property (DefaultCodegen.updatePropertyForString). The Java template beanValidationCore.mustache then adds @Pattern(regexp=...) to the field. Hibernate Validator supports @Pattern only on CharSequence.

Failure: a Spring user generates code from bundled/minfraud.yaml with useBeanValidation=true, which is the Spring generator default. When the user validates an Email, Hibernate Validator throws UnexpectedTypeException (HV000030: No validator could be found for constraint ... Pattern validating type java.time.OffsetDateTime).

event.time (line 116) and phone_verification_time (line 292) already have the same problem. The pattern came in with f662b29 in #6.

Suggested fix: remove the pattern from the date-time fields and rely on format: date-time. If you keep the pattern for non-Java tools, a separate PR for all three fields is fine.

🤖 Comment by Claude Opus 5.5.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is something we should worry about.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked this against the openapi-generator source at v7.26.0 (the latest release). I could not run the generator here, so this is from reading the code.

What is accurate:

  • DefaultCodegen.updatePropertyForString maps format: date-time to a date-time property. It then copies the pattern to the property for every string format.
  • Both Java/beanValidationCore.mustache and JavaSpring/beanValidationCore.mustache then emit @Pattern(regexp = ...). The Spring template skips only UUIDs.
  • Hibernate Validator has no @Pattern validator for OffsetDateTime. It throws UnexpectedTypeException (HV000030).

What I overstated is the impact:

  • The java client generator has useBeanValidation=false and performBeanValidation=false by default. A customer who generates a minFraud client gets no @Pattern annotation unless they opt in.
  • Only the spring generator defaults to useBeanValidation=true, and it generates server stubs. Only someone who builds their own minFraud mock server would hit this.

Is anyone breaking a spec? The OpenAPI document is valid. In OpenAPI 3.1 (JSON Schema 2020-12), pattern applies to the JSON string, and format is an annotation, so the two together are well defined. Hibernate Validator follows Jakarta Validation: a constraint with no validator for the field's type raises UnexpectedTypeException.

The defect is in openapi-generator. It converts the string to OffsetDateTime and then puts a string-only constraint on the converted type. Upstream treats this as a generator bug:

Java date-time still has the bug.

So I agree with Will: this PR does not need to change for this. If we want it fixed, the right fix is a short upstream issue for Java date-time.

🤖 Comment by Claude Opus 5.5.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I searched OpenAPITools/openapi-generator for an existing issue. I did not find one for @Pattern on a Java date-time property.

The same kind of bug (a string pattern put on a non-string Java type) is already reported for other types:

Two issues look related but are not:

A new issue would not be a duplicate. The fix would follow the UUID, enum, and byte-array fixes: skip @Pattern for isDate and isDateTime in Java/beanValidationCore.mustache and JavaSpring/beanValidationCore.mustache.

🤖 Comment by Claude Opus 5.5.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the pattern accepts any two digits for the month and the day, so 2026-13-45T14:25:00Z matches. JSON Schema 2020-12 treats format as an annotation by default, so a validator that does not assert formats accepts this value. The web service rejects it: the value passes the regex in mmtime.ParseRFC3339, but time.Parse fails, and the response has an INPUT_INVALID warning that client-side validation did not predict.

If you keep the pattern, suggest this date part:

^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T...

It does not catch a date such as 02-30, but it closes most of the gap. event.time (line 116) and phone_verification_time (line 292) use the same pattern.

🤖 Comment by Claude Opus 5.5.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems optional.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this is the third copy of the same RFC 3339 pattern. The other copies are event.time (line 116) and phone_verification_time (line 292). A change to the accepted form must go into all three places. If one copy is missed, the fields drift apart and lint does not report it.

Suggest one shared schema, for example schemas/DateTime with type, format, and pattern. Each field then uses $ref: "#/schemas/DateTime" with its own description next to it. OpenAPI 3.1 allows description next to $ref, and the Request properties (account, billing, and others) already use this form.

🤖 Comment by Claude Opus 5.5.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth it.

description: >-
The most recent date and time a verification of the email address was
attempted, if known, in RFC 3339 date-time format. The time must not
be before 1970-01-01T00:00:00Z or more than two days in the future.
For a time outside this range, MaxMind ignores the input and returns a
warning.
was_verification_successful:
type: boolean
description: >-
Whether the most recent verification that the end user controls this
email address was successful (e.g. by confirming a link sent to the
email address). `true` if the email verification was successful, or
`false` if the user failed email verification. Do not include this
field if you have not performed this check.
Address:
type: object
description: A billing or shipping address.
Expand Down
2 changes: 2 additions & 0 deletions examples/minfraud/request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ value:
email:
address: 977577b140bfb7c516e4746204fbdb01
domain: maxmind.com
verification_time: "2026-10-01T14:25:00Z"
was_verification_successful: true
event:
party: customer
shop_id: s2123
Expand Down
Loading