fcm 2.0.0 → 2.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 +4 -4
- data/README.md +6 -0
- data/fcm.gemspec +1 -1
- data/lib/fcm.rb +26 -3
- data/spec/fcm_spec.rb +85 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2802aecc49a82a5fedf980c9cdf38c3a429f0ebfa358efef7b4fbb0097ac8295
|
|
4
|
+
data.tar.gz: a124f4d7b09930550d58993807e4a6c5944279c47e16f51b90c18fab7b5f54a5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aacdfb6460c7ce30f990119219ddaa6ef5fc3ad33efe0f8bed5095df5f4435ec93aeac604f91031a9e9db58a4b19e3499fddbc9bc230e6c6b51c20557a283015
|
|
7
|
+
data.tar.gz: 684c306d874a14909f7f3dd3f95355aba895a9680e2eede3fb6b9b5b568636be09e639d3cfdaf17278cab9d157954b6b917bff6f974762a56ed003641a8be8f7
|
data/README.md
CHANGED
|
@@ -274,6 +274,12 @@ The guide to set up an iOS app to get notifications is here: [Setting up a FCM C
|
|
|
274
274
|
|
|
275
275
|
## ChangeLog
|
|
276
276
|
|
|
277
|
+
### 2.0.2
|
|
278
|
+
- Ensure JSON key path is an actual file or IO object before opening [#134](https://github.com/spacialdb/fcm/pull/134)
|
|
279
|
+
|
|
280
|
+
### 2.0.1
|
|
281
|
+
- Add `http_options` to `initialize` method and whitelist `timeout` option
|
|
282
|
+
|
|
277
283
|
### 2.0.0
|
|
278
284
|
#### Breaking Changes
|
|
279
285
|
- Remove deprecated `API_KEY`
|
data/fcm.gemspec
CHANGED
|
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "fcm"
|
|
6
|
-
s.version = "2.0.
|
|
6
|
+
s.version = "2.0.2"
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
|
8
8
|
s.authors = ["Kashif Rasul", "Shoaib Burq"]
|
|
9
9
|
s.email = ["kashif@decision-labs.com", "shoaib@decision-labs.com"]
|
data/lib/fcm.rb
CHANGED
|
@@ -4,6 +4,8 @@ require "json"
|
|
|
4
4
|
require "googleauth"
|
|
5
5
|
|
|
6
6
|
class FCM
|
|
7
|
+
class InvalidCredentialError < StandardError; end
|
|
8
|
+
|
|
7
9
|
BASE_URI = "https://fcm.googleapis.com"
|
|
8
10
|
BASE_URI_V1 = "https://fcm.googleapis.com/v1/projects/"
|
|
9
11
|
DEFAULT_TIMEOUT = 30
|
|
@@ -12,9 +14,10 @@ class FCM
|
|
|
12
14
|
INSTANCE_ID_API = "https://iid.googleapis.com"
|
|
13
15
|
TOPIC_REGEX = /[a-zA-Z0-9\-_.~%]+/
|
|
14
16
|
|
|
15
|
-
def initialize(json_key_path = "", project_name = "")
|
|
17
|
+
def initialize(json_key_path = "", project_name = "", http_options = {})
|
|
16
18
|
@json_key_path = json_key_path
|
|
17
19
|
@project_name = project_name
|
|
20
|
+
@http_options = http_options
|
|
18
21
|
end
|
|
19
22
|
|
|
20
23
|
# See https://firebase.google.com/docs/cloud-messaging/send-message
|
|
@@ -192,7 +195,7 @@ class FCM
|
|
|
192
195
|
def for_uri(uri, extra_headers = {})
|
|
193
196
|
connection = ::Faraday.new(
|
|
194
197
|
url: uri,
|
|
195
|
-
request: { timeout: DEFAULT_TIMEOUT }
|
|
198
|
+
request: { timeout: @http_options.fetch(:timeout, DEFAULT_TIMEOUT) }
|
|
196
199
|
) do |faraday|
|
|
197
200
|
faraday.adapter Faraday.default_adapter
|
|
198
201
|
faraday.headers["Content-Type"] = "application/json"
|
|
@@ -290,11 +293,31 @@ class FCM
|
|
|
290
293
|
token["access_token"]
|
|
291
294
|
end
|
|
292
295
|
|
|
296
|
+
def raise_credentials_error(param)
|
|
297
|
+
error_msg = 'credentials must be an IO-like ' \
|
|
298
|
+
'object or path. You passed'
|
|
299
|
+
|
|
300
|
+
param_klass = param.nil? ? 'nil' : "a #{param.class.name}"
|
|
301
|
+
error_msg += " #{param_klass}."
|
|
302
|
+
raise InvalidCredentialError, error_msg
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def valid_json_key_path?(path)
|
|
306
|
+
valid_io_object = path.respond_to?(:open)
|
|
307
|
+
return true if valid_io_object && File.file?(path)
|
|
308
|
+
|
|
309
|
+
max_path_len = 1024
|
|
310
|
+
valid_path = path.is_a?(String) && path.length <= max_path_len
|
|
311
|
+
valid_path && File.file?(path)
|
|
312
|
+
end
|
|
313
|
+
|
|
293
314
|
def json_key
|
|
294
315
|
@json_key ||= if @json_key_path.respond_to?(:read)
|
|
295
316
|
@json_key_path
|
|
296
|
-
|
|
317
|
+
elsif valid_json_key_path?(@json_key_path)
|
|
297
318
|
File.open(@json_key_path)
|
|
319
|
+
else
|
|
320
|
+
raise_credentials_error(@json_key_path)
|
|
298
321
|
end
|
|
299
322
|
end
|
|
300
323
|
end
|
data/spec/fcm_spec.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
|
+
require 'tempfile'
|
|
2
3
|
|
|
3
4
|
describe FCM do
|
|
4
5
|
let(:project_name) { 'test-project' }
|
|
@@ -13,27 +14,105 @@ describe FCM do
|
|
|
13
14
|
}
|
|
14
15
|
end
|
|
15
16
|
|
|
17
|
+
let(:client_email) do
|
|
18
|
+
'83315528762cf7e0-7bbcc3aad87e0083391bc7f234d487' \
|
|
19
|
+
'c8@developer.gserviceaccount.com'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
let(:client_x509_cert_url) do
|
|
23
|
+
'https://www.googleapis.com/robot/v1/metadata/x509/' \
|
|
24
|
+
'fd6b61037dd2bb8585527679" + "-7bbcc3aad87e0083391b' \
|
|
25
|
+
'c7f234d487c8%40developer.gserviceaccount.com'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
let(:large_file_name) do
|
|
29
|
+
Array.new(1021) { 'a' }.join('') + '.txt'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
let(:creds_error) do
|
|
33
|
+
FCM::InvalidCredentialError
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
let(:json_credentials) do
|
|
37
|
+
{
|
|
38
|
+
"type": 'service_account',
|
|
39
|
+
"project_id": 'example',
|
|
40
|
+
"private_key_id": 'c09c4593eee53707ca9f4208fbd6fe72b29fc7ab',
|
|
41
|
+
"private_key": OpenSSL::PKey::RSA.new(2048).to_s,
|
|
42
|
+
"client_email": client_email,
|
|
43
|
+
"client_id": 'acedc3c0a63b3562376386f0.apps.googleusercontent.com',
|
|
44
|
+
"auth_uri": 'https://accounts.google.com/o/oauth2/auth',
|
|
45
|
+
"token_uri": 'https://oauth2.googleapis.com/token',
|
|
46
|
+
"auth_provider_x509_cert_url": 'https://www.googleapis.com/oauth2/v1/certs',
|
|
47
|
+
"client_x509_cert_url": client_x509_cert_url,
|
|
48
|
+
"universe_domain": 'googleapis.com'
|
|
49
|
+
}.to_json
|
|
50
|
+
end
|
|
51
|
+
|
|
16
52
|
before do
|
|
17
53
|
allow(client).to receive(:json_key)
|
|
18
54
|
|
|
19
55
|
# Mock the Google::Auth::ServiceAccountCredentials
|
|
20
|
-
allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds)
|
|
21
|
-
and_return(double(fetch_access_token!: { 'access_token' => mock_token }))
|
|
56
|
+
allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds)
|
|
57
|
+
.and_return(double(fetch_access_token!: { 'access_token' => mock_token }))
|
|
22
58
|
end
|
|
23
59
|
|
|
24
|
-
it
|
|
60
|
+
it 'should initialize' do
|
|
25
61
|
expect { client }.not_to raise_error
|
|
26
62
|
end
|
|
27
63
|
|
|
28
64
|
describe "credentials path" do
|
|
29
|
-
it
|
|
65
|
+
it 'can be a path to a file' do
|
|
30
66
|
fcm = FCM.new("README.md")
|
|
31
67
|
expect(fcm.__send__(:json_key).class).to eq(File)
|
|
32
68
|
end
|
|
33
69
|
|
|
34
|
-
it
|
|
35
|
-
|
|
70
|
+
it 'raises an error when passed a large path' do
|
|
71
|
+
expect do
|
|
72
|
+
FCM.new(large_file_name).__send__(:json_key)
|
|
73
|
+
end.to raise_error(creds_error)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'can be an IO object' do
|
|
77
|
+
fcm = FCM.new(StringIO.new('hey'))
|
|
36
78
|
expect(fcm.__send__(:json_key).class).to eq(StringIO)
|
|
79
|
+
|
|
80
|
+
temp_file = Tempfile.new('hello_world.json')
|
|
81
|
+
temp_file.write(json_credentials)
|
|
82
|
+
fcm_with_temp_file = FCM.new(temp_file)
|
|
83
|
+
|
|
84
|
+
expect do
|
|
85
|
+
fcm_with_temp_file
|
|
86
|
+
end.not_to raise_error
|
|
87
|
+
temp_file.close
|
|
88
|
+
temp_file.unlink
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'raises an error when passed a non IO-like object' do
|
|
92
|
+
expect do
|
|
93
|
+
FCM.new(nil, '', {}).__send__(:json_key)
|
|
94
|
+
end.to raise_error(creds_error, 'credentials must be' \
|
|
95
|
+
' an IO-like object or path. You passed nil.')
|
|
96
|
+
|
|
97
|
+
expect do
|
|
98
|
+
FCM.new(json_credentials, '', {}).__send__(:json_key)
|
|
99
|
+
end.to raise_error(creds_error, 'credentials must be' \
|
|
100
|
+
' an IO-like object or path. You passed a String.')
|
|
101
|
+
|
|
102
|
+
expect do
|
|
103
|
+
FCM.new({}, '', {}).__send__(:json_key)
|
|
104
|
+
end.to raise_error(creds_error, 'credentials must be' \
|
|
105
|
+
' an IO-like object or path. You passed a Hash.')
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'raises an error when passed a non-existent credentials file path' do
|
|
109
|
+
fcm = FCM.new('spec/fake_credentials.json', '', {})
|
|
110
|
+
expect { fcm.__send__(:json_key) }.to raise_error(creds_error)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'raises an error when passed a string of a file that does not exist' do
|
|
114
|
+
fcm = FCM.new('example.txt', '', {})
|
|
115
|
+
expect { fcm.__send__(:json_key) }.to raise_error(creds_error)
|
|
37
116
|
end
|
|
38
117
|
end
|
|
39
118
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fcm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kashif Rasul
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2026-05-01 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: faraday
|