apple_auth 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2325fb23f530c7f590aa0b2fa733af052923478e81a6ccc82c4d86963514a7da
4
- data.tar.gz: 9551b96c8c9a1feebaa2ffc6f64fe9f66e6a36787d63805bff81c315a43897d4
3
+ metadata.gz: 81230a2cf77dadea66d5149d533545217931f531e6d1855d7f12d1dcf9dd8957
4
+ data.tar.gz: 8048602dd34d1b32b1ffb9cb6888b73e4ec912d94e41dc543137fc03a880c4af
5
5
  SHA512:
6
- metadata.gz: aa21c140b1c060c38b6fa56f76339b3572f8d4e1d4deca9c761e1a58467950d89244937fa185d22872595ea49215200603efc06a50761712f82f7beac79574a6
7
- data.tar.gz: bc1edcfca29b8176ecfec0fdf74c50065e1d1c313974a8bb8a441fa3300037c495b1ae013a71145e9d9def053de9ec002134289209250ad288b95baa87969dd9
6
+ metadata.gz: fd52622624be456077bc356bef447461d4d4638be8a38c29b0cc21f4a9c1e67cd494be8766aaf736918981067cd9c19eafcc5c248dea0d3b0b4e97b968c9ed0c
7
+ data.tar.gz: a82e5a11a1f4854b7a1e6000a7cfc15b3edc1c3f509f90a83b297388e571ad47acc6151817521fb8e3744c31b4feb4d07934c69bbae3cdb7755a14ecf92eb669
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: "[Bug] "
5
+ labels: bug
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## Bug report:
11
+ * **Expected Behavior**:
12
+ * **Actual Behavior**:
13
+ * **Steps to Reproduce**:
14
+ 1.
15
+ 2.
16
+ 3.
17
+
18
+ * **Version of the repo**:
19
+ * **Ruby and Rails Version**:
20
+ * **Rails Stacktrace**: this can be found in the `log/development.log` or `log/test.log`, if this is applicable.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: '[FEATURE]'
5
+ labels: enhancement
6
+ assignees: ''
7
+
8
+ ---
9
+ <!-- Please note by far the quickest way to get a new feature is to file a Pull Request.
10
+ We will consider your request but it may be closed if it's something we're not actively planning to work on. -->
11
+
12
+ **Is your feature request related to a problem? Please describe.**
13
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
14
+
15
+ **Describe the solution you'd like**
16
+ A clear and concise description of what you want to happen.
17
+
18
+ **Describe alternatives you've considered**
19
+ A clear and concise description of any alternative solutions or features you've considered.
20
+
21
+ **Additional context**
22
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,12 @@
1
+ ### Summary
2
+
3
+ <!-- Provide a general description of the code changes in your pull
4
+ request... were there any bugs you had fixed? If so, mention them. If
5
+ these bugs have open GitHub issues, be sure to tag them here as well,
6
+ to keep the conversation linked together. -->
7
+
8
+ ### Other Information
9
+
10
+ <!-- If there's anything else that's important and relevant to your pull
11
+ request, mention that information here.
12
+ Thanks for contributing to this project! -->
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,41 @@
1
+ ## Contributing ##
2
+
3
+ You can contribute to this repo if you have an issue, found a bug or think there's some functionality required that would add value to the gem. To do so, please check if there's not already an [issue](https://github.com/rootstrap/apple_auth/issues) for that, if you find there's not, create a new one with as much detail as possible.
4
+
5
+ If you want to contribute with code as well, please follow the next steps:
6
+
7
+ 1. Read, understand and agree to our [code of conduct](https://github.com/rootstrap/apple_auth/blob/master/CODE_OF_CONDUCT.md)
8
+ 2. [Fork the repo](https://help.github.com/articles/about-forks/)
9
+ 3. Clone the project into your machine:
10
+ `$ git clone git@github.com:rootstrap/apple_auth.git`
11
+ 4. Access the repo:
12
+ `$ cd apple_auth`
13
+ 5. Create your feature/bugfix branch:
14
+ `$ git checkout -b your_new_feature`
15
+ or
16
+ `$ git checkout -b fix/your_fix` in case of a bug fix
17
+ (if your PR is to address an existing issue, it would be good to name the branch after the issue, for example: if you are trying to solve issue 182, then a good idea for the branch name would be `182_your_new_feature`)
18
+ 6. Write tests for your changes (feature/bug)
19
+ 7. Code your (feature/bugfix)
20
+ 8. Run the code analysis tool by doing:
21
+ `$ rake code_analysis`
22
+ 9. Run the tests:
23
+ `$ bundle exec rspec`
24
+ All tests must pass. If all tests (both code analysis and rspec) do pass, then you are ready to go to the next step:
25
+ 10. Commit your changes:
26
+ `$ git commit -m 'Your feature or bugfix title'`
27
+ 11. Push to the branch `$ git push origin your_new_feature`
28
+ 12. Create a new [pull request](https://help.github.com/articles/creating-a-pull-request/)
29
+
30
+ Some helpful guides that will help you know how we work:
31
+ 1. [Code review](https://github.com/rootstrap/tech-guides/tree/master/code-review)
32
+ 2. [GIT workflow](https://github.com/rootstrap/tech-guides/tree/master/git)
33
+ 3. [Ruby style guide](https://github.com/rootstrap/tech-guides/tree/master/ruby)
34
+ 4. [Rails style guide](https://github.com/rootstrap/tech-guides/blob/master/ruby/rails.md)
35
+ 5. [RSpec style guide](https://github.com/rootstrap/tech-guides/blob/master/ruby/rspec/README.md)
36
+
37
+ For more information or guides like the ones mentioned above, please check our [tech guides](https://github.com/rootstrap/tech-guides). Keep in mind that the more you know about these guides, the easier it will be for your code to get approved and merged.
38
+
39
+ Note: You can push as many commits as you want when working on a pull request, we just ask that they are descriptive and tell a story. Try to open a pull request with just one commit but if you think you need to divide what you did into more commits to convey what you are trying to do go for it.
40
+
41
+ Thank you very much for your time and for considering helping in this project.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AppleAuth
2
2
 
3
- [![CI](https://api.travis-ci.org/rootstrap/apple_auth.svg?branch=master)](https://travis-ci.org/github/rootstrap/apple_auth)
3
+ [![CI](https://api.travis-ci.com/rootstrap/apple_auth.svg?branch=master)](https://travis-ci.com/github/rootstrap/apple_auth)
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/78453501221a76e3806e/maintainability)](https://codeclimate.com/github/rootstrap/apple_sign_in/maintainability)
5
5
  [![Test Coverage](https://api.codeclimate.com/v1/badges/78453501221a76e3806e/test_coverage)](https://codeclimate.com/github/rootstrap/apple_sign_in/test_coverage)
6
6
 
@@ -33,7 +33,7 @@ AppleAuth.configure do |config|
33
33
  # config.apple_private_key = <Your private key provided by Apple>
34
34
  # config.apple_key_id = <Your kid provided by Apple>
35
35
  # config.apple_team_id = <Your team id provided by Apple>
36
- # config.redirect_uri = <Your app redicrect url>
36
+ # config.redirect_uri = <Your app redirect url>
37
37
  end
38
38
  ```
39
39
  Set your different credentials in the file by uncommenting the lines and adding your keys.
@@ -56,13 +56,13 @@ end
56
56
 
57
57
  We strongly recommend to use environment variables for these values.
58
58
 
59
- Apple sign-in workflow:
59
+ ### Apple sign-in workflow:
60
60
 
61
61
  ![alt text](https://docs-assets.developer.apple.com/published/360d59b776/rendered2x-1592224731.png)
62
62
 
63
63
  For more information, check the [Apple oficial documentation](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api).
64
64
 
65
- Validate JWT token and get user information:
65
+ ### Validate JWT token and get user information:
66
66
 
67
67
  ```ruby
68
68
  # with a valid JWT
@@ -79,7 +79,7 @@ AppleAuth::UserIdentity.new(user_id, invalid_jwt_token).validate!
79
79
  >> AppleAuth::Conditions::JWTValidationError
80
80
  ```
81
81
 
82
- Verify user identity and get access and refresh tokens:
82
+ ### Verify user identity and get access and refresh tokens:
83
83
 
84
84
  ```ruby
85
85
  code = 'cfb77c21ecd444390a2c214cd33decdfb.0.mr...'
@@ -87,14 +87,59 @@ AppleAuth::Token.new(code).authenticate!
87
87
  >> { access_token: "a7058d...", expires_at: 1595894672, refresh_token: "r8f1ce..." }
88
88
  ```
89
89
 
90
+ ### Handle server to server notifications
91
+
92
+ from the request parameter :payload
93
+
94
+ ```ruby
95
+ # with a valid JWT
96
+ params[:payload] = "eyJraWQiOiJZ......"
97
+ AppleAuth::ServerIdentity.new(params[:payload]).validate!
98
+ >> {iss: "https://appleid.apple.com", exp: 1632224024, iat: 1632137624, jti: "yctpp1ZHaGCzaNB9PWB4DA",...}
99
+
100
+ # with an invalid JWT
101
+ params[:payload] = "asdasdasdasd......"
102
+ AppleAuth::ServerIdentity.new(params[:payload]).validate!
103
+ >> JWT::VerificationError: Signature verification raised
104
+ ```
105
+
106
+ Implementation in a controller would look like this:
107
+
108
+ ```ruby
109
+ class Hooks::AuthController < ApplicationController
110
+
111
+ skip_before_action :verify_authenticity_token
112
+
113
+ # https://developer.apple.com/documentation/sign_in_with_apple/processing_changes_for_sign_in_with_apple_accounts
114
+ # NOTE: The Apple documentation states the events attribute as an array but is in fact a stringified json object
115
+ def apple
116
+ # will raise an error when the signature is invalid
117
+ payload = AppleAuth::ServerIdentity.new(params[:payload]).validate!
118
+ event = JSON.parse(payload[:events]).symbolize_keys
119
+ uid = event["sub"]
120
+ user = User.find_by!(provider: 'apple', uid: uid)
121
+
122
+ case event[:type]
123
+ when "email-enabled", "email-disabled"
124
+ # Here we should update the user with the relay state
125
+ when "consent-revoked", "account-delete"
126
+ user.destroy!
127
+ else
128
+ throw event
129
+ end
130
+ render plain: "200 OK", status: :ok
131
+ end
132
+ end
133
+ ```
134
+
90
135
  ## Using with Devise
91
136
 
92
137
  If you are using devise_token_auth gem, run this generator.
93
138
 
94
- $ rails g apple_sign_in:appple_auth_controller [scope]
139
+ $ rails g apple_sign_in:apple_auth_controller [scope]
95
140
 
96
141
  In the scope you need to write your path from controllers to your existent devise controllers.
97
- An example `$ rails g apple_auth:appple_auth_controller api/v1/`
142
+ An example `$ rails g apple_auth:apple_auth_controller api/v1/`
98
143
  This will generate a new controller: `controllers/api/v1/apple_auth_controller.rb`.
99
144
 
100
145
  You should configure the route, you can wrap it in the devise_scope block like:
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AppleAuth
4
4
  module Base
5
- VERSION = '1.0.0'
5
+ VERSION = '1.1.0'
6
6
  end
7
7
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: false
2
+
3
+ module AppleAuth
4
+ class JWTDecoder
5
+ APPLE_KEY_URL = 'https://appleid.apple.com/auth/keys'.freeze
6
+
7
+ attr_reader :jwt
8
+
9
+ def initialize(jwt)
10
+ @jwt = jwt
11
+ end
12
+
13
+ def call
14
+ decoded.first
15
+ end
16
+
17
+ private
18
+
19
+ def decoded
20
+ key_hash = apple_key_hash(jwt)
21
+ apple_jwk = JWT::JWK.import(key_hash)
22
+ JWT.decode(jwt, apple_jwk.public_key, true, algorithm: key_hash['alg'])
23
+ end
24
+
25
+ def apple_key_hash(jwt)
26
+ response = Net::HTTP.get(URI.parse(APPLE_KEY_URL))
27
+ certificate = JSON.parse(response)
28
+ matching_key = certificate['keys'].select { |key| key['kid'] == jwt_kid(jwt) }
29
+ ActiveSupport::HashWithIndifferentAccess.new(matching_key.first)
30
+ end
31
+
32
+ def jwt_kid(jwt)
33
+ header = JSON.parse(Base64.decode64(jwt.split('.').first))
34
+ header['kid']
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: false
2
+
3
+ module AppleAuth
4
+ class JWTServerConditions
5
+ include Conditions
6
+
7
+ CONDITIONS = [
8
+ AudCondition,
9
+ IatCondition,
10
+ IssCondition
11
+ ].freeze
12
+
13
+ attr_reader :decoded_jwt
14
+
15
+ def initialize(decoded_jwt)
16
+ @decoded_jwt = decoded_jwt
17
+ end
18
+
19
+ def validate!
20
+ JWT::ClaimsValidator.new(decoded_jwt).validate! && jwt_conditions_validate!
21
+ rescue JWT::InvalidPayload => e
22
+ raise JWTValidationError, e.message
23
+ end
24
+
25
+ private
26
+
27
+ def jwt_conditions_validate!
28
+ conditions_results = CONDITIONS.map do |condition|
29
+ condition.new(decoded_jwt).validate!
30
+ end
31
+ conditions_results.all? { |value| value == true }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AppleAuth
4
+ class ServerIdentity
5
+ attr_reader :jwt
6
+
7
+ def initialize(jwt)
8
+ @jwt = jwt
9
+ end
10
+
11
+ def validate!
12
+ token_data = JWTDecoder.new(jwt).call
13
+
14
+ JWTServerConditions.new(token_data).validate!
15
+
16
+ token_data.symbolize_keys
17
+ end
18
+ end
19
+ end
@@ -2,8 +2,6 @@
2
2
 
3
3
  module AppleAuth
4
4
  class UserIdentity
5
- APPLE_KEY_URL = 'https://appleid.apple.com/auth/keys'
6
-
7
5
  attr_reader :user_identity, :jwt
8
6
 
9
7
  def initialize(user_identity, jwt)
@@ -12,31 +10,11 @@ module AppleAuth
12
10
  end
13
11
 
14
12
  def validate!
15
- token_data = decoded_jwt
13
+ token_data = JWTDecoder.new(jwt).call
16
14
 
17
15
  JWTConditions.new(user_identity, token_data).validate!
18
16
 
19
17
  token_data.symbolize_keys
20
18
  end
21
-
22
- private
23
-
24
- def decoded_jwt
25
- key_hash = apple_key_hash
26
- apple_jwk = JWT::JWK.import(key_hash)
27
- JWT.decode(jwt, apple_jwk.public_key, true, algorithm: key_hash['alg']).first
28
- end
29
-
30
- def apple_key_hash
31
- response = Net::HTTP.get(URI.parse(APPLE_KEY_URL))
32
- certificate = JSON.parse(response)
33
- matching_key = certificate['keys'].select { |key| key['kid'] == jwt_kid }
34
- ActiveSupport::HashWithIndifferentAccess.new(matching_key.first)
35
- end
36
-
37
- def jwt_kid
38
- header = JSON.parse(Base64.decode64(jwt.split('.').first))
39
- header['kid']
40
- end
41
19
  end
42
20
  end
data/lib/apple_auth.rb CHANGED
@@ -22,7 +22,10 @@ require 'apple_auth/helpers/conditions/exp_condition'
22
22
  require 'apple_auth/helpers/conditions/iat_condition'
23
23
  require 'apple_auth/helpers/conditions/iss_condition'
24
24
  require 'apple_auth/helpers/jwt_conditions'
25
+ require 'apple_auth/helpers/jwt_decoder'
26
+ require 'apple_auth/helpers/jwt_server_conditions'
25
27
 
28
+ require 'apple_auth/server_identity'
26
29
  require 'apple_auth/user_identity'
27
30
  require 'apple_auth/token'
28
31
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apple_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Timothy Peraza, Antonieta Alvarez, Martín Morón
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-14 00:00:00.000000000 Z
11
+ date: 2024-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -178,13 +178,16 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: '3.8'
181
- description:
181
+ description:
182
182
  email:
183
183
  - timothy@rootstrap.com, antonieta.alvarez@rootstrap.com, martin.jaime@rootstrap.com
184
184
  executables: []
185
185
  extensions: []
186
186
  extra_rdoc_files: []
187
187
  files:
188
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
189
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
190
+ - ".github/pull_request_template.md"
188
191
  - ".gitignore"
189
192
  - ".reek.yml"
190
193
  - ".rspec"
@@ -192,6 +195,7 @@ files:
192
195
  - ".travis.yml"
193
196
  - CODEOWNERS
194
197
  - CODE_OF_CONDUCT.md
198
+ - CONTRIBUTING.md
195
199
  - Gemfile
196
200
  - LICENSE.txt
197
201
  - README.md
@@ -209,6 +213,9 @@ files:
209
213
  - lib/apple_auth/helpers/conditions/iss_condition.rb
210
214
  - lib/apple_auth/helpers/conditions/jwt_validation_error.rb
211
215
  - lib/apple_auth/helpers/jwt_conditions.rb
216
+ - lib/apple_auth/helpers/jwt_decoder.rb
217
+ - lib/apple_auth/helpers/jwt_server_conditions.rb
218
+ - lib/apple_auth/server_identity.rb
212
219
  - lib/apple_auth/token.rb
213
220
  - lib/apple_auth/user_identity.rb
214
221
  - lib/generators/apple_auth/apple_auth_controller/apple_auth_controller_generator.rb
@@ -222,7 +229,7 @@ metadata:
222
229
  homepage_uri: https://github.com/rootstrap/apple_auth
223
230
  source_code_uri: https://github.com/rootstrap/apple_auth
224
231
  changelog_uri: https://github.com/rootstrap/apple_auth
225
- post_install_message:
232
+ post_install_message:
226
233
  rdoc_options: []
227
234
  require_paths:
228
235
  - lib
@@ -237,8 +244,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
244
  - !ruby/object:Gem::Version
238
245
  version: '0'
239
246
  requirements: []
240
- rubygems_version: 3.0.3
241
- signing_key:
247
+ rubygems_version: 3.1.6
248
+ signing_key:
242
249
  specification_version: 4
243
250
  summary: Integration with Apple Sign In and Devise for backend. Validate and Verify
244
251
  user token.