verikloak 0.4.0 → 0.4.1

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: a8fea8bb10499fcd42f05ecc1eadda3008c5215b1907807351c9b4a8a4a420a4
4
- data.tar.gz: '05476942149fcdf5f5cbe9605524c8a8ea79359f1b9533b623d08e7b130a0290'
3
+ metadata.gz: 2acaa72f8a2eee680d3c439b99488a48e7f512de4fb1ab2092ff781f13799c89
4
+ data.tar.gz: 5918e081c8be11ef410170f38cd4f520c2cfe55a5b34ac9e5363eddedc297a75
5
5
  SHA512:
6
- metadata.gz: 3133b44cd8ada0217916d82b5b725ed5bd50c445c727969478b6af67cb712de8247d7a124585f5ca2ee763ec69171f3c65b70be60fdb91c16f6d5467b2853b9a
7
- data.tar.gz: c790ce4825f32e2d17187b2de7e3564e765274517b4ca59f0fbd8b61a7fbe22edac4e9f72cee91a92ec7e9b2bc6529da74e4d9b3d22abf3d068a3bff2f78a4df
6
+ metadata.gz: 8ee86f3b6586beac55b0a4e54f9815f58c99edf57bb2661851ae39e4f9f0bab80126643b903802ec90c266ca9fd16bac92550fd18d0c21be52487bfbb80c756e
7
+ data.tar.gz: 83f47c238874faee6b3391a833e7e3966b04637b3859b64e01943243d5aa1c64bf22986586a00c85ac651928cec476b7a8e05b030fd23172abf5ce60a3ff0e65
data/CHANGELOG.md CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.4.1] - 2026-02-15
11
+
12
+ ### Added
13
+ - `Verikloak::SkipPathMatcher` now supports `Regexp` patterns alongside string paths, restoring compatibility with `verikloak-audience` skip_paths Regexp usage
14
+
15
+ ---
16
+
10
17
  ## [0.4.0] - 2026-02-15
11
18
 
12
19
  ### Security
