apnotic 1.7.0 → 1.7.1

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: 5ae71d53585d79f023006333f32688ff88ccf7ae92c3c639831ece42a05a2de3
4
- data.tar.gz: a4b9ba46513dfb766c303d9ba72ad99e0db0122258967414f34e7c0236aa53bc
3
+ metadata.gz: b8b5ad73f27fa8e662219ed4cbfb6f005421b5eea231db56a7c70df4f36133e2
4
+ data.tar.gz: 3fbea27f1a1e4286588cf64ec168dc3391df328eb01081a4b18e50cf893986d0
5
5
  SHA512:
6
- metadata.gz: 55d81b9a2d59f19f6725cc1f7f163769123b91bfe84a4b1517810d6c8f3f6b533a12e66c535f9337a81356957c426388eb361551075b646d6b1ac34e61145e89
7
- data.tar.gz: 6ee59aada3067fc897c259d9a8c41c6fd94c6ac68e3d1e2e7bed402aa7284bdf51fe67dad7a428f4583fe82257b85e06bf680320d3c57e8bd2d12cca8da172b1
6
+ metadata.gz: aaf851556ae88f4d70fc8142c49553379ba769d8566d172fb9b3ec2fc083ab25ade7d1835d8e821ca46f747dbe4b53514f9f0941621442d962c1c82eab2fbdf8
7
+ data.tar.gz: fa75cf207e666aa958007f08ef4f655166458acdfd3eb734bc1866b80a3ba0332dd8bb5367a924550ad885139f3e7cb9a160c11c696e2b2f463cfee27e6e43e5
@@ -0,0 +1,19 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ ruby-version: ['2.4', '2.5', '2.6', '2.7', '3.0', '3.1', '3.2']
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - name: Set up Ruby
14
+ uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: ${{ matrix.ruby-version }}
17
+ bundler-cache: true
18
+ - name: Run tests
19
+ run: bundle exec rake
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 2.7.1
1
+ ruby 3.2.1
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 Roberto Ostinelli.
3
+ Copyright (c) 2016-2023 Roberto Ostinelli.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://travis-ci.org/ostinelli/apnotic.svg?branch=master)](https://travis-ci.org/ostinelli/apnotic)
1
+ [![Build Status](https://github.com/ostinelli/apnotic/actions/workflows/ci.yml/badge.svg)](https://github.com/ostinelli/apnotic/actions/workflows/ci.yml)
2
2
  [![Code Climate](https://codeclimate.com/github/ostinelli/apnotic/badges/gpa.svg)](https://codeclimate.com/github/ostinelli/apnotic)
3
3
  [![Gem Version](https://badge.fury.io/rb/apnotic.svg)](https://badge.fury.io/rb/apnotic)
4
4
 
@@ -201,16 +201,19 @@ To create a new persistent connection:
201
201
  Apnotic::Connection.new(options)
202
202
  ```
203
203
 
204
- | Option | Description
205
- |-----|-----
206
- | :cert_path | Required. The path to a valid APNS push certificate in `.pem` or `.p12` format, or any object that responds to `:read`.
207
- | :cert_pass | Optional. The certificate's password.
208
- | :url | Optional. Defaults to https://api.push.apple.com:443.
209
- | :connect_timeout | Optional. Expressed in seconds, defaults to 30.
210
- | :proxy_addr | Optional. Proxy server. e.g. http://proxy.example.com
211
- | :proxy_port | Optional. Proxy port. e.g. 8080
212
- | :proxy_user | Optional. User name for proxy authentication. e.g. user_name
213
- | :proxy_pass | Optional. Password for proxy authentication. e.g. pass_word
204
+ | Option | Description
205
+ |------------------|------------
206
+ | :cert_path | `Required` The path to a valid APNS push certificate or any object that responds to `:read`. Supported formats: `.pem`, `.p12` (`:cert` auth), or `.p8` (`:token` auth).
207
+ | :cert_pass | `Optional` The certificate's password.
208
+ | :auth_method | `Optional` The options are `:cert` or `:token`. Defaults to `:cert`.
209
+ | :team_id | `Required for :token auth` Team ID from [Membership Details](https://developer.apple.com/account/#!/membership/).
210
+ | :key_id | `Required for :token auth` ID from [Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources/authkeys).
211
+ | :url | `Optional` Defaults to https://api.push.apple.com:443.
212
+ | :connect_timeout | `Optional` Expressed in seconds, defaults to 30.
213
+ | :proxy_addr | `Optional` Proxy server. e.g. http://proxy.example.com
214
+ | :proxy_port | `Optional` Proxy port. e.g. 8080
215
+ | :proxy_user | `Optional` User name for proxy authentication. e.g. user_name
216
+ | :proxy_pass | `Optional` Password for proxy authentication. e.g. pass_word
214
217
 
215
218
  Note that since `:cert_path` can be any object that responds to `:read`, it is possible to pass in a certificate string directly by wrapping it up in a `StringIO` object:
216
219
 
@@ -224,47 +227,47 @@ It is also possible to create a connection that points to the Apple Development
224
227
  Apnotic::Connection.development(options)
225
228
  ```
226
229
 
227
- > The concepts of PRODUCTION and DEVELOPMENT are different from what they used to be in previous specifications. Anything built directly from XCode and loaded on your phone will have the app generate DEVELOPMENT tokens, while everything else (TestFlight, Apple Store, HockeyApp, ...) will be considered as PRODUCTION environment.
230
+ > The concepts of PRODUCTION and DEVELOPMENT are different from what they used to be in previous specifications. Anything built directly from Xcode and loaded on your phone will have the app generate DEVELOPMENT tokens, while everything else (TestFlight, Apple Store, HockeyApp, ...) will be considered as PRODUCTION environment.
228
231
 
229
232
  #### Methods
230
233
 
231
- * **cert_path** → **`string`**
234
+ - **cert_path** → **`string`**
232
235
 
233
- Returns the path to the certificate.
236
+ Returns the path to the certificate.
234
237
 
235
- * **on(event, &block)**
238
+ - **on(event, &block)**
236
239
 
237
- Allows to set a callback for the connection. The only available event is `:error`, which allows to set a callback when an error is raised at socket level, hence in the underlying socket thread.
240
+ Allows to set a callback for the connection. The only available event is `:error`, which allows to set a callback when an error is raised at socket level, hence in the underlying socket thread.
238
241
 
239
- ```ruby
240
- connection.on(:error) { |exception| puts "Exception has been raised: #{exception}" }
241
- ```
242
+ ```ruby
243
+ connection.on(:error) { |exception| puts "Exception has been raised: #{exception}" }
244
+ ```
242
245
 
243
- > If the `:error` callback is not set, the underlying socket thread may raise an error in the main thread at unexpected execution times.
246
+ > If the `:error` callback is not set, the underlying socket thread may raise an error in the main thread at unexpected execution times.
244
247
 
245
- * **url** → **`URL`**
248
+ - **url** → **`URL`**
246
249
 
247
- Returns the URL of the APNS endpoint.
250
+ Returns the URL of the APNS endpoint.
248
251
 
249
252
  ##### Blocking calls
250
253
 
251
- * **push(notification, timeout: 30)** → **`Apnotic::Response` or `nil`**
254
+ - **push(notification, timeout: 30)** → **`Apnotic::Response` or `nil`**
252
255
 
253
- Sends a notification. Returns `nil` in case a timeout occurs.
256
+ Sends a notification. Returns `nil` in case a timeout occurs.
254
257
 
255
258
  ##### Non-blocking calls
256
259
 
257
- * **prepare_push(notification)** → **`Apnotic::Push`**
260
+ - **prepare_push(notification)** → **`Apnotic::Push`**
258
261
 
259
- Prepares an async push.
262
+ Prepares an async push.
260
263
 
261
- ```ruby
262
- push = client.prepare_push(notification)
263
- ```
264
+ ```ruby
265
+ push = client.prepare_push(notification)
266
+ ```
264
267
 
265
- * **push_async(push)**
268
+ - **push_async(push)**
266
269
 
267
- Sends the push asynchronously.
270
+ Sends the push asynchronously.
268
271
 
269
272
 
270
273
  ### `Apnotic::ConnectionPool`
@@ -318,10 +321,15 @@ These are all Accessor attributes.
318
321
  | `target_content_id` | "
319
322
  | `interruption_level` | Refer to [Payload Key Reference](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943363) for details. iOS 15+
320
323
  | `relevance_score` | Refer to [Payload Key Reference](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943363) for details. iOS 15+
324
+ | `stale_date` | Refer to [Payload Key Reference](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943363) for details. iOS 16+
325
+ | `content_state` | Refer to [Payload Key Reference](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943363) for details. iOS 16+
326
+ | `timestamp` | Refer to [Payload Key Reference](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943363) for details. iOS 16+
327
+ | `event` | Refer to [Payload Key Reference](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification#2943363) for details. iOS 16+
321
328
  | `apns_id` | Refer to [Communicating with APNs](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html) for details.
322
329
  | `expiration` | "
323
330
  | `priority` | "
324
331
  | `topic` | "
332
+ | `push_type` | Refer to [Sending Notification Requests to APNs](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns) for details, defaults to alert or background (when content-availabe key is set to 1)
325
333
  | `url_args` | Values for [Safari push notifications](https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html#//apple_ref/doc/uid/TP40013225-CH3-SW12).
326
334
  | `mutable_content` | Key for [UNNotificationServiceExtension](https://developer.apple.com/reference/usernotifications/unnotificationserviceextension).
327
335
  | `apns_collapse_id` | Key for setting the identification of a notification and allowing for the updating of the content of that notification in a subsequent push. More information avaible in [WWDC 2016 - Session 707 Introduction to Notifications](https://developer.apple.com/videos/play/wwdc2016/707/?time=1134). iOS 10+
@@ -355,21 +363,21 @@ The response to a call to `connection.push`.
355
363
 
356
364
  #### Methods
357
365
 
358
- * **body** → **`hash` or `string`**
366
+ - **body** → **`hash` or `string`**
359
367
 
360
- Returns the body of the response in Hash format if a valid JSON was returned, otherwise just the RAW body.
368
+ Returns the body of the response in Hash format if a valid JSON was returned, otherwise just the RAW body.
361
369
 
362
- * **headers** → **`hash`**
370
+ - **headers** → **`hash`**
363
371
 
364
- Returns a Hash containing the Headers of the response.
372
+ Returns a Hash containing the Headers of the response.
365
373
 
366
- * **ok?** → **`boolean`**
374
+ - **ok?** → **`boolean`**
367
375
 
368
- Returns if the push was successful.
376
+ Returns if the push was successful.
369
377
 
370
- * **status** → **`string`**
378
+ - **status** → **`string`**
371
379
 
372
- Returns the status code.
380
+ Returns the status code.
373
381
 
374
382
 
375
383
  ### `Apnotic::Push`
@@ -377,21 +385,21 @@ The push object to be sent in an async call.
377
385
 
378
386
  #### Methods
379
387
 
380
- * **http2_request** → **`NetHttp2::Request`**
388
+ - **http2_request** → **`NetHttp2::Request`**
381
389
 
382
- Returns the HTTP/2 request of the push.
390
+ Returns the HTTP/2 request of the push.
383
391
 
384
- * **on(event, &block)**
392
+ - **on(event, &block)**
385
393
 
386
- Allows to set a callback for the request. Available events are:
394
+ Allows to set a callback for the request. Available events are:
387
395
 
388
- * `:response`: triggered when a response is fully received (called once).
396
+ `:response`: triggered when a response is fully received (called once).
389
397
 
390
- Even if Apnotic is thread-safe, the async callbacks will be executed in a different thread, so ensure that your code in the callbacks is thread-safe.
398
+ Even if Apnotic is thread-safe, the async callbacks will be executed in a different thread, so ensure that your code in the callbacks is thread-safe.
391
399
 
392
- ```ruby
393
- push.on(:response) { |response| p response.headers }
394
- ```
400
+ ```ruby
401
+ push.on(:response) { |response| p response.headers }
402
+ ```
395
403
 
396
404
  ## Getting Your APNs Certificate
397
405
 
data/apnotic.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ["roberto@ostinelli.net"]
12
12
  spec.summary = %q{Apnotic is an Apple Push Notification gem able to provide instant feedback.}
13
13
  spec.homepage = "http://github.com/ostinelli/apnotic"
14
- spec.required_ruby_version = '>=2.1.0'
14
+ spec.required_ruby_version = '>=2.4.0'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
17
  spec.bindir = "exe"
@@ -11,7 +11,8 @@ module Apnotic
11
11
  :priority,
12
12
  :topic,
13
13
  :apns_collapse_id,
14
- :authorization
14
+ :authorization,
15
+ :push_type
15
16
 
16
17
  def initialize(token)
17
18
  @token = token
@@ -114,6 +114,7 @@ module Apnotic
114
114
  def build_ssl_context
115
115
  @build_ssl_context ||= begin
116
116
  ctx = OpenSSL::SSL::SSLContext.new
117
+ ctx.security_level = 1 if development? && ctx.respond_to?(:security_level)
117
118
  begin
118
119
  p12 = OpenSSL::PKCS12.new(certificate, @cert_pass)
119
120
  ctx.key = p12.key
@@ -146,5 +147,8 @@ module Apnotic
146
147
  @provider_token_cache.call
147
148
  end
148
149
 
150
+ def development?
151
+ url == APPLE_DEVELOPMENT_SERVER_URL
152
+ end
149
153
  end
150
154
  end
@@ -17,12 +17,16 @@ module Apnotic
17
17
  private
18
18
 
19
19
  def expired?
20
- Time.now - @cached_at >= @ttl
20
+ now - @cached_at >= @ttl
21
21
  end
22
22
 
23
23
  def new_value
24
- @cached_at = Time.now
24
+ @cached_at = now
25
25
  @cached_value = @instance.send(@method)
26
26
  end
27
+
28
+ def now
29
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
30
+ end
27
31
  end
28
32
  end
@@ -5,7 +5,8 @@ module Apnotic
5
5
  class Notification < AbstractNotification
6
6
  attr_accessor :alert, :badge, :sound, :content_available, :category, :custom_payload, :url_args, :mutable_content, :thread_id
7
7
  attr_accessor :target_content_id, :interruption_level, :relevance_score
8
-
8
+ attr_accessor :stale_date, :content_state, :timestamp, :event
9
+
9
10
  def background_notification?
10
11
  aps.count == 1 && aps.key?('content-available') && aps['content-available'] == 1
11
12
  end
@@ -25,6 +26,10 @@ module Apnotic
25
26
  result.merge!('target-content-id' => target_content_id) if target_content_id
26
27
  result.merge!('interruption-level' => interruption_level) if interruption_level
27
28
  result.merge!('relevance-score' => relevance_score) if relevance_score
29
+ result.merge!('stale-date' => stale_date) if stale_date
30
+ result.merge!('content-state' => content_state) if content_state
31
+ result.merge!('timestamp' => timestamp) if timestamp
32
+ result.merge!('event' => event) if event
28
33
  end
29
34
  end
30
35
 
@@ -26,7 +26,7 @@ module Apnotic
26
26
  def payload
27
27
  JSON.generate({
28
28
  iss: @team_id,
29
- iat: Time.now.to_i
29
+ iat: Time.now.utc.to_i
30
30
  })
31
31
  end
32
32
 
@@ -16,7 +16,7 @@ module Apnotic
16
16
  h.merge!('apns-id' => notification.apns_id) if notification.apns_id
17
17
  h.merge!('apns-expiration' => notification.expiration) if notification.expiration
18
18
  h.merge!('apns-priority' => notification.priority) if notification.priority
19
- h.merge!('apns-push-type' => notification.background_notification? ? 'background' : 'alert' )
19
+ h.merge!('apns-push-type' => notification.push_type || (notification.background_notification? ? 'background' : 'alert'))
20
20
  h.merge!('apns-topic' => notification.topic) if notification.topic
21
21
  h.merge!('apns-collapse-id' => notification.apns_collapse_id) if notification.apns_collapse_id
22
22
  h.merge!('authorization' => notification.authorization_header) if notification.authorization_header
@@ -1,3 +1,3 @@
1
1
  module Apnotic
2
- VERSION = '1.7.0'.freeze
2
+ VERSION = '1.7.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apnotic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Ostinelli
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-22 00:00:00.000000000 Z
11
+ date: 2023-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http2
@@ -93,10 +93,10 @@ executables: []
93
93
  extensions: []
94
94
  extra_rdoc_files: []
95
95
  files:
96
+ - ".github/workflows/ci.yml"
96
97
  - ".gitignore"
97
98
  - ".rspec"
98
99
  - ".tool-versions"
99
- - ".travis.yml"
100
100
  - Gemfile
101
101
  - LICENSE.md
102
102
  - README.md
@@ -128,14 +128,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: 2.1.0
131
+ version: 2.4.0
132
132
  required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  requirements:
134
134
  - - ">="
135
135
  - !ruby/object:Gem::Version
136
136
  version: '0'
137
137
  requirements: []
138
- rubygems_version: 3.1.2
138
+ rubygems_version: 3.4.6
139
139
  signing_key:
140
140
  specification_version: 4
141
141
  summary: Apnotic is an Apple Push Notification gem able to provide instant feedback.
data/.travis.yml DELETED
@@ -1,14 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.3
4
- - 2.4
5
- - 2.5
6
- - 2.6
7
- - 2.7
8
-
9
- branches:
10
- only:
11
- - master
12
-
13
- before_install:
14
- - gem install bundler