omniauth-spotify 1.0.2 → 1.0.4

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: cc8741608bbfa92369035a3998b72a27b73a17a67b603688d5cc55d9fdb47728
4
- data.tar.gz: fdc122f1bb1adc612c2bb2de212c69da8a16ec4323a4b79ba178fccef1f4532f
3
+ metadata.gz: de25e7d9dc464fdd5bb4b7b8ffd945fd7ef6ccd025ac8d938f3bad368a1b7ae1
4
+ data.tar.gz: 4ec21d397695d96c73f3eff5d202462d62d882430b25e272406b60cc25955c53
5
5
  SHA512:
6
- metadata.gz: ded11472a459b53ffcb5250e0f581a311b516cc1c2985d52ffdec91c3b0f1bb0596c64aa3210ca2d465ca426c50e1b1d10cdf1cb01a3340c9b2e6912a98536f6
7
- data.tar.gz: ea62dfdad9b92d5813a3fffe1752e31d74d15f7e92a013d854a56b50dcf4454e17e072dd38c70f9f94225c475ee3aae70e0c7c93924f39d4de3b965ece499a7b
6
+ metadata.gz: 4735b6ad5984b8cbb9ab8d1e37e942b6a90edf67e0b0cfef1595133e8ccfd76320fa0e4048c40c15973719868586ea42fbb71a5aa6c8d3ede64bc6b6f5ba3149
7
+ data.tar.gz: 60e28c8cb306d54f96747c6a52120a61e4aa3156c903ee6ba67cfc4607bfe665262c622c79a13f13b54e8c6f4151839ee6e8244f306e208031acf823c5f6d34c
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # OmniAuth Spotify Strategy
2
2
 
