lunchmoney 1.4.1 → 1.5.0

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_and_publish_yard_docs.yml +2 -2
  3. data/.github/workflows/ci.yml +9 -10
  4. data/.github/workflows/rbi-updater.yml +1 -1
  5. data/.github/workflows/release_pipeline.yml +1 -1
  6. data/.rubocop.yml +1 -1
  7. data/.ruby-version +1 -1
  8. data/.toys/.toys.rb +8 -0
  9. data/Gemfile +1 -1
  10. data/Gemfile.lock +76 -60
  11. data/README.md +0 -2
  12. data/SECURITY.md +151 -0
  13. data/bin/check_vcr_version +94 -0
  14. data/lib/lunchmoney/api.rb +25 -38
  15. data/lib/lunchmoney/calls/assets.rb +10 -13
  16. data/lib/lunchmoney/calls/base.rb +59 -7
  17. data/lib/lunchmoney/calls/budgets.rb +22 -25
  18. data/lib/lunchmoney/calls/categories.rb +28 -36
  19. data/lib/lunchmoney/calls/crypto.rb +7 -9
  20. data/lib/lunchmoney/calls/plaid_accounts.rb +7 -9
  21. data/lib/lunchmoney/calls/recurring_expenses.rb +4 -5
  22. data/lib/lunchmoney/calls/tags.rb +3 -4
  23. data/lib/lunchmoney/calls/transactions.rb +28 -36
  24. data/lib/lunchmoney/calls/users.rb +3 -4
  25. data/lib/lunchmoney/configuration.rb +20 -0
  26. data/lib/lunchmoney/objects/object.rb +4 -9
  27. data/lib/lunchmoney/validators.rb +8 -6
  28. data/lib/lunchmoney/version.rb +1 -1
  29. data/lib/lunchmoney.rb +3 -3
  30. data/lunchmoney.gemspec +1 -1
  31. data/sorbet/rbi/annotations/activesupport.rbi +35 -0
  32. data/sorbet/rbi/dsl/active_support/callbacks.rbi +0 -2
  33. data/sorbet/rbi/gems/{activesupport@7.2.2.1.rbi → activesupport@8.0.2.1.rbi} +1369 -989
  34. data/sorbet/rbi/gems/{ast@2.4.2.rbi → ast@2.4.3.rbi} +4 -3
  35. data/sorbet/rbi/gems/{base64@0.2.0.rbi → base64@0.3.0.rbi} +76 -39
  36. data/sorbet/rbi/gems/{benchmark@0.4.0.rbi → benchmark@0.4.1.rbi} +50 -49
  37. data/sorbet/rbi/gems/bigdecimal@3.2.2.rbi +275 -0
  38. data/sorbet/rbi/gems/{dotenv@3.1.7.rbi → dotenv@3.1.8.rbi} +9 -9
  39. data/sorbet/rbi/gems/{drb@2.2.1.rbi → drb@2.2.3.rbi} +503 -188
  40. data/sorbet/rbi/gems/{faraday-net_http@3.4.0.rbi → faraday-net_http@3.4.1.rbi} +23 -23
  41. data/sorbet/rbi/gems/{faraday@2.12.2.rbi → faraday@2.13.4.rbi} +468 -141
  42. data/sorbet/rbi/gems/{hashdiff@1.1.2.rbi → hashdiff@1.2.0.rbi} +5 -3
  43. data/sorbet/rbi/gems/{json@2.10.2.rbi → json@2.13.2.rbi} +386 -175
  44. data/sorbet/rbi/gems/{kramdown@2.4.0.rbi → kramdown@2.5.1.rbi} +316 -234
  45. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
  46. data/sorbet/rbi/gems/{logger@1.6.6.rbi → logger@1.7.0.rbi} +63 -40
  47. data/sorbet/rbi/gems/{parser@3.3.7.1.rbi → parser@3.3.9.0.rbi} +303 -291
  48. data/sorbet/rbi/gems/{rack@3.1.9.rbi → rack@3.2.1.rbi} +712 -547
  49. data/sorbet/rbi/gems/{rake@13.2.1.rbi → rake@13.3.0.rbi} +238 -227
  50. data/sorbet/rbi/gems/{rbi@0.3.1.rbi → rbi@0.3.6.rbi} +1084 -2521
  51. data/sorbet/rbi/gems/{rbs@3.9.0.rbi → rbs@4.0.0.dev.4.rbi} +1336 -419
  52. data/sorbet/rbi/gems/{regexp_parser@2.10.0.rbi → regexp_parser@2.11.2.rbi} +1044 -956
  53. data/sorbet/rbi/gems/require-hooks@0.2.2.rbi +110 -0
  54. data/sorbet/rbi/gems/{rexml@3.4.1.rbi → rexml@3.4.2.rbi} +302 -292
  55. data/sorbet/rbi/gems/{rubocop-ast@1.38.0.rbi → rubocop-ast@1.46.0.rbi} +802 -1016
  56. data/sorbet/rbi/gems/{rubocop-minitest@0.36.0.rbi → rubocop-minitest@0.38.2.rbi} +129 -93
  57. data/sorbet/rbi/gems/{rubocop-rails@2.29.1.rbi → rubocop-rails@2.33.3.rbi} +575 -230
  58. data/sorbet/rbi/gems/{rubocop-shopify@2.15.1.rbi → rubocop-shopify@2.17.1.rbi} +1 -0
  59. data/sorbet/rbi/gems/{rubocop-sorbet@0.8.7.rbi → rubocop-sorbet@0.10.5.rbi} +761 -83
  60. data/sorbet/rbi/gems/{rubocop@1.71.2.rbi → rubocop@1.80.1.rbi} +6543 -3097
  61. data/sorbet/rbi/gems/{spoom@1.6.1.rbi → spoom@1.7.6.rbi} +1179 -2621
  62. data/sorbet/rbi/gems/{tapioca@0.16.11.rbi → tapioca@0.17.7.rbi} +623 -745
  63. data/sorbet/rbi/gems/{thor@1.3.2.rbi → thor@1.4.0.rbi} +88 -67
  64. data/sorbet/rbi/gems/{unicode-display_width@3.1.4.rbi → unicode-display_width@3.1.5.rbi} +5 -5
  65. data/sorbet/rbi/gems/{vcr@6.3.1.rbi → vcr@6.3.1-ce35c236fe48899f02ddf780973b44cdb756c0ee.rbi} +140 -123
  66. metadata +42 -38
  67. data/sorbet/rbi/gems/bigdecimal@3.1.9.rbi +0 -78
  68. /data/sorbet/rbi/gems/{connection_pool@2.5.0.rbi → connection_pool@2.5.3.rbi} +0 -0
  69. /data/sorbet/rbi/gems/{language_server-protocol@3.17.0.4.rbi → language_server-protocol@3.17.0.5.rbi} +0 -0
  70. /data/sorbet/rbi/gems/{parallel@1.26.3.rbi → parallel@1.27.0.rbi} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50f3573ce7923a9282be65ac6fba693be82c2c51b8be11c268e23112fd06337c
4
- data.tar.gz: 7be51f4d39ed969199ab04e36dda18acc8203b10c149cf3410d447bfc4794019
3
+ metadata.gz: 837338cb47e04506201212586e26c1b9c25a21eded600c3ddf34b9e20fae4395
4
+ data.tar.gz: ef26cf61532ecc48c74e7f15f6bf215a148578c6903dea90ad4a78d36f89dc8f
5
5
  SHA512:
6
- metadata.gz: b3686c260fd902ca41f82f4ffc00064ed39b3828e86a648c9b5e5720ad87256778e96617447b7880aba7733e953a88341f7f9426f068f855afb7b62c35559dd8
7
- data.tar.gz: bcbf7d9ff45a32f0339df95660de9c5911ba556ef77becb44b21cdced5492b67bc6c3f764829bec6f87850e87269ee50326a97b3dbb4d9bad90f90ae1f259e52
6
+ metadata.gz: d5285b8d16caa4dd5d4f6897008db0d4ec0ac51efea529ac8174cd6fce0b1c3a2b5384a4a9c08f6ff667fb3b08cf3aaab52bb7e26b52220e116b7245dd052d16
7
+ data.tar.gz: a8775f582eee1fc9c8258ab8e89d7486dedd66be933f4fa7b3044eee6ce859edfcb3f218cb6c87e9eb4c98e381708fa1dcdd41b4e33019e1d4d445bfcd82b6ab
@@ -20,7 +20,7 @@ jobs:
20
20
  runs-on: ubuntu-latest
