app_store_connect_jwt 0.3.0 → 0.4.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: c71424de5f38c22a6d37033331e216d60aae61048d99ef31ecf87bcaa944604a
4
- data.tar.gz: bb19b41b06c00c459303563fca6ad9a4258313f923aebff7db594ee71f3eef4d
3
+ metadata.gz: c5cc4cc4768241760d8a0d1a6898804ee2910655af8af4920ae245369390c4e3
4
+ data.tar.gz: 9e558fc1e1efa9b6277791b9f71586bc5f463b6d91845841d7d0f3be616dbf79
5
5
  SHA512:
6
- metadata.gz: 82a3c208645dddbbec4a0dc63bf09522601e5f3aced6cc04199b8215074f6cdc78de41c833cd63413fefb62e9febad35b89ca524920529dee6c5fdb5e2e2e620
7
- data.tar.gz: 6c9a1e669a463caebdcdaeb77db2222c35ab542f2e54618bfd60ae6edfaccbd3af2c6b68366212bda334e84da02d3c7e46a81ab04ddb948f62de21dff27575d2
6
+ metadata.gz: 58ee8eb7b987a1594245cac753eb5325b9d7f0cf969cc3ce3c6d35e3b6d38e61ff4a261452e7af2b2a80b3cae226ac8b25f1633f1eea04a1d1f0e1175d8deb8d
7
+ data.tar.gz: c99f2b5e8cd149e7d0200d27165dcf834c2af9a3b125401fa6c458c8003176a190c3012e902752bcc3804496cb82cff2f60fddc58329f07b25903208982505cc
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: Publish
3
+
4
+ on:
5
+ push:
6
+ tags:
7
+ - v*
8
+
9
+ jobs:
10
+ build:
11
+ name: Build + Publish
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@master
16
+ - name: Set up Ruby 2.6
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.6.x
20
+ - name: Configure Bundler
21
+ run: |
22
+ gem install bundler
23
+ bundle install --jobs=3 --retry=3
24
+ mkdir -p $HOME/.gem
25
+ touch $HOME/.gem/credentials
26
+ chmod 0600 $HOME/.gem/credentials
27
+ printf -- "---\n:rubygems_api_key: ${RUBYGEMS_API_KEY}\n:github: Bearer ${GITHUB_PACKAGE_REPOSITORY_AUTH_TOKEN}" > $HOME/.gem/credentials
28
+ env:
29
+ RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
30
+ GITHUB_PACKAGE_REPOSITORY_AUTH_TOKEN: ${{secrets.GITHUB_PACKAGE_REPOSITORY_AUTH_TOKEN}}
31
+
32
+ - name: Build Gem
33
+ run: |
34
+ gem build *.gemspec
35
+ - name: Publish to RubyGems
36
+ run: bundle exec ./bin/publish --rubygems
37
+
38
+ - name: Publish to Github Package Repository
39
+ run: bundle exec ./bin/publish --github
@@ -0,0 +1,76 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at kyle.decot@icloud.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_store_connect_jwt (0.3.0)
5
- gli
6
- jwt
4
+ app_store_connect_jwt (0.4.0)
5
+ gli (~> 2.19)
6
+ jwt (~> 2.2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -89,13 +89,13 @@ PLATFORMS
89
89
  DEPENDENCIES
90
90
  app_store_connect_jwt!
91
91
  bundler (~> 2.0)
92
- guard-rspec
93
- pry
92
+ guard-rspec (~> 4.7)
93
+ pry (~> 0.12)
94
94
  rake (~> 10.0)
95
95
  rspec (~> 3.0)
96
- rubocop
97
- simplecov
98
- timecop
96
+ rubocop (~> 0.79)
97
+ simplecov (~> 0.17)
98
+ timecop (~> 0.9)
99
99
 
100
100
  BUNDLED WITH
101
101
  2.0.2
data/README.md CHANGED
@@ -26,33 +26,52 @@ Or install it yourself as:
26
26
 
27
27
  ### CLI
28
28
 
29
+ #### Encoding
30
+
29
31
  ```sh
30
- $ app-store-connect-jwt generate \
32
+ $ app-store-connect-jwt encode \
31
33
  --issuer-id=$APP_STORE_CONNECT_ISSUER_ID \
32
34
  --key-id=$APP_STORE_CONNECT_KEY_ID \
33
35
  --private-key-path=$APP_STORE_CONNECT_PRIVATE_KEY_PATH
34
36
  ```
35
37
 
36
- :information_desk_person: _Pro Tip: if you have the environment variables set that are listed above you can omit the flags entirely and the CLI will automatically pick up on them, thus making the command `app-store-connect-jwt generate`!_
38
+ :information_desk_person: _Pro Tip: if you have the environment variables set that are listed above you can omit the flags entirely and the CLI will automatically pick up on them, thus making the command `app-store-connect-jwt encode`!_
39
+
40
+ #### Decoding
41
+
42
+ ```sh
43
+ $ app-store-connect-jwt decode \
44
+ --token="..." \
45
+ --private-key-path=$APP_STORE_CONNECT_PRIVATE_KEY_PATH
46
+ ```
37
47
 
38
48
  #### cURL
39
49
 
40
50
  ```sh
41
- $ curl -H "Authorization: Bearer $(app-store-connect-jwt generate)" \
51
+ $ curl -H "Authorization: Bearer $(app-store-connect-jwt encode)" \
42
52
  https://api.appstoreconnect.apple.com/v1/apps
43
53
  ```
44
54
 
45
55
  ### Ruby
46
56
 
57
+ #### Encoding
58
+
47
59
  ```ruby
48
- puts AppStoreConnect::JWT.new(
60
+ AppStoreConnect::JWT.encode(
49
61
  issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
50
62
  key_id: ENV["APP_STORE_CONNECT_KEY_ID"],
51
63
  private_key_path: ENV["APP_STORE_CONNECT_PRIVATE_KEY_PATH"]
52
- ).token
64
+ )
53
65
  ```
54
66
 
55
- :information_desk_person: _Pro Tip: `#token` is aliased to `#to_s` so in this example the `.token` is superfolus!_
67
+ #### Decoding
68
+
69
+ ```ruby
70
+ AppStoreConnect::JWT.decode(
71
+ token: token,
72
+ private_key_path: ENV["APP_STORE_CONNECT_PRIVATE_KEY_PATH"]
73
+ )
74
+ ```
56
75
 
57
76
  ## Development
58
77
 
@@ -25,14 +25,14 @@ Gem::Specification.new do |spec|
25
25
  spec.require_paths = ['lib']
26
26
 
27
27
  spec.add_development_dependency 'bundler', '~> 2.0'
28
- spec.add_development_dependency 'guard-rspec'
29
- spec.add_development_dependency 'pry'
28
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
29
+ spec.add_development_dependency 'pry', '~> 0.12'
30
30
  spec.add_development_dependency 'rake', '~> 10.0'
31
31
  spec.add_development_dependency 'rspec', '~> 3.0'
32
- spec.add_development_dependency 'rubocop'
33
- spec.add_development_dependency 'simplecov'
34
- spec.add_development_dependency 'timecop'
32
+ spec.add_development_dependency 'rubocop', '~> 0.79'
33
+ spec.add_development_dependency 'simplecov', '~> 0.17'
34
+ spec.add_development_dependency 'timecop', '~> 0.9'
35
35
 
36
- spec.add_runtime_dependency 'gli'
37
- spec.add_runtime_dependency 'jwt'
36
+ spec.add_runtime_dependency 'gli', '~> 2.19'
37
+ spec.add_runtime_dependency 'jwt', '~> 2.2'
38
38
  end
data/bin/publish ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'optparse'
5
+ require 'app_store_connect/jwt/version'
6
+
7
+ OPTIONS = {
8
+ hosts: [],
9
+ version: AppStoreConnect::JWT::VERSION
10
+ }
11
+
12
+ HOSTS = {
13
+ rubygems: 'https://rubygems.org',
14
+ github: 'https://rubygems.pkg.github.com/kyledecot'
15
+ }.freeze
16
+
17
+ OptionParser.new do |parser|
18
+ HOSTS.keys.each do |key|
19
+ parser.on("--#{key}") do
20
+ OPTIONS[:hosts] << key
21
+ end
22
+ end
23
+
24
+ parser.on('--version VERSION') do |version|
25
+ OPTIONS[:version] = version
26
+ end
27
+
28
+ parser.on('--help', '-h') do
29
+ puts parser
30
+ exit(0)
31
+ end
32
+ end.parse!
33
+
34
+ OPTIONS[:hosts].each do |key|
35
+ ENV['RUBYGEMS_HOST'] = HOSTS.fetch(key)
36
+
37
+ system "gem push -k #{key} app_store_connect_jwt-#{OPTIONS[:version]}.gem"
38
+ end
@@ -8,55 +8,25 @@ module AppStoreConnect
8
8
  AUDIENCE = 'appstoreconnect-v1'
9
9
  ALGORITHM = 'ES256'
10
10
 
11
- # App Store Connect API Issuer ID
12
- # @return [String]
13
- attr_reader :issuer_id
14
-
15
- # App Store Connect API Key ID
11
+ # @param issuer_id [String] App Store Connect API Issuer ID
12
+ # @param key_id [String] App Store Connect API Key ID
13
+ # @param private_key_path [String] Path to App Store Connect API Private Key (.p8)
16
14
  # @return [String]
17
- attr_reader :key_id
15
+ def self.encode(issuer_id:, key_id:, private_key_path:)
16
+ payload = Utils.payload(issuer_id, AUDIENCE)
17
+ header_fields = Utils.header_fields(key_id)
18
+ private_key = Utils.private_key(private_key_path)
18
19
 
19
- # App Store Connect API Private Key
20
- # @return [OpenSSL::PKey::EC]
21
- attr_reader :private_key
20
+ Utils.encode(payload, private_key, ALGORITHM, header_fields)
21
+ end
22
22
 
23
23
  # @param token [String]
24
24
  # @param private_key_path [String] Path to App Store Connect API Private Key (.p8)
25
25
  # @return [Array<Hash>]
26
26
  def self.decode(token:, private_key_path:)
27
- private_key = Utils.private_key(path: private_key_path)
27
+ private_key = Utils.private_key(private_key_path)
28
28
 
29
29
  Utils.decode(token, private_key, ALGORITHM)
30
30
  end
31
-
32
- # @param issuer_id [String] App Store Connect API Issuer ID
33
- # @param key_id [String] App Store Connect API Key ID
34
- # @param private_key_path [String] Path to App Store Connect API Private Key (.p8)
35
- def initialize(issuer_id:, key_id:, private_key_path:)
36
- @issuer_id = issuer_id
37
- @key_id = key_id
38
- @private_key = Utils.private_key(path: private_key_path)
39
- end
40
-
41
- # @return [Hash]
42
- def payload
43
- {
44
- exp: Time.now.to_i + 20 * 60,
45
- iss: issuer_id,
46
- aud: AUDIENCE
47
- }
48
- end
49
-
50
- # @return [Hash]
51
- def header_fields
52
- { kid: key_id }
53
- end
54
-
55
- # @return [String]
56
- def token
57
- Utils.encode(payload, private_key, ALGORITHM, header_fields)
58
- end
59
-
60
- alias to_s token
61
31
  end
62
32
  end
@@ -8,19 +8,45 @@ module AppStoreConnect
8
8
  class CLI
9
9
  extend GLI::App
10
10
 
11
- command :generate do |c|
12
- c.flag %i[issuer-id i], required: true, default_value: ENV['APP_STORE_CONNECT_ISSUER_ID'], mask: true
13
- c.flag %i[key-id k], required: true, default_value: ENV['APP_STORE_CONNECT_KEY_ID'], mask: true
14
- c.flag %i[private-key-path p], required: true, default_value: ENV['APP_STORE_CONNECT_PRIVATE_KEY_PATH']
11
+ command :encode do |c|
12
+ c.flag %i[issuer-id i],
13
+ required: true,
14
+ default_value: ENV['APP_STORE_CONNECT_ISSUER_ID'],
15
+ mask: true
16
+
17
+ c.flag %i[key-id k],
18
+ required: true,
19
+ default_value: ENV['APP_STORE_CONNECT_KEY_ID'],
20
+ mask: true
21
+
22
+ c.flag %i[private-key-path p],
23
+ required: true,
24
+ default_value: ENV['APP_STORE_CONNECT_PRIVATE_KEY_PATH']
15
25
 
16
26
  c.action do |_, options, _|
17
- puts AppStoreConnect::JWT.new(
27
+ puts AppStoreConnect::JWT.encode(
18
28
  issuer_id: options.fetch(:"issuer-id"),
19
29
  key_id: options.fetch(:"key-id"),
20
30
  private_key_path: options.fetch(:"private-key-path")
21
31
  )
22
32
  end
23
33
  end
34
+
35
+ command :decode do |c|
36
+ c.flag %i[token t],
37
+ required: true
38
+
39
+ c.flag %i[private-key-path p],
40
+ required: true,
41
+ default_value: ENV['APP_STORE_CONNECT_PRIVATE_KEY_PATH']
42
+
43
+ c.action do |_, options, _|
44
+ puts AppStoreConnect::JWT.decode(
45
+ token: options.fetch(:token),
46
+ private_key_path: options.fetch(:"private-key-path")
47
+ )
48
+ end
49
+ end
24
50
  end
25
51
  end
26
52
  end
@@ -23,9 +23,26 @@ module AppStoreConnect
23
23
  ::JWT.decode(token, private_key, true, algorithm: algorithm)
24
24
  end
25
25
 
26
+ # @param key_id [String]
27
+ # @return [Hash]
28
+ def self.header_fields(key_id)
29
+ { kid: key_id }
30
+ end
31
+
32
+ # @param issuer_id [String]
33
+ # @param audience [String]
34
+ # @return [Hash]
35
+ def self.payload(issuer_id, audience)
36
+ {
37
+ exp: Time.now.to_i + 20 * 60,
38
+ iss: issuer_id,
39
+ aud: audience
40
+ }
41
+ end
42
+
26
43
  # @param path [String]
27
44
  # @return [OpenSSL::PKey::EC]
28
- def self.private_key(path:)
45
+ def self.private_key(path)
29
46
  OpenSSL::PKey.read(File.read(File.expand_path(path)))
30
47
  end
31
48
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AppStoreConnect
4
4
  class JWT
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_store_connect_jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Decot
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-17 00:00:00.000000000 Z
11
+ date: 2020-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,30 +28,30 @@ dependencies:
28
28
  name: guard-rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '4.7'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '4.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '0.12'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '0.12'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -84,72 +84,72 @@ dependencies:
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: '0.79'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: '0.79'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: '0.17'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: '0.17'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: timecop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
117
+ version: '0.9'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: '0.9'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: gli
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: '2.19'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '0'
138
+ version: '2.19'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: jwt
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - ">="
143
+ - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '0'
145
+ version: '2.2'
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - ">="
150
+ - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '0'
152
+ version: '2.2'
153
153
  description: Generate App Store Connect JWT
154
154
  email:
155
155
  - kyle.decot@icloud.com
@@ -162,12 +162,14 @@ files:
162
162
  - ".github/ISSUE_TEMPLATE/config.yml"
163
163
  - ".github/ISSUE_TEMPLATE/feature_request.md"
164
164
  - ".github/workflows/lint.yml"
165
+ - ".github/workflows/publish.yml"
165
166
  - ".github/workflows/test.yml"
166
167
  - ".gitignore"
167
168
  - ".rspec"
168
169
  - ".rubocop.yml"
169
170
  - ".ruby-version"
170
171
  - ".yamllint"
172
+ - CODE_OF_CONDUCT.md
171
173
  - Gemfile
172
174
  - Gemfile.lock
173
175
  - Guardfile
@@ -176,6 +178,7 @@ files:
176
178
  - Rakefile
177
179
  - app_store_connect_jwt.gemspec
178
180
  - bin/console
181
+ - bin/publish
179
182
  - bin/setup
180
183
  - exe/app-store-connect-jwt
181
184
  - lib/app_store_connect.rb