3
3
  [![Test](https://github.com/icoretech/omniauth-spotify/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/icoretech/omniauth-spotify/actions/workflows/test.yml?query=branch%3Amain)
4
- [![Gem Version](https://img.shields.io/gem/v/omniauth-spotify.svg)](https://rubygems.org/gems/omniauth-spotify)
4
+ [![Gem Version](https://badge.fury.io/rb/omniauth-spotify.svg)](https://badge.fury.io/rb/omniauth-spotify)
5
5
 
6
6
  `omniauth-spotify` provides a Spotify OAuth2 strategy for OmniAuth.
7
7
 
@@ -35,6 +35,9 @@ end
35
35
  - Spotify developer dashboard: <https://developer.spotify.com/dashboard>
36
36
  - OAuth scopes reference: <https://developer.spotify.com/documentation/web-api/concepts/scopes>
37
37
  - Register callback URL (example): `https://your-app.example.com/auth/spotify/callback`
38
+ - The redirect URI must match exactly in Spotify's dashboard.
39
+ - Spotify requires HTTPS redirect URIs except for loopback IP literals such as
40
+ `http://127.0.0.1:3000/auth/spotify/callback`; `localhost` is not accepted.
38
41
 
39
42
  ## Options
40
43
 
@@ -103,7 +106,38 @@ Example payload from `request.env['omniauth.auth']` (real shape, anonymized):
103
106
  }
104
107
  ```
105
108
 
106
- `info.image` and `info.birthdate` are included only when Spotify returns those fields.
109
+ `info.email`, `info.image`, `info.birthdate`, `info.country_code`,
110
+ `info.product`, and `info.follower_count` are included only when Spotify
111
+ returns those fields.
112
+
113
+ ## Spotify API Changelog Notes
114
+
115
+ The strategy still uses Spotify's authorization-code flow and
116
+ `GET https://api.spotify.com/v1/me` for the current user profile.
117
+
118
+ Recent changelog items reviewed:
119
+
120
+ - February 2026 Development Mode changes: Spotify deprecated `country`,
121
+ `email`, `explicit_content`, `followers`, and `product` and may omit them
122
+ from `GET /me` user payloads for affected development-mode apps. The gem
123
+ treats these fields as optional and omits absent values from `info`.
124
+ - March 2026 changelog: Spotify reverted the February removal of Album and
125
+ Track `external_ids`. This gem does not call Album or Track endpoints and
126
+ does not map `external_ids`, so no code change is required for that reversal.
127
+ - February 2025 redirect URI security changes: Spotify rejects `localhost`
128
+ redirect URIs and requires HTTPS except for explicit loopback IP literals.
129
+ - Development Mode access changes: if `GET /me` returns `403` with a message
130
+ requiring Spotify Premium for the app owner, OAuth token exchange may still
131
+ be working; the Web API call is blocked by Spotify account/app policy, not by
132
+ this strategy's auth-hash mapping.
133
+
134
+ References:
135
+
136
+ - <https://developer.spotify.com/documentation/web-api/tutorials/february-2026-migration-guide>
137
+ - <https://developer.spotify.com/documentation/web-api/references/changes/february-2026>
138
+ - <https://developer.spotify.com/documentation/web-api/references/changes/march-2026>
139
+ - <https://developer.spotify.com/documentation/web-api/concepts/redirect_uri>
140
+ - <https://developer.spotify.com/blog/2026-02-06-update-on-developer-access-and-platform-security>
107
141
 
108
142
  ## Development
109
143
 
@@ -128,7 +162,7 @@ RAILS_VERSION='~> 8.1.0' bundle exec rake test_rails_integration
128
162
  ## Compatibility
129
163
 
130
164
  - Ruby: `>= 3.2` (tested on `3.2`, `3.3`, `3.4`, `4.0`)
131
- - `omniauth-oauth2`: `>= 1.8`, `< 1.9`
165
+ - `omniauth-oauth2`: `>= 1.8`, `< 2.0`
132
166
  - Rails integration lanes: `~> 7.1.0`, `~> 7.2.0`, `~> 8.0.0`, `~> 8.1.0`
133
167
 
134
168
  ## Release
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniAuth
4
4
  module Spotify
5
- VERSION = '1.0.2'
5
+ VERSION = "1.0.4"
6
6
  end
7
7
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'omniauth/spotify/version'
4
- require 'omniauth/strategies/spotify'
3
+ require "omniauth/spotify/version"
4
+ require "omniauth/strategies/spotify"
@@ -1,67 +1,67 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
- require 'omniauth-oauth2'
3
+ require "date"
4
+ require "omniauth-oauth2"
5
5
 
6
6
  module OmniAuth
7
7
  module Strategies
8
8
  # OmniAuth strategy for Spotify OAuth2.
9
9
  class Spotify < OmniAuth::Strategies::OAuth2
10
- option :name, 'spotify'
10
+ option :name, "spotify"
11
11
 
12
- FORCE_APPROVAL_KEY = 'omniauth_spotify_force_approval?'
13
- LEGACY_FORCE_APPROVAL_KEY = 'ommiauth_spotify_force_approval?'
12
+ FORCE_APPROVAL_KEY = "omniauth_spotify_force_approval?"
13
+ LEGACY_FORCE_APPROVAL_KEY = "ommiauth_spotify_force_approval?"
14
14
 
15
15
  option :client_options,
16
- site: 'https://api.spotify.com',
17
- authorize_url: 'https://accounts.spotify.com/authorize',
18
- token_url: 'https://accounts.spotify.com/api/token',
19
- connection_opts: {
20
- headers: {
21
- user_agent: 'icoretech-omniauth-spotify gem',
22
- accept: 'application/json',
23
- content_type: 'application/json'
24
- }
25
- }
26
-
27
- uid { raw_info['id'] }
16
+ site: "https://api.spotify.com",
17
+ authorize_url: "https://accounts.spotify.com/authorize",
18
+ token_url: "https://accounts.spotify.com/api/token",
19
+ connection_opts: {
20
+ headers: {
21
+ user_agent: "icoretech-omniauth-spotify gem",
22
+ accept: "application/json",
23
+ content_type: "application/json"
24
+ }
25
+ }
26
+
27
+ uid { raw_info["id"] }
28
28
 
29
29
  info do
30
30
  {
31
- name: raw_info['display_name'] || raw_info['id'],
32
- nickname: raw_info['id'],
33
- email: raw_info['email'],
34
- urls: raw_info['external_urls'],
31
+ name: raw_info["display_name"] || raw_info["id"],
32
+ nickname: raw_info["id"],
33
+ email: raw_info["email"],
34
+ urls: raw_info["external_urls"],
35
35
  image: image_url,
36
- birthdate: parse_birthdate(raw_info['birthdate']),
37
- country_code: raw_info['country'],
38
- product: raw_info['product'],
39
- follower_count: raw_info.dig('followers', 'total')
36
+ birthdate: parse_birthdate(raw_info["birthdate"]),
37
+ country_code: raw_info["country"],
38
+ product: raw_info["product"],
39
+ follower_count: raw_info.dig("followers", "total")
40
40
  }.compact
41
41
  end
42
42
 
43
43
  credentials do
44
44
  {
45
- 'token' => access_token.token,
46
- 'refresh_token' => access_token.refresh_token,
47
- 'expires_at' => access_token.expires_at,
48
- 'expires' => access_token.expires?,
49
- 'scope' => token_scope
45
+ "token" => access_token.token,
46
+ "refresh_token" => access_token.refresh_token,
47
+ "expires_at" => access_token.expires_at,
48
+ "expires" => access_token.expires?,
49
+ "scope" => token_scope
50
50
  }.compact
51
51
  end
52
52
 
53
53
  extra do
54
54
  {
55
- 'raw_info' => raw_info
55
+ "raw_info" => raw_info
56
56
  }
57
57
  end
58
58
 
59
59
  def raw_info
60
- @raw_info ||= access_token.get('v1/me').parsed
60
+ @raw_info ||= access_token.get("v1/me").parsed
61
61
  end
62
62
 
63
63
  def image_url
64
- raw_info.fetch('images', []).first&.fetch('url', nil)
64
+ raw_info.fetch("images", []).first&.fetch("url", nil)
65
65
  end
66
66
 
67
67
  def authorize_params
@@ -71,18 +71,18 @@ module OmniAuth
71
71
  end
72
72
 
73
73
  def request_phase
74
- options[:authorize_params][:show_dialog] = request.params['show_dialog'] if request.params.key?('show_dialog')
74
+ options[:authorize_params][:show_dialog] = request.params["show_dialog"] if request.params.key?("show_dialog")
75
75
  super
76
76
  end
77
77
 
78
78
  def callback_url
79
- return '' if @authorization_code_from_signed_request
79
+ return "" if @authorization_code_from_signed_request
80
80
 
81
81
  options[:callback_url] || super
82
82
  end
83
83
 
84
84
  def query_string
85
- return '' if request.params['code']
85
+ return "" if request.params["code"]
86
86
 
87
87
  super
88
88
  end
@@ -91,7 +91,7 @@ module OmniAuth
91
91
 
92
92
  def token_scope
93
93
  token_params = access_token.respond_to?(:params) ? access_token.params : {}
94
- token_params['scope'] || (access_token['scope'] if access_token.respond_to?(:[]))
94
+ token_params["scope"] || (access_token["scope"] if access_token.respond_to?(:[]))
95
95
  end
96
96
 
97
97
  def force_approval_requested?
@@ -102,7 +102,7 @@ module OmniAuth
102
102
  end
103
103
 
104
104
  def flash_force_approval?(key)
105
- flashes = session.dig(:flash, 'flashes') || session.dig('flash', 'flashes')
105
+ flashes = session.dig(:flash, "flashes") || session.dig("flash", "flashes")
106
106
  !!flashes&.[](key)
107
107
  end
108
108
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'omniauth/spotify/version'
3
+ require "omniauth/spotify/version"
4
4
 
5
5
  # Backward compatibility for historical constant usage.
6
6
  module Omniauth
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'omniauth/spotify'
3
+ require "omniauth/spotify"
@@ -1,34 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'omniauth/spotify/version'
5
+ require "omniauth/spotify/version"
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = 'omniauth-spotify'
8
+ spec.name = "omniauth-spotify"
9
9
  spec.version = OmniAuth::Spotify::VERSION
10
- spec.authors = ['Claudio Poli']
11
- spec.email = ['masterkain@gmail.com']
10
+ spec.authors = ["Claudio Poli"]
11
+ spec.email = ["masterkain@gmail.com"]
12
12
 
13
- spec.summary = 'OmniAuth strategy for Spotify OAuth2 authentication.'
14
- spec.description = 'OAuth2 strategy for OmniAuth that authenticates users with Spotify and exposes account metadata.'
15
- spec.homepage = 'https://github.com/icoretech/omniauth-spotify'
16
- spec.license = 'MIT'
17
- spec.required_ruby_version = '>= 3.2'
13
+ spec.summary = "OmniAuth strategy for Spotify OAuth2 authentication."
14
+ spec.description = "OAuth2 strategy for OmniAuth that authenticates users with Spotify and exposes account metadata."
15
+ spec.homepage = "https://github.com/icoretech/omniauth-spotify"
16
+ spec.license = "MIT"
17
+ spec.required_ruby_version = ">= 3.2"
18
18
 
19
- spec.metadata['source_code_uri'] = 'https://github.com/icoretech/omniauth-spotify'
20
- spec.metadata['bug_tracker_uri'] = 'https://github.com/icoretech/omniauth-spotify/issues'
21
- spec.metadata['changelog_uri'] = 'https://github.com/icoretech/omniauth-spotify/releases'
22
- spec.metadata['rubygems_mfa_required'] = 'true'
19
+ spec.metadata["source_code_uri"] = "https://github.com/icoretech/omniauth-spotify"
20
+ spec.metadata["bug_tracker_uri"] = "https://github.com/icoretech/omniauth-spotify/issues"
21
+ spec.metadata["changelog_uri"] = "https://github.com/icoretech/omniauth-spotify/releases"
22
+ spec.metadata["rubygems_mfa_required"] = "true"
23
23
 
24
24
  spec.files = Dir[
25
- 'lib/**/*.rb',
26
- 'README*',
27
- 'LICENSE*',
28
- '*.gemspec'
25
+ "lib/**/*.rb",
26
+ "README*",
27
+ "LICENSE*",
28
+ "*.gemspec"
29
29
  ]
30
- spec.require_paths = ['lib']
30
+ spec.require_paths = ["lib"]
31
31
 
32
- spec.add_dependency 'cgi', '>= 0.3.6'
33
- spec.add_dependency 'omniauth-oauth2', '>= 1.8', '< 1.9'
32
+ spec.add_dependency "cgi", ">= 0.3.6"
33
+ spec.add_dependency "omniauth-oauth2", ">= 1.8", "< 2.0"
34
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-spotify
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Poli
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '1.8'
33
33
  - - "<"
34
34
  - !ruby/object:Gem::Version
35
- version: '1.9'
35
+ version: '2.0'
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  version: '1.8'
43
43
  - - "<"
44
44
  - !ruby/object:Gem::Version
45
- version: '1.9'
45
+ version: '2.0'
46
46
  description: OAuth2 strategy for OmniAuth that authenticates users with Spotify and
47
47
  exposes account metadata.
48
48
  email: