standard_id 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/app/models/standard_id/email_identifier.rb +22 -1
- data/lib/standard_id/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f929d1f67a0302d3b2f93043c5ac009d8d98195a8c1f3f5c7e79ca45210873dc
|
|
4
|
+
data.tar.gz: 1b58091aeb06c9d3a13a3fc57dd710688dd75c8be48d2d950b19bfc400cb00d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b4dbbac7f24a1cb89efa9787e2acbed6ab4f8fa531d84c525344f3069c4d6bd0be2d5a17f014074f700c5af88be2b6c071ed6d1ecb94d1b27fec172bf8d3b169
|
|
7
|
+
data.tar.gz: 265319cf5f65851df3e4a7f8a24d3aa4765d001a27e4d89797e10cc372f4515d558b785863810cd71e7f8d577e4388c1b8f98dfe273218824e29fa7f8e3f9183
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.31.0] - 2026-07-27
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **`EmailIdentifier` now rejects dot-atom violations in the local part.**
|
|
15
|
+
`URI::MailTo::EMAIL_REGEXP` models the local part as one flat character class
|
|
16
|
+
that happens to include `.`, so it accepted dot placements RFC 5322 forbids in
|
|
17
|
+
an unquoted local part — a leading dot, a trailing dot, and consecutive dots.
|
|
18
|
+
`a..b@example.com` passed it. Email service providers do not accept these:
|
|
19
|
+
Postmark rejects them at *send* time with `InvalidEmailRequestError`, so a
|
|
20
|
+
typo accepted at sign-up only surfaced much later as a failed delivery job,
|
|
21
|
+
long after the user could have corrected it. The domain pattern is
|
|
22
|
+
`URI::MailTo`'s own, unchanged; only the local part is stricter.
|
|
23
|
+
|
|
24
|
+
**Consumer impact.** Addresses your app previously accepted may now be
|
|
25
|
+
rejected at the identifier layer. The validation is scoped to a *changed*
|
|
26
|
+
value, so rows created under the looser rule keep saving until someone edits
|
|
27
|
+
the address — an existing account will not be locked out of a flow that merely
|
|
28
|
+
stamps `verified_at`. Check any test fixtures or seeds using addresses with
|
|
29
|
+
doubled or edge dots.
|
|
30
|
+
|
|
10
31
|
## [0.30.0] - 2026-07-26
|
|
11
32
|
|
|
12
33
|
### Added
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
module StandardId
|
|
2
2
|
class EmailIdentifier < Identifier
|
|
3
|
+
# `URI::MailTo::EMAIL_REGEXP` models the local part as one flat character
|
|
4
|
+
# class that happens to include `.`, so it accepts dot placements RFC 5322
|
|
5
|
+
# forbids in an unquoted local part: a leading dot, a trailing dot, and
|
|
6
|
+
# consecutive dots. `a..b@example.com` passes it.
|
|
7
|
+
#
|
|
8
|
+
# ESPs do not. Postmark rejects such an address at send time with
|
|
9
|
+
# `InvalidEmailRequestError`, so a typo accepted at sign-up surfaces much
|
|
10
|
+
# later as a failed delivery job that no operator can act on — the address
|
|
11
|
+
# is already stored and the user is long gone.
|
|
12
|
+
#
|
|
13
|
+
# Enforce the dot-atom rule instead: the local part is dot-separated atoms,
|
|
14
|
+
# each at least one character. The domain pattern is `URI::MailTo`'s,
|
|
15
|
+
# unchanged.
|
|
16
|
+
LOCAL_PART = %r{[A-Za-z0-9!\#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!\#$%&'*+/=?^_`{|}~-]+)*}
|
|
17
|
+
DOMAIN = /[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*/
|
|
18
|
+
EMAIL_FORMAT = /\A#{LOCAL_PART}@#{DOMAIN}\z/
|
|
19
|
+
|
|
3
20
|
normalizes :value, with: ->(e) { e.strip.downcase }
|
|
4
21
|
|
|
5
|
-
|
|
22
|
+
# Scoped to a changed value so tightening the rule cannot strand an account
|
|
23
|
+
# created under the looser one: an existing row keeps working until someone
|
|
24
|
+
# actually edits the address. Without this, saving an unrelated attribute on
|
|
25
|
+
# a grandfathered identifier would start raising.
|
|
26
|
+
validates :value, format: { with: EMAIL_FORMAT }, if: :value_changed?
|
|
6
27
|
end
|
|
7
28
|
end
|
data/lib/standard_id/version.rb
CHANGED