21
21
 
22
22
  steps:
23
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v5
24
24
 
25
25
  - name: Set up Ruby
26
26
  uses: ruby/setup-ruby@v1.218.0
@@ -38,7 +38,7 @@ jobs:
38
38
  uses: actions/configure-pages@v5
39
39
 
40
40
  - name: Upload Artifact
41
- uses: actions/upload-pages-artifact@v3
41
+ uses: actions/upload-pages-artifact@v4
42
42
  with:
43
43
  path: "doc"
44
44
 
@@ -14,19 +14,22 @@ jobs:
14
14
 
15
15
  strategy:
16
16
  matrix:
17
- ruby-version: [3.1, 3.2, 3.3, head]
17
+ ruby-version: [3.2, 3.3, 3.4, head]
18
18
  continue-on-error: ${{ endsWith(matrix.ruby-version, 'head') }}
19
19
 
20
20
  steps:
21
21
  -
22
22
  name: Checkout
23
- uses: actions/checkout@v4
23
+ uses: actions/checkout@v5
24
24
  -
25
25
  name: Setup Ruby
26
26
  uses: ruby/setup-ruby@v1
27
27
  with:
28
28
  bundler-cache: true
29
29
  ruby-version: ${{ matrix.ruby-version }}
30
+ -
31
+ name: Check for newer VCR version
32
+ run: bin/toys check-vcr-version
30
33
  -
31
34
  name: RuboCop
32
35
  run: bin/rubocop
@@ -46,18 +49,14 @@ jobs:
46
49
  run: bin/toys mdl
47
50
  -
48
51
  name: Run Tests (Using Cassettes)
49
- if: ${{ ! endsWith(matrix.ruby-version, '3.3') }}
52
+ if: ${{ ! endsWith(matrix.ruby-version, '3.4') }}
50
53
  run: bin/toys test
51
54
  -
52
55
  name: Run Tests (With Remote Calls & Coverage Report)
53
- if: ${{ endsWith(matrix.ruby-version, '3.3') }}
54
- uses: paambaati/codeclimate-action@v9.0.0
56
+ if: ${{ endsWith(matrix.ruby-version, '3.4') }}
57
+ continue-on-error: true
55
58
  env:
56
- CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
57
59
  REMOTE_TESTS_ENABLED: ${{ vars.REMOTE_TESTS_ENABLED }}
58
60
  LUNCHMONEY_TOKEN: ${{ secrets.LUNCHMONEY_TOKEN }}
59
- with:
60
- coverageCommand: bin/toys test
61
- coverageLocations: |
62
- ${{ github.workspace }}/coverage/coverage.json:simplecov
61
+ run: bin/toys test
63
62
 
@@ -9,7 +9,7 @@ jobs:
9
9
  steps:
10
10
  -
11
11
  name: Checkout
12
- uses: actions/checkout@v4
12
+ uses: actions/checkout@v5
13
13
  with:
14
14
  ref: ${{ github.event.pull_request.head.sha }}
15
15
  token: ${{ secrets.LUNCHMONEY_PAT_TOKEN }}
@@ -24,7 +24,7 @@ jobs:
24
24
 
25
25
  steps:
26
26
  # Set up
27
- - uses: actions/checkout@v4
27
+ - uses: actions/checkout@v5
28
28
  - name: Set up Ruby
29
29
  uses: ruby/setup-ruby@v1
30
30
  with:
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  inherit_gem:
2
2
  rubocop-shopify: rubocop.yml
3
3
 
4
- require:
4
+ plugins:
5
5
  - rubocop-sorbet
6
6
  - rubocop-minitest
7
7
  - rubocop-rails
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.4.2
1
+ 3.4.5
data/.toys/.toys.rb CHANGED
@@ -9,3 +9,11 @@ alias_tool :style, :rubocop
9
9
  alias_tool :tapioca, :rbi
10
10
  alias_tool :tc, :typecheck
11
11
  alias_tool :cov, :coverage
12
+
13
+ tool "check-vcr-version" do
14
+ desc "Check if a newer version of VCR has been released"
15
+
16
+ def run
17
+ system("ruby", "bin/check_vcr_version") || exit(1)
18
+ end
19
+ end
data/Gemfile CHANGED
@@ -10,7 +10,7 @@ gem "toys"
10
10
  gem "minitest", "~> 5.25", require: false
