Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discourage developers to check in their p8 file #348

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
### Unreleased

* Support html safe translations for Rails 7+
* iOS notifications now default to retrieving the APNS .p8 key from Rails credentials.

### 1.6.3

Expand Down
40 changes: 18 additions & 22 deletions docs/delivery_methods/ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Send Apple Push Notifications with HTTP2 using the `apnotic` gem. The benefit of
bundle add "apnotic"
```

## Apple Push Notification Service (APNS) Authentication
## Apple Push Notification Service (APNs) Authentication

Token-based authentication is used for APNS.
Token-based authentication is used for APNs.
* A single key can be used for every app in your developer account.
* Token authentication never expires, unlike certificate authentication which must be renewed annually.

Expand All @@ -28,26 +28,14 @@ With custom configuration:

```ruby
class CommentNotification
deliver_by :ios, format: :ios_format, cert_path: :ios_cert_path, key_id: :ios_key_id, team_id: :ios_team_id, pool_size: 5
deliver_by :ios, format: :ios_format, development: Rails.env.local?, pool_size: 5

# Customize notification
# See https://github.com/ostinelli/apnotic#apnoticnotification
def ios_format(apn)
apn.alert = "Hello world"
apn.custom_payload = { url: root_url }
end

def ios_cert_path
Rails.root.join("config/certs/ios/apns.p8")
end

def ios_key_id
Rails.application.credentials.dig(:ios, :key_id)
end

def ios_team_id
Rails.application.credentials.dig(:ios, :team_id)
end
end
```

Expand All @@ -63,23 +51,31 @@ end

The APN bundle identifier

* `cert_path: Rails.root.join("config/certs/ios/apns.p8")` - *Optional*
* `apns_key: Rails.application.credentials.dig(:ios, :apns_key)` - *Optional*

Your APNs p8 certificate

Copy paste the contents of your private key (.p8 file) in your credentials, like so.

The location of your APNs p8 certificate.
This can also accept a StringIO object `StringIO.new("p8 file content as string")`.
As well as a File object `File.open("path/to/p8.file")`.
```text
ios:
apns_key: |-
-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_CONTENTS_GO_HERE
-----END PRIVATE KEY-----
```

* `key_id: Rails.application.credentials.dig(:ios, :key_id)` - *Optional*

Your APN Key ID
Your APNs Key ID

If nothing passed, we'll default to `Rails.application.credentials.dig(:ios, :key_id)`
If a String is passed, we'll use that as the key ID.
If a Symbol is passed, we'll call the matching method and you can return the Key ID.

* `team_id: Rails.application.credentials.dig(:ios, :team_id)` - *Optional*

Your APN Team ID
Your APNs Team ID

If nothing passed, we'll default to `Rails.application.credentials.dig(:ios, :team_id)`
If a String is passed, we'll use that as the team ID.
Expand All @@ -91,7 +87,7 @@ end

* `development: false` - *Optional*

Set this to true to use the APNS sandbox environment for sending notifications. This is required when running the app to your device via Xcode. Running the app via TestFlight or the App Store should not use development.
Set this to true to use the APNs sandbox environment for sending notifications. This is required when running the app to your device via Xcode. Running the app via TestFlight or the App Store should not use development.

## Gathering Notification Tokens

Expand Down
19 changes: 5 additions & 14 deletions lib/noticed/delivery_methods/ios.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def deliver
raise ArgumentError, "bundle_identifier is missing" if bundle_identifier.blank?
raise ArgumentError, "key_id is missing" if key_id.blank?
raise ArgumentError, "team_id is missing" if team_id.blank?
raise ArgumentError, "Could not find APN cert at '#{cert_path}'" unless valid_cert_path?
raise ArgumentError, "apns_key is missing" if apns_key.blank?

device_tokens.each do |device_token|
connection_pool.with do |connection|
Expand Down Expand Up @@ -88,7 +88,7 @@ def new_connection_pool
def connection_pool_options
{
auth_method: :token,
cert_path: cert_path,
cert_path: StringIO.new(apns_key),
key_id: key_id,
team_id: team_id
}
Expand All @@ -106,15 +106,15 @@ def bundle_identifier
end
end

def cert_path
option = options[:cert_path]
def apns_key
option = options[:apns_key]
case option
when String
option
when Symbol
notification.send(option)
else
Rails.root.join("config/certs/ios/apns.p8")
Rails.application.credentials.dig(:ios, :apns_key)
end
end

Expand Down Expand Up @@ -152,15 +152,6 @@ def development?
end
end

def valid_cert_path?
case cert_path
when File, StringIO
cert_path.size > 0
else
File.exist?(cert_path)
end
end

def pool_options
{
size: options.fetch(:pool_size, 5)
Expand Down
4 changes: 2 additions & 2 deletions test/delivery_methods/ios_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class IosTest < ActiveSupport::TestCase
assert_equal "team_id is missing", exception.message
end

test "raises error when cert missing" do
test "raises error when apns_key is missing" do
exception = assert_raises ArgumentError do
Noticed::DeliveryMethods::Ios.new.perform(
notification_class: "IosExample",
Expand All @@ -60,7 +60,7 @@ class IosTest < ActiveSupport::TestCase
)
end

assert_match "Could not find APN cert at", exception.message
assert_match "apns_key is missing", exception.message
end

test "raises error when ios_device_tokens method is missing" do
Expand Down
Loading