standard_id 0.33.0 → 0.34.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5341add412ad2ef395a4252d31f751e5b9eeb9df585f1eb3e5c276d7071211f
4
- data.tar.gz: b53b6dc29f5aa4a5994b040f5a6cdca2441c4c0c57cb2449b1fc1aead9caf4a7
3
+ metadata.gz: 984924490081d96a84ec4570541802d70414cac9dcf9dd325b8aba6ee7af7be2
4
+ data.tar.gz: c132d58daeea53090156fe42bfd3b6a7b8d8a2393d7ae7a3766e0c4ece0e8a6d
5
5
  SHA512:
6
- metadata.gz: a4162b488000bc8e889dba2887ffe2257ad8ac342d7612aff936c74fccbf30f22560f4194c39e0552446e3e6a93b2d335c2d34b3d27ceb67586fdeb188de5181
7
- data.tar.gz: fd04fc771429eaf0ed9efd4fa01fa85263983be3dd8cdf9a5b3df16194959387d929aa7bcf27711681dfb0262c3d57fd1df11f64761128646f43d9bb495ad8da
6
+ metadata.gz: 65dac8337e2bfa0784d43308d4c29eeeb8208c3b06b721a3f1a2f040eec1916ba35c00b8e69945f72c80a7240b95cb17ed4bf46c6939fe8c78508c44bf3363b9
7
+ data.tar.gz: eb1acc6703201fa5955494aec635f1821ea4d9689b49f73703736f853deb166b5eeaec1adcb20fe79c083f15903301e60829da0497ec0e138af49d2f406e4b02
data/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.34.0] - 2026-07-31
11
+
12
+ ### Added
13
+
14
+ - **`config.verify_issuer`** — decouples MINTING an `iss` claim from REQUIRING one. `nil` (default) follows `config.issuer`, which is the historic behaviour and changes nothing. Set `false` to stamp `iss` on new tokens without yet verifying it.
15
+
16
+ This exists because the two were one switch, which made adopting an issuer a flag day: every token already in flight was minted without an `iss`, so setting `config.issuer` rejected all of them at once — every access token and, far worse, every refresh token. An app that had never configured an issuer had no safe single step, which is where `nutripod-web` was stuck (rarebit-one/nutripod-web#1111) and why it could not retire its hand-rolled discovery controller with the rest of the estate.
17
+
18
+ Migration: set `issuer` with `verify_issuer = false`, wait out `refresh_token_lifetime` (the long pole — access tokens are short), then remove the override. Setting `true` with no issuer raises at boot rather than silently verifying against `nil` and accepting anything.
19
+
10
20
  ## [0.33.0] - 2026-07-30
11
21
 
12
22
  ### Added
@@ -12,6 +12,26 @@ StandardId::ConfigSchema.define do
12
12
  field :passwordless_email_sender, type: :any, default: nil
13
13
  field :passwordless_sms_sender, type: :any, default: nil
14
14
  field :issuer, type: :string, default: nil
15
+
16
+ # Whether `JwtService.decode` REQUIRES a matching `iss` claim.
17
+ #
18
+ # `nil` (default) means "follow the issuer": verification is on exactly
19
+ # when `issuer` is set. That is the historic behaviour and is what you
20
+ # want once an issuer has always been configured.
21
+ #
22
+ # Set `false` to MINT an `iss` claim without yet REQUIRING one. This
23
+ # exists because the two were coupled, and that coupling makes adopting an
24
+ # issuer an all-or-nothing flag day: every token already in flight was
25
+ # minted without an `iss`, so turning the issuer on rejected all of them at
26
+ # once — every access token and, far worse, every refresh token. For an app
27
+ # that had never set an issuer there was no safe single step, which is
28
+ # exactly the position nutripod-web was stuck in (rarebit-one/nutripod-web#1111).
29
+ #
30
+ # The migration is then: set `issuer` with `verify_issuer = false`, wait
31
+ # out `refresh_token_lifetime` (the long pole — access tokens are short),
32
+ # then remove the override. Setting `true` with no issuer raises at boot
33
+ # rather than silently verifying nothing.
34
+ field :verify_issuer, type: :boolean, default: nil
15
35
  field :login_url, type: :string, default: nil
16
36
  field :allowed_post_logout_redirect_uris, type: :array, default: []
17
37
  field :account_scope, type: :any, default: nil
@@ -52,6 +52,30 @@ module StandardId
52
52
  SUPPORTED_ALGORITHMS[algorithm] || raise(ArgumentError, "Unsupported algorithm: #{algorithm}. Supported: #{SUPPORTED_ALGORITHMS.keys.join(', ')}")
53
53
  end
54
54
 
55
+ # Whether decode REQUIRES a matching `iss`. `nil` (the default) follows the
56
+ # issuer, which is the historic behaviour: verification on exactly when an
57
+ # issuer is configured.
58
+ #
59
+ # The override exists so an app can START MINTING an `iss` without yet
60
+ # REQUIRING one. Coupled, adopting an issuer is a flag day — every token
61
+ # already in flight was minted without the claim, so enabling the issuer
62
+ # rejects all of them at once, refresh tokens included. Decoupled, the app
63
+ # sets `verify_issuer = false`, waits out `refresh_token_lifetime`, and then
64
+ # drops the override with no window in which valid tokens are refused.
65
+ def self.verify_issuer?
66
+ configured = StandardId.config.verify_issuer
67
+ return StandardId.config.issuer.present? if configured.nil?
68
+
69
+ if configured && StandardId.config.issuer.blank?
70
+ raise StandardId::ConfigurationError,
71
+ "verify_issuer is true but no issuer is configured — decode would " \
72
+ "verify against nil and accept any token. Set config.issuer, or " \
73
+ "leave verify_issuer nil to follow it."
74
+ end
75
+
76
+ configured
77
+ end
78
+
55
79
  def self.asymmetric?
56
80
  algorithm_config[:type] == :asymmetric
57
81
  end
@@ -152,7 +176,7 @@ module StandardId
152
176
  def self.decode(token, allowed_audiences: nil)
153
177
  options = { algorithms: [algorithm] }
154
178
 
155
- if StandardId.config.issuer.present?
179
+ if StandardId.config.issuer.present? && verify_issuer?
156
180
  options[:iss] = StandardId.config.issuer
157
181
  options[:verify_iss] = true
158
182
  end
@@ -1,3 +1,3 @@
1
1
  module StandardId
2
- VERSION = "0.33.0"
2
+ VERSION = "0.34.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standard_id
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.33.0
4
+ version: 0.34.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaryl Sim