11
11
  gem "mocha", "~> 2.7.1", require: false
12
12
  gem "webmock", require: false
13
- gem "vcr", require: false
13
+ gem "vcr", git: "https://github.com/vcr/vcr.git", ref: "ce35c236fe48899f02ddf780973b44cdb756c0ee", require: false
14
14
  gem "rubocop-shopify", require: false
15
15
  gem "rubocop-sorbet", require: false
16
16
  gem "rubocop-minitest", require: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,14 @@
1
+ GIT
2
+ remote: https://github.com/vcr/vcr.git
3
+ revision: ce35c236fe48899f02ddf780973b44cdb756c0ee
4
+ ref: ce35c236fe48899f02ddf780973b44cdb756c0ee
5
+ specs:
6
+ vcr (6.3.1)
7
+
1
8
  PATH
2
9
  remote: .
3
10
  specs:
4
- lunchmoney (1.4.1)
11
+ lunchmoney (1.5.0)
5
12
  activesupport (>= 6.1)
6
13
  faraday (>= 1.0.0)
7
14
  sorbet-runtime (>= 0.5)
@@ -9,7 +16,7 @@ PATH
9
16
  GEM
10
17
  remote: https://rubygems.org/
11
18
  specs:
12
- activesupport (7.2.2.1)
19
+ activesupport (8.0.2.1)
13
20
  base64
14
21
  benchmark (>= 0.3)
15
22
  bigdecimal
@@ -21,43 +28,45 @@ GEM
21
28
  minitest (>= 5.1)
22
29
  securerandom (>= 0.3)
23
30
  tzinfo (~> 2.0, >= 2.0.5)
31
+ uri (>= 0.13.1)
24
32
  addressable (2.8.7)
25
33
  public_suffix (>= 2.0.2, < 7.0)
26
34
  appraisal (2.5.0)
27
35
  bundler
28
36
  rake
29
37
  thor (>= 0.14.0)
30
- ast (2.4.2)
31
- base64 (0.2.0)
32
- benchmark (0.4.0)
33
- bigdecimal (3.1.9)
38
+ ast (2.4.3)
39
+ base64 (0.3.0)
40
+ benchmark (0.4.1)
41
+ bigdecimal (3.2.2)
34
42
  chef-utils (18.5.0)
35
43
  concurrent-ruby
36
44
  concurrent-ruby (1.3.5)
37
- connection_pool (2.5.0)
45
+ connection_pool (2.5.3)
38
46
  crack (1.0.0)
39
47
  bigdecimal
40
48
  rexml
41
49
  docile (1.4.1)
42
- dotenv (3.1.7)
43
- drb (2.2.1)
50
+ dotenv (3.1.8)
51
+ drb (2.2.3)
44
52
  erubi (1.13.1)
45
- faraday (2.12.2)
53
+ faraday (2.13.4)
46
54
  faraday-net_http (>= 2.0, < 3.5)
47
55
  json
48
56
  logger
49
- faraday-net_http (3.4.0)
57
+ faraday-net_http (3.4.1)
50
58
  net-http (>= 0.5.0)
51
- hashdiff (1.1.2)
59
+ hashdiff (1.2.0)
52
60
  i18n (1.14.7)
53
61
  concurrent-ruby (~> 1.0)
54
- json (2.10.2)
55
- kramdown (2.4.0)
56
- rexml
62
+ json (2.13.2)
63
+ kramdown (2.5.1)
64
+ rexml (>= 3.3.9)
57
65
  kramdown-parser-gfm (1.1.0)
58
66
  kramdown (~> 2.0)
59
- language_server-protocol (3.17.0.4)
60
- logger (1.6.6)
67
+ language_server-protocol (3.17.0.5)
68
+ lint_roller (1.1.0)
69
+ logger (1.7.0)
61
70
  mdl (0.13.0)
62
71
  kramdown (~> 2.3)
63
72
  kramdown-parser-gfm (~> 1.1)
@@ -75,48 +84,54 @@ GEM
75
84
  net-http (0.6.0)
76
85
  uri
77
86
  netrc (0.11.0)
78
- parallel (1.26.3)
79
- parser (3.3.7.1)
87
+ parallel (1.27.0)
88
+ parser (3.3.9.0)
80
89
  ast (~> 2.4.1)