data/README.md CHANGED
@@ -238,7 +238,7 @@ For a full list of error cases and detailed explanations, please see the [ERRORS
238
238
  | `discovery_url` | Yes | Full URL to your realm's OIDC discovery doc |
239
239
  | `audience` | Yes | Your client ID (checked against `aud`). Accepts a String or callable returning a String/Array per request. |
240
240
  | `issuer` | No | Optional override for the expected `iss` claim; defaults to the discovery `issuer`. |
241
- | `skip_paths` | No | Array of paths or wildcards to skip authentication, e.g. `['/', '/health', '/public/*']`. **Note:** Regex patterns are not supported. |
241
+ | `skip_paths` | No | Array of paths, wildcards, or `Regexp` patterns to skip authentication, e.g. `['/', '/health', '/public/*', /\A\/api\/v\d+\/public/]`. |
242
242
  | `discovery` | No | Inject custom Discovery instance (advanced/testing) |
243
243
  | `jwks_cache` | No | Inject custom JwksCache instance (advanced/testing) |
244
244
  | `leeway` | No | Clock skew tolerance (seconds) applied during JWT verification. Defaults to `TokenDecoder::DEFAULT_LEEWAY`. |
@@ -259,17 +259,17 @@ Plain paths are exact-match only, while `/*` at the end enables prefix matching.
259
259
  For example:
260
260
 
261
261
  ```ruby
262
- skip_paths: ['/', '/health', '/rails/*', '/public/src']
262
+ skip_paths: ['/', '/health', '/rails/*', '/public/src', /\A\/api\/v\d+\/public/]
263
263
  ```
264
264
  - `'/'` matches only the root path.
265
265
  - `'/health'` matches **only** `/health` (for subpaths, use `'/health/*'`).
266
266
  - `'/rails/*'` matches `/rails` itself as well as `/rails/foo`, `/rails/foo/bar`, etc.
267
267
  - `'/public/src'` matches `/public/src`, but does **not** match `/public`, any subpath like `/public/src/html` or other siblings like `/public/css`.
268
+ - `Regexp` patterns are matched against the normalized path via `Regexp#match?`. For example, `/\A\/api\/v\d+\/public/` matches `/api/v1/public/docs`, `/api/v2/public/info`, etc.
268
269
 
269
270
  Paths **not matched** by any `skip_paths` entry will require a valid JWT.
270
271
 
271
- **Note:** Regex patterns are not supported. Only literal paths and `*` wildcards are allowed.
272
- Internally, `*` expands to match nested paths, so patterns like `/rails/*` are valid. This differs from regex; for example, `'/rails'` alone matches only `/rails`, while `'/rails/*'` covers both `/rails` and deeper subpaths.
272
+ Internally, `*` expands to match nested paths, so patterns like `/rails/*` are valid. `'/rails'` alone matches only `/rails`, while `'/rails/*'` covers both `/rails` and deeper subpaths. For more complex matching needs, use `Regexp` patterns.
273
273
 
274
274
  #### Option: `audience`
275
275
 
@@ -12,6 +12,7 @@ module Verikloak
12
12
  # * `'/'` — matches only the root path
13
13
  # * `'/foo'` — exact-match only (matches `/foo` but **not** `/foo/...`)
14
14
  # * `'/foo/*'` — prefix match (matches `/foo` and any nested path under it)
15
+ # * `Regexp` — matched against the normalized path via `Regexp#match?`
15
16
  module SkipPathMatcher
16
17
  private
17
18
 
@@ -23,8 +24,9 @@ module Verikloak
23
24
  np = normalize_path(path)
24
25
  return true if @skip_root && np == '/'
25
26
  return true if @skip_exacts.include?(np)
27
+ return true if @skip_prefixes.any? { |prefix| np == prefix || np.start_with?("#{prefix}/") }
26
28
 
27
- @skip_prefixes.any? { |prefix| np == prefix || np.start_with?("#{prefix}/") }
29
+ @skip_regexps.any? { |re| re.match?(np) }
28
30
  end
29
31
 
30
32
  # Normalizes paths for stable comparisons:
@@ -46,37 +48,44 @@ module Verikloak
46
48
  # * `@skip_root` — whether `'/'` is present
47
49
  # * `@skip_exacts` — exact-match set (e.g. `'/health'`)
48
50
  # * `@skip_prefixes` — wildcard prefixes for `'/*'` (e.g. `'/public'`)
51
+ # * `@skip_regexps` — Regexp patterns matched via `Regexp#match?`
49
52
  #
50
- # @param paths [Array<String>]
53
+ # @param paths [Array<String, Regexp>]
51
54
  # @return [void]
52
55
  def compile_skip_paths(paths)
53
56
  @skip_root = false
54
57
  @skip_exacts = Set.new
55
58
  @skip_prefixes = []
59
+ @skip_regexps = []
56
60
 
57
- Array(paths).each do |raw|
58
- next if raw.nil?
61
+ Array(paths).each { |raw| classify_skip_entry(raw) }
59
62
 
60
- s = raw.to_s.strip
61
- next if s.empty?
62
-
63
- if s == '/'
64
- @skip_root = true
65
- next
66
- end
63
+ @skip_prefixes.uniq!
64
+ end
67
65
 
68
- if s.end_with?('/*')
69
- prefix = normalize_path(s.chomp('/*'))
70
- next if prefix == '/' # root is handled by @skip_root
66
+ # Classify a single skip-path entry into the appropriate bucket.
67
+ #
68
+ # @param raw [String, Regexp, nil]
69
+ # @return [void]
70
+ def classify_skip_entry(raw)
71
+ return if raw.nil?
71
72
 
72
- @skip_prefixes << prefix
73
- else
74
- exact = normalize_path(s)
75
- @skip_exacts << exact
76
- end
73
+ if raw.is_a?(Regexp)
74
+ @skip_regexps << raw
75
+ return
77
76
  end
78
77
 
79
- @skip_prefixes.uniq!
78
+ s = raw.to_s.strip
79
+ return if s.empty?
80
+
81
+ if s == '/'
82
+ @skip_root = true
83
+ elsif s.end_with?('/*')
84
+ prefix = normalize_path(s.chomp('/*'))
85
+ @skip_prefixes << prefix unless prefix == '/'
86
+ else
87
+ @skip_exacts << normalize_path(s)
88
+ end
80
89
  end
81
90
  end
82
91
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Verikloak
4
4
  # Defines the current version of the Verikloak gem.
5
- VERSION = '0.4.0'
5
+ VERSION = '0.4.1'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verikloak
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - taiyaky
@@ -111,7 +111,7 @@ metadata:
111
111
  source_code_uri: https://github.com/taiyaky/verikloak
112
112
  changelog_uri: https://github.com/taiyaky/verikloak/blob/main/CHANGELOG.md
113
113
  bug_tracker_uri: https://github.com/taiyaky/verikloak/issues
114
- documentation_uri: https://rubydoc.info/gems/verikloak/0.4.0
114
+ documentation_uri: https://rubydoc.info/gems/verikloak/0.4.1
115
115
  rubygems_mfa_required: 'true'
116
116
  rdoc_options: []
117
117
  require_paths: