omniauth-apple 0.0.1 → 1.0.2

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: d7998a38a969afb6c44b52111e0ce267a2f64e39c8e1059c7a3b2d4804c2ac5c
4
- data.tar.gz: e151d17ba689527597adf1a7ce5c152c005e3dd3c51865dd0b297aeffeb56e5b
3
+ metadata.gz: a5e32b1f9b3dfe8859855b86ffdb6da18d238c0f065d2aa83fd8494ae49a3dc5
4
+ data.tar.gz: bab7b98074c2a989120b1a7d3188a9ba85037c55956efc5e2e462373ed9d0d4f
5
5
  SHA512:
6
- metadata.gz: ea94526792b55a24852ea3e2a637a44f9565c59399707dcef0079358f03e71311f90d274f2390f18b80593c113ad5dd9adb16a0c34d9ac16fb9a60e6bb0b09e2
7
- data.tar.gz: 152441ec7c484bf1ee451113e65e94f3d8427e18418a75c2013cedd61ed22ffb9043f52246b73d141c562d0774f63db1bafe2f04bc0a9822bfebaae892ce1463
6
+ metadata.gz: bce3e4e1a4feb3df68f3d2d5361a56e6977dfe765068b2bee6cef743a41f59212d1b533a1cdefbeb1eaebf8a7cf832dd0f53dbd080f4efa1311bd30942b7ea86
7
+ data.tar.gz: c67ff848f44f6061c6f319db5a708e0e407977446252bea63af9e94799df2ce140c93dd7a5be5c1afbbdf3fdcdeafaeb7650cad4de199749d8edb436f21896e8
@@ -0,0 +1,26 @@
1
+ name: RSpec
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby: ['2.5', '2.6', '2.7']
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby ${{ matrix.ruby }}
19
+ uses: actions/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ - name: Build and test with Rake on Ruby ${{ matrix.ruby }}
23
+ run: |
24
+ gem install bundler
25
+ bundle install --jobs 4 --retry 3
26
+ bundle exec rake spec
data/.gitignore CHANGED
@@ -42,9 +42,10 @@ build-iPhoneSimulator/
42
42
 
43
43
  # for a library or gem, you might want to ignore these files since the code is
44
44
  # intended to run in multiple environments; otherwise, check them in:
45
- # Gemfile.lock
46
- # .ruby-version
45
+ Gemfile.lock
46
+ .ruby-version
47
47
  # .ruby-gemset
48
48
 
49
49
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
50
  .rvmrc
51
+ .idea
data/CHANGELOG.md ADDED
@@ -0,0 +1,50 @@
1
+ ## [Unreleased]
2
+
3
+ ## [1.0.2] - 2021-05-19
4
+
5
+ ### Fixed
6
+
7
+ - [#59](https://github.com/nhosoya/omniauth-apple/pull/59) Provide User-Agent when fetching JWKs
8
+
9
+
10
+ ## [1.0.1] - 2020-12-03
11
+
12
+ ### Security
13
+
14
+ - Use only verified email address to prevent fake email address
15
+
16
+ ## [1.0.0] - 2020-06-26
17
+
18
+ ### Added
19
+
20
+ - [#26](https://github.com/nhosoya/omniauth-apple/pull/26) Support ID Token verification
21
+ - [#40](https://github.com/nhosoya/omniauth-apple/pull/40) Add rspec test cases
22
+ - [#42](https://github.com/nhosoya/omniauth-apple/pull/42) [#43](https://github.com/nhosoya/omniauth-apple/pull/43) Setup CI
23
+
24
+
25
+ ### Fixed
26
+
27
+ - [#31](https://github.com/nhosoya/omniauth-apple/pull/31) Stop relying on ActiveSupport
28
+ - [#37](https://github.com/nhosoya/omniauth-apple/pull/37) Fix nonce validation
29
+ - [#41](https://github.com/nhosoya/omniauth-apple/pull/41) Fix where the RoR extension is used
30
+ - [#46](https://github.com/nhosoya/omniauth-apple/pull/46) Fix naming of Omniauth module to OmniAuth
31
+ - [#48](https://github.com/nhosoya/omniauth-apple/pull/48) Remove .rakeTasks
32
+
33
+
34
+ ### Changed
35
+
36
+ - [#27](https://github.com/nhosoya/omniauth-apple/pull/27) Update development dependency
37
+ - [#28](https://github.com/nhosoya/omniauth-apple/pull/28) Update README.md
38
+ - [#38](https://github.com/nhosoya/omniauth-apple/pull/38) Refine AuthHash
39
+ - [#39](https://github.com/nhosoya/omniauth-apple/pull/39) Set the default scope to 'email name'
40
+
41
+ ## [0.0.3] - 2020-05-15
42
+
43
+ ## [0.0.2] - 2020-01-16
44
+
45
+ ## [0.0.1] - 2019-06-07
46
+
47
+ [Unreleased]: https://github.com/nhosoya/omniauth-apple/compare/v1.0.2...master
48
+ [1.0.0]: https://github.com/nhosoya/omniauth-apple/compare/v0.0.3...v1.0.0
49
+ [1.0.1]: https://github.com/nhosoya/omniauth-apple/compare/v1.0.0...v1.0.1
50
+ [1.0.2]: https://github.com/nhosoya/omniauth-apple/compare/v1.0.1...v1.0.2
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ ![build](https://github.com/nhosoya/omniauth-apple/workflows/RSpec/badge.svg?branch=master&event=push)
2
+
1
3
  # OmniAuth::Apple
2
4
 
3
5
  OmniAuth strategy for [Sign In with Apple](https://developer.apple.com/sign-in-with-apple/).
@@ -7,7 +9,7 @@ OmniAuth strategy for [Sign In with Apple](https://developer.apple.com/sign-in-w
7
9
  Add this line to your application's Gemfile:
8
10
 
9
11
  ```ruby
10
- gem 'omniauth-apple' github: 'nhosoya/omniauth-apple', branch: master
12
+ gem 'omniauth-apple'
11
13
  ```
12
14
 
13
15
  And then execute:
@@ -22,9 +24,12 @@ Or install it yourself as:
22
24
 
23
25
  ```ruby
24
26
  Rails.application.config.middleware.use OmniAuth::Builder do
25
- provider :apple, ENV['CLIENT_ID'], ENV['TEAM_ID'], ENV['KEY_ID'], ENV['PRIVATE_KEY'],
27
+ provider :apple, ENV['CLIENT_ID'], '',
26
28
  {
27
29
  scope: 'email name',
30
+ team_id: ENV['TEAM_ID'],
31
+ key_id: ENV['KEY_ID'],
32
+ pem: ENV['PRIVATE_KEY']
28
33
  }
29
34
  end
30
35
  ```
data/Rakefile CHANGED
@@ -1,2 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
2
6
  task :default => :spec
@@ -1,4 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'omniauth-apple/version'
4
- require 'omniauth/strategies/apple'
3
+ require 'omniauth/apple'
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'omniauth/apple/version'
4
+ require 'omniauth/strategies/apple'
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module Apple
3
+ VERSION = "1.0.2"
4
+ end
5
+ end
@@ -1,51 +1,140 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'omniauth-oauth2'
4
+ require 'net/https'
2
5
 
3
6
  module OmniAuth
4
7
  module Strategies
5
8
  class Apple < OmniAuth::Strategies::OAuth2
6
-
7
- attr_reader :id_token
8
- args %i[client_id team_id key_id pem]
9
-
10
9
  option :name, 'apple'
11
- option :client_options, {
12
- site: 'https://appleid.apple.com',
13
- authorize_url: '/auth/authorize',
14
- token_url: '/auth/token',
15
- }
16
10
 
17
- uid { id_token['sub'] }
11
+ option :client_options,
12
+ site: 'https://appleid.apple.com',
13
+ authorize_url: '/auth/authorize',
14
+ token_url: '/auth/token'
15
+ option :authorize_params,
16
+ response_mode: 'form_post',
17
+ scope: 'email name'
18
+ option :authorized_client_ids, []
19
+
20
+ uid { id_info['sub'] }
18
21
 
19
22
  info do
20
- { sub: id_token['sub'] }
23
+ prune!(
24
+ sub: id_info['sub'],
25
+ email: email,
26
+ first_name: first_name,
27
+ last_name: last_name,
28
+ name: (first_name || last_name) ? [first_name, last_name].join(' ') : email,
29
+ )
30
+ end
31
+
32
+ extra do
33
+ id_token = request.params['id_token'] || access_token&.params&.dig('id_token')
34
+ prune!(raw_info: {id_info: id_info, user_info: user_info, id_token: id_token})
21
35
  end
22
36
 
23
37
  def client
24
- ::OAuth2::Client.new(options.client_id, client_secret, deep_symbolize(options.client_options))
38
+ ::OAuth2::Client.new(client_id, client_secret, deep_symbolize(options.client_options))
25
39
  end
26
40
 
27
- def callback_url
28
- full_host + script_name + callback_path
41
+ def authorize_params
42
+ super.merge(nonce: new_nonce)
29
43
  end
30
44
 
31
- def build_access_token
32
- _access_token = super
33
- @id_token = ::JSON::JWT.decode(_access_token.params['id_token'], :skip_verification)
34
- _access_token
45
+ def callback_url
46
+ options[:redirect_uri] || (full_host + script_name + callback_path)
35
47
  end
36
48
 
37
49
  private
38
50
 
51
+ def new_nonce
52
+ session['omniauth.nonce'] = SecureRandom.urlsafe_base64(16)
53
+ end
54
+
55
+ def stored_nonce
56
+ session.delete('omniauth.nonce')
57
+ end
58
+
59
+ def id_info
60
+ @id_info ||= if request.params&.key?('id_token') || access_token&.params&.key?('id_token')
61
+ id_token = request.params['id_token'] || access_token.params['id_token']
62
+ jwt_options = {
63
+ verify_iss: true,
64
+ iss: 'https://appleid.apple.com',
65
+ verify_iat: true,
66
+ verify_aud: true,
67
+ aud: [options.client_id].concat(options.authorized_client_ids),
68
+ algorithms: ['RS256'],
69
+ jwks: fetch_jwks
70
+ }
71
+ payload, _header = ::JWT.decode(id_token, nil, true, jwt_options)
72
+ verify_nonce!(payload)
73
+ payload
74
+ end
75
+ end
76
+
77
+ def fetch_jwks
78
+ http = Net::HTTP.new('appleid.apple.com', 443)
79
+ http.use_ssl = true
80
+ request = Net::HTTP::Get.new('/auth/keys', 'User-Agent' => 'ruby/omniauth-apple')
81
+ response = http.request(request)
82
+ JSON.parse(response.body, symbolize_names: true)
83
+ end
84
+
85
+ def verify_nonce!(payload)
86
+ return unless payload['nonce_supported']
87
+
88
+ return if payload['nonce'] && payload['nonce'] == stored_nonce
89
+
90
+ fail!(:nonce_mismatch, CallbackError.new(:nonce_mismatch, 'nonce mismatch'))
91
+ end
92
+
93
+ def client_id
94
+ @client_id ||= if id_info.nil?
95
+ options.client_id
96
+ else
97
+ id_info['aud'] if options.authorized_client_ids.include? id_info['aud']
98
+ end
99
+ end
100
+
101
+ def user_info
102
+ user = request.params['user']
103
+ return {} if user.nil?
104
+
105
+ @user_info ||= JSON.parse(user)
106
+ end
107
+
108
+ def email
109
+ id_info['email']
110
+ end
111
+
112
+ def first_name
113
+ user_info.dig('name', 'firstName')
114
+ end
115
+
116
+ def last_name
117
+ user_info.dig('name', 'lastName')
118
+ end
119
+
120
+ def prune!(hash)
121
+ hash.delete_if do |_, v|
122
+ prune!(v) if v.is_a?(Hash)
123
+ v.nil? || (v.respond_to?(:empty?) && v.empty?)
124
+ end
125
+ end
126
+
39
127
  def client_secret
40
- jwt = ::JSON::JWT.new(
128
+ payload = {
41
129
  iss: options.team_id,
42
130
  aud: 'https://appleid.apple.com',
43
- sub: options.client_id,
44
- iat: Time.current,
45
- exp: 1.minutes.after
46
- )
47
- jwt.kid = options.key_id
48
- jwt.sign(private_key).to_s
131
+ sub: client_id,
132
+ iat: Time.now.to_i,
133
+ exp: Time.now.to_i + 60
134
+ }
135
+ headers = { kid: options.key_id }
136
+
137
+ ::JWT.encode(payload, private_key, 'ES256', headers)
49
138
  end
50
139
 
51
140
  def private_key
@@ -1,13 +1,13 @@
1
1
 
2
2
  lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "omniauth-apple/version"
4
+ require "omniauth/apple/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "omniauth-apple"
8
- spec.version = Omniauth::Apple::VERSION
9
- spec.authors = ["nhosoya"]
10
- spec.email = ["hnhnnhnh@gmail.com"]
8
+ spec.version = OmniAuth::Apple::VERSION
9
+ spec.authors = ["nhosoya", "Fabian Jäger"]
10
+ spec.email = ["hnhnnhnh@gmail.com", "fabian@mailbutler.io"]
11
11
 
12
12
  spec.summary = %q{OmniAuth strategy for Sign In with Apple}
13
13
  spec.description = %q{OmniAuth strategy for Sign In with Apple}
@@ -37,6 +37,10 @@ Gem::Specification.new do |spec|
37
37
  spec.require_paths = ["lib"]
38
38
 
39
39
  spec.add_dependency 'omniauth-oauth2'
40
+ spec.add_dependency 'jwt'
40
41
  spec.add_development_dependency "bundler", "~> 2.0"
41
- spec.add_development_dependency "rake", "~> 10.0"
42
+ spec.add_development_dependency "rake", "~> 13.0"
43
+ spec.add_development_dependency "rspec", "~> 3.9"
44
+ spec.add_development_dependency "webmock", "~> 3.8"
45
+ spec.add_development_dependency 'simplecov', "~> 0.18"
42
46
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-apple
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - nhosoya
8
- autorequire:
8
+ - Fabian Jäger
9
+ autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2019-06-07 00:00:00.000000000 Z
12
+ date: 2021-05-19 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: omniauth-oauth2
@@ -24,6 +25,20 @@ dependencies:
24
25
  - - ">="
25
26
  - !ruby/object:Gem::Version
26
27
  version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: jwt
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
27
42
  - !ruby/object:Gem::Dependency
28
43
  name: bundler
29
44
  requirement: !ruby/object:Gem::Requirement
@@ -44,22 +59,67 @@ dependencies:
44
59
  requirements:
45
60
  - - "~>"
46
61
  - !ruby/object:Gem::Version
47
- version: '10.0'
62
+ version: '13.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '13.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '3.9'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '3.9'
84
+ - !ruby/object:Gem::Dependency
85
+ name: webmock
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '3.8'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '3.8'
98
+ - !ruby/object:Gem::Dependency
99
+ name: simplecov
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.18'
48
105
  type: :development
49
106
  prerelease: false
50
107
  version_requirements: !ruby/object:Gem::Requirement
51
108
  requirements:
52
109
  - - "~>"
53
110
  - !ruby/object:Gem::Version
54
- version: '10.0'
111
+ version: '0.18'
55
112
  description: OmniAuth strategy for Sign In with Apple
56
113
  email:
57
114
  - hnhnnhnh@gmail.com
115
+ - fabian@mailbutler.io
58
116
  executables: []
59
117
  extensions: []
60
118
  extra_rdoc_files: []
61
119
  files:
120
+ - ".github/workflows/rspec.yml"
62
121
  - ".gitignore"
122
+ - CHANGELOG.md
63
123
  - Gemfile
64
124
  - LICENSE
65
125
  - README.md
@@ -67,14 +127,15 @@ files:
67
127
  - bin/console
68
128
  - bin/setup
69
129
  - lib/omniauth-apple.rb
70
- - lib/omniauth-apple/version.rb
130
+ - lib/omniauth/apple.rb
131
+ - lib/omniauth/apple/version.rb
71
132
  - lib/omniauth/strategies/apple.rb
72
133
  - omniauth-apple.gemspec
73
134
  homepage: https://github.com/nhosoya/omniauth-apple
74
135
  licenses:
75
136
  - MIT
76
137
  metadata: {}
77
- post_install_message:
138
+ post_install_message:
78
139
  rdoc_options: []
79
140
  require_paths:
80
141
  - lib
@@ -89,8 +150,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
150
  - !ruby/object:Gem::Version
90
151
  version: '0'
91
152
  requirements: []
92
- rubygems_version: 3.0.3
93
- signing_key:
153
+ rubygems_version: 3.2.3
154
+ signing_key:
94
155
  specification_version: 4
95
156
  summary: OmniAuth strategy for Sign In with Apple
96
157
  test_files: []
@@ -1,5 +0,0 @@
1
- module Omniauth
2
- module Apple
3
- VERSION = "0.0.1"
4
- end
5
- end