81
90
  racc
82
91
  prism (1.4.0)
83
92
  public_suffix (6.0.1)
84
93
  racc (1.8.1)
85
- rack (3.1.9)
94
+ rack (3.2.1)
86
95
  rainbow (3.1.1)
87
- rake (13.2.1)
88
- rbi (0.3.1)
96
+ rake (13.3.0)
97
+ rbi (0.3.6)
89
98
  prism (~> 1.0)
90
99
  rbs (>= 3.4.4)
91
- sorbet-runtime (>= 0.5.9204)
92
- rbs (3.9.0)
100
+ rbs (4.0.0.dev.4)
93
101
  logger
94
- regexp_parser (2.10.0)
95
- rexml (3.4.1)
96
- rubocop (1.71.2)
102
+ prism (>= 1.3.0)
103
+ regexp_parser (2.11.2)
104
+ require-hooks (0.2.2)
105
+ rexml (3.4.2)
106
+ rubocop (1.80.1)
97
107
  json (~> 2.3)
98
- language_server-protocol (>= 3.17.0)
108
+ language_server-protocol (~> 3.17.0.2)
109
+ lint_roller (~> 1.1.0)
99
110
  parallel (~> 1.10)
100
111
  parser (>= 3.3.0.2)
101
112
  rainbow (>= 2.2.2, < 4.0)
102
113
  regexp_parser (>= 2.9.3, < 3.0)
103
- rubocop-ast (>= 1.38.0, < 2.0)
114
+ rubocop-ast (>= 1.46.0, < 2.0)
104
115
  ruby-progressbar (~> 1.7)
105
116
  unicode-display_width (>= 2.4.0, < 4.0)
106
- rubocop-ast (1.38.0)
107
- parser (>= 3.3.1.0)
108
- rubocop-minitest (0.36.0)
109
- rubocop (>= 1.61, < 2.0)
110
- rubocop-ast (>= 1.31.1, < 2.0)
111
- rubocop-rails (2.29.1)
117
+ rubocop-ast (1.46.0)
118
+ parser (>= 3.3.7.2)
119
+ prism (~> 1.4)
120
+ rubocop-minitest (0.38.2)
121
+ lint_roller (~> 1.1)
122
+ rubocop (>= 1.75.0, < 2.0)
123
+ rubocop-ast (>= 1.38.0, < 2.0)
124
+ rubocop-rails (2.33.3)
112
125
  activesupport (>= 4.2.0)
126
+ lint_roller (~> 1.1)
113
127
  rack (>= 1.1)
114
- rubocop (>= 1.52.0, < 2.0)
115
- rubocop-ast (>= 1.31.1, < 2.0)
116
- rubocop-shopify (2.15.1)
117
- rubocop (~> 1.51)
118
- rubocop-sorbet (0.8.7)
119
- rubocop (>= 1)
128
+ rubocop (>= 1.75.0, < 2.0)
129
+ rubocop-ast (>= 1.44.0, < 2.0)
130
+ rubocop-shopify (2.17.1)
131
+ rubocop (~> 1.62)
132
+ rubocop-sorbet (0.10.5)
133
+ lint_roller
134
+ rubocop (>= 1.75.2)
120
135
  ruby-progressbar (1.13.0)
121
136
  ruby2_keywords (0.0.5)
122
137
  securerandom (0.4.1)
@@ -126,43 +141,44 @@ GEM
126
141
  simplecov_json_formatter (~> 0.1)
127
142
  simplecov-html (0.12.3)
128
143
  simplecov_json_formatter (0.1.4)
129
- sorbet (0.5.11953)
130
- sorbet-static (= 0.5.11953)
131
- sorbet-runtime (0.5.11953)
132
- sorbet-static (0.5.11953-universal-darwin)
133
- sorbet-static (0.5.11953-x86_64-linux)
134
- sorbet-static-and-runtime (0.5.11953)
135
- sorbet (= 0.5.11953)
136
- sorbet-runtime (= 0.5.11953)
137
- spoom (1.6.1)
144
+ sorbet (0.6.12473)
145
+ sorbet-static (= 0.6.12473)
146
+ sorbet-runtime (0.6.12473)
147
+ sorbet-static (0.6.12473-universal-darwin)
148
+ sorbet-static (0.6.12473-x86_64-linux)
149
+ sorbet-static-and-runtime (0.6.12473)
150
+ sorbet (= 0.6.12473)
151
+ sorbet-runtime (= 0.6.12473)
152
+ spoom (1.7.6)
138
153
  erubi (>= 1.10.0)
