blinkist-airbrake-scrubber 2.1.2 → 3.0.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.
- checksums.yaml +5 -5
- data/README.md +6 -12
- data/blinkist-airbrake-scrubber.gemspec +4 -4
- data/lib/blinkist-airbrake-scrubber.rb +15 -17
- data/lib/blinkist-airbrake-scrubber/deep_traversal.rb +26 -28
- data/lib/blinkist-airbrake-scrubber/scrubbers/message_email.rb +11 -13
- data/lib/blinkist-airbrake-scrubber/scrubbers/params_email.rb +10 -12
- data/lib/blinkist-airbrake-scrubber/scrubbers/params_password.rb +10 -12
- data/lib/blinkist-airbrake-scrubber/version.rb +4 -4
- data/spec/specs/lib/blinkist-airbrake-scrubber/airbrake_spec.rb +4 -4
- data/spec/specs/lib/blinkist-airbrake-scrubber/deep_traversal_spec.rb +1 -1
- data/spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/message_email_spec.rb +2 -2
- data/spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/params_email_spec.rb +4 -4
- data/spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/params_password_spec.rb +4 -4
- data/spec/specs/lib/blinkist_airbrake_scrubber_spec.rb +8 -8
- data/spec/specs/version_spec.rb +5 -5
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6c7292d499d48e12d164b7099303bc900cb2386c
|
4
|
+
data.tar.gz: e5c1c74178c864d515b79e91c3cf2815da08584e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a6c5b60ac452b1c6137dd00138db21b2bdfd403fb2ef62c5514b23dc6aefca20946ce0076581077fd6198b6e62f4626ce06385850f47cbce3bf62f69f83949c
|
7
|
+
data.tar.gz: ce775a0990fe520c9d7396df3da85c48e92b279b7faae5963e6d8da16db69c3c0b87230247d2e49c530190d8cac06a0b02f6bff7a677b0999bb42dc8c0f117bd
|
data/README.md
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
# Blinkist::
|
1
|
+
# Blinkist::AirbrakeScrubber
|
2
2
|
|
3
|
-
Blinkist::
|
3
|
+
Blinkist::AirbrakeScrubber provides an Airbrake scrubbing service to remove various sensitive informations from the notifications, e.g. emails. It does *not* replace Airbrake configuration, but provides some seamless functionality.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
gem "blinkist-airbrake-scrubber"
|
9
|
+
gem "blinkist-airbrake-scrubber"
|
10
10
|
|
11
11
|
And then execute:
|
12
12
|
|
@@ -19,7 +19,7 @@ And then execute:
|
|
19
19
|
To extend the functionality, create a new scrubber file in `lib/blinkist-airbrake-scrubber/scrubbers` folder, like the template:
|
20
20
|
|
21
21
|
```ruby
|
22
|
-
module Blinkist::
|
22
|
+
module Blinkist::AirbrakeScrubber
|
23
23
|
class WubbaLubba
|
24
24
|
REGEXP = /[\S]+@[\S]+/i
|
25
25
|
|
@@ -34,17 +34,11 @@ module Blinkist::Airbrake::Scrubber
|
|
34
34
|
end
|
35
35
|
```
|
36
36
|
|
37
|
-
Then, add the class to Blinkist::
|
38
|
-
|
39
|
-
### Applications using this gem
|
40
|
-
|
41
|
-
There are a few applications available on GitHub that use this gem. For usage see:
|
42
|
-
|
43
|
-
* blinkist-messenger
|
37
|
+
Then, add the class to Blinkist::AirbrakeScrubber's SCRUBBERS list to have it ran after Airbrake.configure
|
44
38
|
|
45
39
|
### Dependencies
|
46
40
|
|
47
|
-
This gem has dependency on airbrake (~>
|
41
|
+
This gem has dependency on airbrake (~> 7), it will automatically add it unless already bundled.
|
48
42
|
|
49
43
|
## Maintainers
|
50
44
|
|
@@ -5,12 +5,12 @@ require_relative "lib/blinkist-airbrake-scrubber/version"
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "blinkist-airbrake-scrubber"
|
8
|
-
gem.version = Blinkist::
|
9
|
-
gem.authors = ["Paweł Komarnicki", "Dinesh Vasudevan"]
|
10
|
-
gem.email = ["pawel@blinkist.com", "dinesh@blinkist.com"]
|
8
|
+
gem.version = Blinkist::AirbrakeScrubber::VERSION
|
9
|
+
gem.authors = ["Paweł Komarnicki", "Dinesh Vasudevan", 'Tomek Przedmojski']
|
10
|
+
gem.email = ["pawel@blinkist.com", "dinesh@blinkist.com", "tomek@blinkist.com"]
|
11
11
|
gem.description = %q{Email scrubbing configuration for Airbrake at Blinkist}
|
12
12
|
gem.summary = %q{With this, Airbrake will not leak emails via exception notifications}
|
13
|
-
gem.homepage = "https://github.com/blinkist/
|
13
|
+
gem.homepage = "https://github.com/blinkist/airbrake-scrubber"
|
14
14
|
gem.license = "MIT"
|
15
15
|
|
16
16
|
# Airbrake
|
@@ -4,32 +4,30 @@ Dir[File.expand_path('../../lib/**/*.rb', __FILE__)].each do |f|
|
|
4
4
|
end
|
5
5
|
|
6
6
|
# Prepend the original Airbrake module
|
7
|
-
# Note: Do not remove from this file, it needs to be before Blinkist::
|
7
|
+
# Note: Do not remove from this file, it needs to be before Blinkist::AirbrakeScrubber
|
8
8
|
module Airbrake
|
9
9
|
class << self
|
10
|
-
prepend Blinkist::
|
10
|
+
prepend Blinkist::AirbrakeScrubber
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
# Set up the namespace and run every scrubber listed in SCRUBBERS
|
15
15
|
module Blinkist
|
16
|
-
module
|
17
|
-
|
18
|
-
|
19
|
-
SCRUBBERS = [ MessageEmail, ParamsEmail, ParamsPassword ]
|
16
|
+
module AirbrakeScrubber
|
17
|
+
FILTERED = '[Filtered]'
|
18
|
+
SCRUBBERS = [ MessageEmail, ParamsEmail, ParamsPassword ]
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
# Run scrubbers
|
29
|
-
def self.run!
|
30
|
-
SCRUBBERS.each { |scrubber| scrubber::scrub! }
|
31
|
-
end
|
20
|
+
# Override original Airbrake.configure
|
21
|
+
def configure(*args, &block)
|
22
|
+
super
|
23
|
+
ensure
|
24
|
+
Blinkist::AirbrakeScrubber.run!
|
25
|
+
end
|
32
26
|
|
27
|
+
# Run scrubbers
|
28
|
+
def self.run!
|
29
|
+
SCRUBBERS.each { |scrubber| scrubber::scrub! }
|
33
30
|
end
|
31
|
+
|
34
32
|
end
|
35
33
|
end
|
@@ -1,43 +1,41 @@
|
|
1
1
|
# DeepTraversal provides traverse possibility of Hashes
|
2
2
|
# Can handle Hash objects with deep nesting, or other nested objects that can be dug deeper (e.g. Array)
|
3
3
|
module Blinkist
|
4
|
-
module
|
5
|
-
module Scrubber
|
4
|
+
module AirbrakeScrubber
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
class DeepTraversal
|
7
|
+
def initialize(source)
|
8
|
+
@source = source
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def traverse(&block)
|
12
|
+
recursive_traverse(@source, &block)
|
13
|
+
end
|
15
14
|
|
16
|
-
|
15
|
+
private
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
def recursive_traverse(input, &block)
|
18
|
+
case input
|
19
|
+
when Array
|
20
|
+
input.map { |i| recursive_traverse(i, &block) }
|
22
21
|
|
23
|
-
|
24
|
-
|
22
|
+
when Hash
|
23
|
+
Hash[input.map { |key, value|
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
25
|
+
# Go deeper for things that are not simple objects
|
26
|
+
case value
|
27
|
+
when Array, Hash
|
28
|
+
[ key, recursive_traverse(value, &block) ]
|
29
|
+
else
|
30
|
+
[ key, block.call(key, value) ]
|
31
|
+
end
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
33
|
+
}]
|
34
|
+
else
|
35
|
+
input
|
38
36
|
end
|
39
37
|
end
|
40
|
-
|
41
38
|
end
|
39
|
+
|
42
40
|
end
|
43
41
|
end
|
@@ -1,21 +1,19 @@
|
|
1
1
|
module Blinkist
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
REGEXP = /[\S]+@[\S]+/i
|
2
|
+
module AirbrakeScrubber
|
3
|
+
class MessageEmail
|
4
|
+
REGEXP = /[\S]+@[\S]+/i
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
end # def self.scrub!
|
13
|
-
|
14
|
-
def self.scrub(message)
|
15
|
-
message.gsub(REGEXP, FILTERED)
|
6
|
+
def self.scrub!
|
7
|
+
::Airbrake.add_filter do |notice|
|
8
|
+
# Cannot do gsub! coz of frozen literals
|
9
|
+
notice[:errors].each { |error| error[:message] = scrub(error[:message]) }
|
16
10
|
end
|
11
|
+
end # def self.scrub!
|
17
12
|
|
13
|
+
def self.scrub(message)
|
14
|
+
message.gsub(REGEXP, FILTERED)
|
18
15
|
end
|
16
|
+
|
19
17
|
end
|
20
18
|
end
|
21
19
|
end
|
@@ -1,19 +1,17 @@
|
|
1
1
|
module Blinkist
|
2
|
-
module
|
3
|
-
|
4
|
-
class ParamsEmail
|
2
|
+
module AirbrakeScrubber
|
3
|
+
class ParamsEmail
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
notice
|
5
|
+
def self.scrub!
|
6
|
+
::Airbrake.add_filter do |notice|
|
7
|
+
notice[:params] = DeepTraversal.new(notice[:params]).traverse do |key, value|
|
8
|
+
value = FILTERED if key.to_s == 'email'
|
9
|
+
value
|
13
10
|
end
|
14
|
-
|
11
|
+
notice
|
12
|
+
end
|
13
|
+
end # def self.scrub!
|
15
14
|
|
16
|
-
end
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
@@ -1,19 +1,17 @@
|
|
1
1
|
module Blinkist
|
2
|
-
module
|
3
|
-
|
4
|
-
class ParamsPassword
|
2
|
+
module AirbrakeScrubber
|
3
|
+
class ParamsPassword
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
notice
|
5
|
+
def self.scrub!
|
6
|
+
::Airbrake.add_filter do |notice|
|
7
|
+
notice[:params] = DeepTraversal.new(notice[:params]).traverse do |key, value|
|
8
|
+
value = FILTERED if key.to_s == 'password'
|
9
|
+
value
|
13
10
|
end
|
14
|
-
|
11
|
+
notice
|
12
|
+
end
|
13
|
+
end # def self.scrub!
|
15
14
|
|
16
|
-
end
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
@@ -10,14 +10,14 @@ describe Airbrake do
|
|
10
10
|
}
|
11
11
|
|
12
12
|
describe "Module#prepend" do
|
13
|
-
it "does have Blinkist::
|
14
|
-
expect(described_class.ancestors).to include(Blinkist::
|
13
|
+
it "does have Blinkist::AirbrakeScrubber as one of the ancestors" do
|
14
|
+
expect(described_class.ancestors).to include(Blinkist::AirbrakeScrubber)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
describe '.configure' do
|
19
|
-
it "does call Blinkist::
|
20
|
-
expect_any_instance_of(Blinkist::
|
19
|
+
it "does call Blinkist::AirbrakeScrubber.configure" do
|
20
|
+
expect_any_instance_of(Blinkist::AirbrakeScrubber).to receive(:configure)
|
21
21
|
instantiate_airbrake
|
22
22
|
end
|
23
23
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Blinkist::
|
3
|
+
describe Blinkist::AirbrakeScrubber::MessageEmail do
|
4
4
|
|
5
5
|
describe "Structure" do
|
6
6
|
it "has REGEXP constant" do
|
@@ -24,7 +24,7 @@ describe Blinkist::Airbrake::Scrubber::MessageEmail do
|
|
24
24
|
# It's ridiculously hard to peek into Airbrake::Notice
|
25
25
|
# Instead verify the functionality here
|
26
26
|
describe ".scrub" do
|
27
|
-
let(:filtered) { Blinkist::
|
27
|
+
let(:filtered) { Blinkist::AirbrakeScrubber::FILTERED }
|
28
28
|
let(:regexp) { described_class::REGEXP }
|
29
29
|
|
30
30
|
let(:valid_domains) { %w{ example.org exam-ple.org exam.ple.org e-xam.ple.org e-xam.p-le.org e.x.a.m.p.l.e.co.uk } }
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Blinkist::
|
3
|
+
describe Blinkist::AirbrakeScrubber::ParamsEmail do
|
4
4
|
let(:notifier) { Airbrake[:default] }
|
5
5
|
let(:notice) {
|
6
6
|
Airbrake[:default].build_notice(
|
@@ -23,7 +23,7 @@ describe Blinkist::Airbrake::Scrubber::ParamsEmail do
|
|
23
23
|
|
24
24
|
it "scrubs the email from the params hash" do
|
25
25
|
notifier.instance_variable_get(:@filter_chain).refine(notice)
|
26
|
-
expect(notice[:params][:email]).to eq(Blinkist::
|
26
|
+
expect(notice[:params][:email]).to eq(Blinkist::AirbrakeScrubber::FILTERED)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "scrubs the deep-nested email from the params hash" do
|
@@ -33,8 +33,8 @@ describe Blinkist::Airbrake::Scrubber::ParamsEmail do
|
|
33
33
|
)
|
34
34
|
|
35
35
|
notifier.instance_variable_get(:@filter_chain).refine(notice)
|
36
|
-
expect(notice[:params][:email]).to eq(Blinkist::
|
37
|
-
expect(notice[:params][:deeply][:nested][:email]).to eq(Blinkist::
|
36
|
+
expect(notice[:params][:email]).to eq(Blinkist::AirbrakeScrubber::FILTERED)
|
37
|
+
expect(notice[:params][:deeply][:nested][:email]).to eq(Blinkist::AirbrakeScrubber::FILTERED)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Blinkist::
|
3
|
+
describe Blinkist::AirbrakeScrubber::ParamsPassword do
|
4
4
|
let(:notifier) { Airbrake[:default] }
|
5
5
|
let(:notice) {
|
6
6
|
Airbrake[:default].build_notice(
|
@@ -23,7 +23,7 @@ describe Blinkist::Airbrake::Scrubber::ParamsPassword do
|
|
23
23
|
|
24
24
|
it "scrubs the password from the params hash" do
|
25
25
|
notifier.instance_variable_get(:@filter_chain).refine(notice)
|
26
|
-
expect(notice[:params][:password]).to eq(Blinkist::
|
26
|
+
expect(notice[:params][:password]).to eq(Blinkist::AirbrakeScrubber::FILTERED)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "scrubs the deep-nested password from the params hash" do
|
@@ -33,8 +33,8 @@ describe Blinkist::Airbrake::Scrubber::ParamsPassword do
|
|
33
33
|
)
|
34
34
|
|
35
35
|
notifier.instance_variable_get(:@filter_chain).refine(notice)
|
36
|
-
expect(notice[:params][:password]).to eq(Blinkist::
|
37
|
-
expect(notice[:params][:deeply][:nested][:password]).to eq(Blinkist::
|
36
|
+
expect(notice[:params][:password]).to eq(Blinkist::AirbrakeScrubber::FILTERED)
|
37
|
+
expect(notice[:params][:deeply][:nested][:password]).to eq(Blinkist::AirbrakeScrubber::FILTERED)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'securerandom'
|
3
3
|
require 'blinkist-airbrake-scrubber'
|
4
4
|
|
5
|
-
describe Blinkist::
|
5
|
+
describe Blinkist::AirbrakeScrubber do
|
6
6
|
let(:instantiate_airbrake) {
|
7
7
|
Airbrake.configure :"notifier_#{ SecureRandom.uuid }" do |c|
|
8
8
|
c.project_id = 1
|
@@ -12,19 +12,19 @@ describe Blinkist::Airbrake::Scrubber do
|
|
12
12
|
|
13
13
|
describe "Constants" do
|
14
14
|
it "has FILTERED constant" do
|
15
|
-
expect(Blinkist::
|
15
|
+
expect(Blinkist::AirbrakeScrubber.constants).to include(:FILTERED)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "has explicit FILTERED constant content" do
|
19
|
-
expect(Blinkist::
|
19
|
+
expect(Blinkist::AirbrakeScrubber::FILTERED).to eq('[Filtered]')
|
20
20
|
end
|
21
21
|
|
22
22
|
it "has SCRUBBERS constant" do
|
23
|
-
expect(Blinkist::
|
23
|
+
expect(Blinkist::AirbrakeScrubber.constants).to include(:SCRUBBERS)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "has list of scrubbers in SCRUBBERS" do
|
27
|
-
expect(Blinkist::
|
27
|
+
expect(Blinkist::AirbrakeScrubber::SCRUBBERS.is_a?(Array)).to be true
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -34,15 +34,15 @@ describe Blinkist::Airbrake::Scrubber do
|
|
34
34
|
instantiate_airbrake
|
35
35
|
end
|
36
36
|
|
37
|
-
it "calls Blinkist::
|
38
|
-
expect(Blinkist::
|
37
|
+
it "calls Blinkist::AirbrakeScrubber.run!" do
|
38
|
+
expect(Blinkist::AirbrakeScrubber).to receive(:run!)
|
39
39
|
instantiate_airbrake
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
describe "self.run!" do
|
44
44
|
it "runs ::scrub! for every scrubber declared in SCRUBBERS" do
|
45
|
-
Blinkist::
|
45
|
+
Blinkist::AirbrakeScrubber::SCRUBBERS.each do |scrubber|
|
46
46
|
expect(scrubber).to receive(:scrub!)
|
47
47
|
end
|
48
48
|
instantiate_airbrake
|
data/spec/specs/version_spec.rb
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
require 'blinkist-airbrake-scrubber/version'
|
4
4
|
|
5
|
-
describe Blinkist::
|
5
|
+
describe Blinkist::AirbrakeScrubber::VERSION do
|
6
6
|
|
7
7
|
it 'provides the current version' do
|
8
|
-
version = Blinkist::
|
8
|
+
version = Blinkist::AirbrakeScrubber::VERSION
|
9
9
|
expect(version).to_not be nil
|
10
10
|
expect(version.instance_of?(String)).to be true
|
11
11
|
end
|
12
12
|
|
13
|
-
it 'equals
|
14
|
-
version = Blinkist::
|
15
|
-
expect(version).to eq '
|
13
|
+
it 'equals 3.0.0 for auto-check purposes' do
|
14
|
+
version = Blinkist::AirbrakeScrubber::VERSION
|
15
|
+
expect(version).to eq '3.0.0'
|
16
16
|
end
|
17
17
|
|
18
18
|
end
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blinkist-airbrake-scrubber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paweł Komarnicki
|
8
8
|
- Dinesh Vasudevan
|
9
|
+
- Tomek Przedmojski
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2018-05-
|
13
|
+
date: 2018-05-28 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: airbrake
|
@@ -29,6 +30,7 @@ description: Email scrubbing configuration for Airbrake at Blinkist
|
|
29
30
|
email:
|
30
31
|
- pawel@blinkist.com
|
31
32
|
- dinesh@blinkist.com
|
33
|
+
- tomek@blinkist.com
|
32
34
|
executables: []
|
33
35
|
extensions: []
|
34
36
|
extra_rdoc_files: []
|
@@ -51,7 +53,7 @@ files:
|
|
51
53
|
- spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/params_password_spec.rb
|
52
54
|
- spec/specs/lib/blinkist_airbrake_scrubber_spec.rb
|
53
55
|
- spec/specs/version_spec.rb
|
54
|
-
homepage: https://github.com/blinkist/
|
56
|
+
homepage: https://github.com/blinkist/airbrake-scrubber
|
55
57
|
licenses:
|
56
58
|
- MIT
|
57
59
|
metadata: {}
|
@@ -71,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
73
|
version: '0'
|
72
74
|
requirements: []
|
73
75
|
rubyforge_project:
|
74
|
-
rubygems_version: 2.
|
76
|
+
rubygems_version: 2.5.2.2
|
75
77
|
signing_key:
|
76
78
|
specification_version: 4
|
77
79
|
summary: With this, Airbrake will not leak emails via exception notifications
|