139
154
  prism (>= 0.28.0)
140
- rbi (>= 0.2.3)
155
+ rbi (>= 0.3.3)
156
+ rbs (>= 4.0.0.dev.4)
157
+ rexml (>= 3.2.6)
141
158
  sorbet-static-and-runtime (>= 0.5.10187)
142
159
  thor (>= 0.19.2)
143
- tapioca (0.16.11)
160
+ tapioca (0.17.7)
144
161
  benchmark
145
162
  bundler (>= 2.2.25)
146
163
  netrc (>= 0.11.0)
147
164
  parallel (>= 1.21.0)
148
- rbi (~> 0.2)
165
+ rbi (>= 0.3.1)
166
+ require-hooks (>= 0.2.2)
149
167
  sorbet-static-and-runtime (>= 0.5.11087)
150
- spoom (>= 1.2.0)
168
+ spoom (>= 1.7.0)
151
169
  thor (>= 1.2.0)
152
170
  yard-sorbet
153
- thor (1.3.2)
171
+ thor (1.4.0)
154
172
  tomlrb (2.0.3)
155
173
  toys (0.15.6)
156
174
  toys-core (= 0.15.6)
157
175
  toys-core (0.15.6)
158
176
  tzinfo (2.0.6)
159
177
  concurrent-ruby (~> 1.0)
160
- unicode-display_width (3.1.4)
178
+ unicode-display_width (3.1.5)
161
179
  unicode-emoji (~> 4.0, >= 4.0.4)
162
180
  unicode-emoji (4.0.4)
163
181
  uri (1.0.3)
164
- vcr (6.3.1)
165
- base64
166
182
  webmock (3.25.1)
167
183
  addressable (>= 2.8.0)
168
184
  crack (>= 0.3.2)
@@ -196,10 +212,10 @@ DEPENDENCIES
196
212
  spoom
197
213
  tapioca
198
214
  toys
199
- vcr
215
+ vcr!
200
216
  webmock
201
217
  yard
202
218
  yard-sorbet
203
219
 
204
220
  BUNDLED WITH
205
- 2.6.6
221
+ 2.7.0
data/README.md CHANGED
@@ -3,8 +3,6 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/lunchmoney.svg)](https://badge.fury.io/rb/lunchmoney)
4
4
  [![CI](https://github.com/mmenanno/lunchmoney/actions/workflows/ci.yml/badge.svg)](https://github.com/mmenanno/lunchmoney/actions/workflows/ci.yml)
5
5
  [![Yard Docs](https://github.com/mmenanno/lunchmoney/actions/workflows/build_and_publish_yard_docs.yml/badge.svg)](https://github.com/mmenanno/lunchmoney/actions/workflows/build_and_publish_yard_docs.yml)
6
- [![Maintainability](https://api.codeclimate.com/v1/badges/6e84458e8cf831e6a6fa/maintainability)](https://codeclimate.com/github/mmenanno/lunchmoney/maintainability)
7
- [![Test Coverage](https://api.codeclimate.com/v1/badges/6e84458e8cf831e6a6fa/test_coverage)](https://codeclimate.com/github/mmenanno/lunchmoney/test_coverage)
8
6
 
9
7
  <a href="https://www.buymeacoffee.com/mmenanno" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
10
8
 
data/SECURITY.md ADDED
@@ -0,0 +1,151 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We actively support the following versions of the `lunchmoney` gem with security updates:
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | 1.4.x | :white_check_mark: |
10
+ | 1.3.x | :white_check_mark: |
11
+ | < 1.3 | :x: |
12
+
13
+ ## Reporting a Vulnerability
14
+
15
+ We take the security of the `lunchmoney` gem seriously. If you discover a security vulnerability, please follow these steps:
16
+
17
+ ### How to Report
18
+
19
+ **Please do not report security vulnerabilities through public GitHub issues.**
20
+
21
+ Instead, please report security vulnerabilities by emailing us directly at:
22
+
23
+ - **Email**: [Create an email to the maintainer based on the GitHub profile]
24
+ - **Subject Line**: "[SECURITY] Vulnerability Report for lunchmoney gem"
25
+
26
+ ### What to Include
27
+
28
+ Please include the following information in your report:
29
+
30
+ 1. **Description**: A clear description of the vulnerability
31
+ 2. **Impact**: The potential impact and severity of the vulnerability
32
+ 3. **Reproduction Steps**: Step-by-step instructions to reproduce the issue
33
+ 4. **Affected Versions**: Which versions of the gem are affected
34
+ 5. **Suggested Fix**: If you have ideas for how to fix the issue (optional)
35
+ 6. **Your Contact Information**: So we can follow up with questions if needed
36
+
37
+ ### Response Timeline
38
+
39
+ We are committed to addressing security vulnerabilities promptly:
40
+
41
+ - **Acknowledgment**: We will acknowledge receipt of your vulnerability report within 48 hours
42
+ - **Initial Assessment**: We will provide an initial assessment within 5 business days
43
+ - **Status Updates**: We will provide regular updates on our progress
44
+ - **Resolution**: We aim to resolve critical vulnerabilities within 30 days
45
+
46
+ ### Responsible Disclosure
47
+
48
+ We kindly ask that you:
49
+
50
+ - Give us reasonable time to investigate and fix the issue before public disclosure
51
+ - Avoid accessing, modifying, or deleting data that doesn't belong to you
52
+ - Don't perform actions that could harm the availability or integrity of our services
53
+ - Don't social engineer our team members or contractors
54
+
55
+ ### Recognition
56
+
57
+ We appreciate the security research community's efforts to improve the security of our project. If you report a valid security vulnerability, we will:
58
+
59
+ - Acknowledge your contribution in our release notes (unless you prefer to remain anonymous)
60
+ - Work with you on the disclosure timeline
61
+ - Keep you informed throughout the remediation process
62
+
63
+ ## Security Best Practices for Users
64
+
65
+ When using the `lunchmoney` gem in your applications:
66
+
67
+ ### API Key Security
68
+
69
+ 1. **Never commit API keys to version control**
70
+ - Use environment variables (`LUNCHMONEY_TOKEN`)
71
+ - Use secure credential management systems
72
+ - Add API keys to your `.gitignore` file
73
+
74
+ 2. **Rotate API keys regularly**
75
+ - Generate new API keys periodically
76
+ - Immediately revoke compromised keys
77
+
78
+ 3. **Use least privilege access**
79
+ - Only grant the minimum permissions necessary
80
+ - Monitor API key usage for unusual activity
81
+
82
+ ### Network Security
83
+
84
+ 1. **Use HTTPS only**
85
+ - The gem uses HTTPS by default for all API calls
86
+ - Never disable SSL verification in production
87
+
88
+ 2. **Network monitoring**
89
+ - Monitor outbound API calls to LunchMoney
90
+ - Set up alerts for unusual API usage patterns
91
+
92
+ ### Dependency Security
93
+
94
+ 1. **Keep dependencies updated**
95
+ - Regularly update the `lunchmoney` gem
96
+ - Monitor for security advisories affecting dependencies
97
+
98
+ 2. **Audit your dependencies**
99
+
100
+ ```bash
101
+ # Install bundler-audit gem first
102
+ gem install bundler-audit
103
+
104
+ # Then audit your dependencies
105
+ bundle audit
106
+ ```
107
+
108
+ ### Error Handling
109
+
110
+ 1. **Don't log sensitive data**
111
+ - API keys should never appear in logs
112
+ - Be careful with error messages that might expose sensitive information
113
+
114
+ 2. **Handle API errors gracefully**
115
+
116
+ ```ruby
117
+ api = LunchMoney::Api.new
118
+ response = api.categories
119
+
120
+ if response.is_a?(LunchMoney::Errors)
121
+ # Handle error without exposing sensitive details
122
+ logger.error "API call failed"
123
+ end
124
+ ```
125
+
126
+ ## Security Features
127
+
128
+ This gem includes several security features:
129
+
130
+ - **HTTPS-only communication** with the LunchMoney API
131
+ - **Input validation** for API parameters
132
+ - **Error handling** that doesn't expose sensitive information
133
+ - **Dependency management** with regular updates
134
+
135
+ ## Vulnerability History
136
+
137
+ We will maintain a record of resolved security vulnerabilities here:
138
+
139
+ - No security vulnerabilities have been reported to date
140
+
141
+ ## Contact
142
+
143
+ For security-related questions or concerns, please contact:
144
+
145
+ - **Maintainer**: @mmenanno
146
+ - **Repository**: <https://github.com/mmenanno/lunchmoney>
147
+ - **Documentation**: <https://mmenanno.github.io/lunchmoney/>
148
+
149
+ ---
150
+
151
+ Thank you for helping keep the `lunchmoney` gem and our community safe!
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "net/http"
5
+ require "json"
6
+ require "uri"
7
+
8
+ # This script checks if a newer version of VCR has been released beyond 6.3.1
9
+ # If a newer version is found, it raises an error indicating that we should
10
+ # switch back to using the released gem instead of the git commit.
11
+
12
+ CURRENT_VCR_VERSION = "6.3.1"
13
+ VCR_COMMIT_SHA = "ce35c236fe48899f02ddf780973b44cdb756c0ee"
14
+
15
+ def fetch_latest_vcr_version
16
+ uri = URI("https://rubygems.org/api/v1/gems/vcr.json")
17
+ response = Net::HTTP.get_response(uri)
18
+
19
+ unless response.is_a?(Net::HTTPSuccess)
20
+ puts "Warning: Could not fetch VCR version information from RubyGems API"
21
+ puts "Response: #{response.code} #{response.message}"
22
+ return nil
23
+ end
24
+
25
+ gem_info = JSON.parse(response.body)
26
+ gem_info["version"]
27
+ rescue StandardError => e
28
+ puts "Warning: Error fetching VCR version information: #{e.message}"
29
+ nil
30
+ end
31
+
32
+ def version_greater?(version1, version2)
33
+ # Simple version comparison - splits by dots and compares numerically
34
+ v1_parts = version1.split(".").map(&:to_i)
35
+ v2_parts = version2.split(".").map(&:to_i)
36
+
37
+ # Pad shorter version with zeros
38
+ max_length = [v1_parts.length, v2_parts.length].max
39
+ v1_parts += [0] * (max_length - v1_parts.length)
40
+ v2_parts += [0] * (max_length - v2_parts.length)
41
+
42
+ v1_parts.zip(v2_parts).each do |v1, v2|
43
+ return true if v1 > v2
44
+ return false if v1 < v2
45
+ end
46
+
47
+ false # versions are equal
48
+ end
49
+
50
+ def main
51
+ puts "Checking for newer VCR releases..."
52
+ puts "Current pinned version: #{CURRENT_VCR_VERSION}"
53
+ puts "Using commit: #{VCR_COMMIT_SHA}"
54
+ puts ""
55
+
56
+ latest_version = fetch_latest_vcr_version
57
+
58
+ if latest_version.nil?
59
+ puts "Could not determine latest VCR version. Skipping check."
60
+ exit 0
61
+ end
62
+
63
+ puts "Latest released version: #{latest_version}"
64
+
65
+ if version_greater?(latest_version, CURRENT_VCR_VERSION)
66
+ puts ""
67
+ puts "🚨 NEWER VCR VERSION AVAILABLE! 🚨"
68
+ puts ""
69
+ puts "A newer version of VCR (#{latest_version}) has been released!"
70
+ puts "This is likely to include the Ruby 3.5+ compatibility fix from commit #{VCR_COMMIT_SHA}."
71
+ puts ""
72
+ puts "ACTION REQUIRED:"
73
+ puts "1. Update Gemfile to use the released version:"
74
+ puts " gem \"vcr\", \"~> #{latest_version}\", require: false"
75
+ puts ""
76
+ puts "2. Remove the git reference and commit SHA"
77
+ puts ""
78
+ puts "3. Run 'bundle update vcr' to update to the new version"
79
+ puts ""
80
+ puts "4. Test to ensure everything works with the released version"
81
+ puts ""
82
+ puts "5. Consider removing this version check script once updated"
83
+ puts ""
84
+
85
+ exit 1
86
+ else
87
+ puts "No newer version available. Continuing to use commit #{VCR_COMMIT_SHA}."
88
+ exit 0
89
+ end
90
+ end
91
+
92
+ if __FILE__ == $0
93
+ main
94
+ end