Skip to content

Commit 72b73e2

Browse files
committed
Allow to mount dashboard in production
1 parent 93859fa commit 72b73e2

21 files changed

+133
-46
lines changed

.example.env

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ PASSKIT_PRIVATE_P12_CERTIFICATE=path/to/certificate.p12
44
PASSKIT_APPLE_INTERMEDIATE_CERTIFICATE=path/to/AppleWWDRCA.cer
55
PASSKIT_APPLE_TEAM_IDENTIFIER=XXXXXXXXXX
66
PASSKIT_PASS_TYPE_IDENTIFIER=pass.com.example.pass
7+
PASSKIT_DASHBOARD_USERNAME=admin
8+
PASSKIT_DASHBOARD_PASSWORD=admin

CHANGELOG.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
## [0.4.0]
2+
3+
- Allow to use the dashboard also in production.
4+
- Allow to protect the dashboard using different strategies. Basic auth is default.
5+
- Breaking: now your Passkit dashboard is mounted under `/passkit/dashboard` instead of just `/passkit`.
6+
17
## [0.3.3]
28

3-
- Fix previews page
9+
- Fix previews page.
410

511
## [0.3.2]
612

@@ -12,4 +18,4 @@
1218

1319
## [0.1.0]
1420

15-
- Initial release
21+
- Initial release.

README.md

+24-6
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ This gem provides everything necessary to distribute Wallet Passes in pkpass for
2222
* Push notifications: this is the most wanted feature I believe. Pull requests are welcome!
2323
* Google Wallet integration: we use https://walletpasses.io/ on Android to read .pkpass format.
2424

25-
## Apple documentation
26-
27-
* [Apple Wallet Passes](https://developer.apple.com/documentation/walletpasses)
28-
* [Send Push Notifications](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns)
29-
3025
## Installation
3126

3227
Add this line to your application's Gemfile:
@@ -79,10 +74,27 @@ If you followed the installation steps and you have the ENV variables set, we ca
7974

8075
### Dashboard
8176

82-
Head to `http://localhost:3000/passkit/previews` and you will see a first `ExampleStoreCard` available for download.
77+
Head to `http://localhost:3000/passkit/dashboard/previews` and you will see a first `ExampleStoreCard` available for download.
8378
You can click on the button and you will obtain a `.pkpass` file that you can simply open or install on your phone.
8479
The dashboard has also a view for logs, and a view for emitted passes.
8580

81+
By default the dashboard is protected with basic auth. Set the credentials using these ENV variables:
82+
* `PASSKIT_DASHBOARD_USERNAME`
83+
* `PASSKIT_DASHBOARD_PASSWORD`
84+
85+
You can also change the authentication method used (see example below for Devise):
86+
87+
```ruby
88+
# config/passkit.rb
89+
90+
Passkit.configure do |config|
91+
config.authenticate_dashboard_with do
92+
warden.authenticate! scope: :user
93+
## redirect_to main_app.root_path unless warden.user.admin? # if you want to check a specific role
94+
end
95+
end
96+
```
97+
8698
### Mailer Helpers
8799

88100
If you use mailer previews, you can create the following file in `spec/mailers/previews/passkit/example_mailer_preview.rb`:
@@ -135,6 +147,12 @@ Again, check the example mailer included in the gem to see how to use it.
135147
* In case of error "The passTypeIdentifier or teamIdentifier provided may not match your certificate,
136148
or the certificate trust chain could not be verified." the certificate (p12) might be expired.
137149

150+
151+
## Apple documentation
152+
153+
* [Apple Wallet Passes](https://developer.apple.com/documentation/walletpasses)
154+
* [Send Push Notifications](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns)
155+
138156
## Development
139157

140158
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module Passkit
2+
module Dashboard
3+
class ApplicationController < ActionController::Base
4+
layout "passkit/application"
5+
6+
before_action :_authenticate_dashboard!
7+
8+
private
9+
10+
def _authenticate_dashboard!
11+
instance_eval(&Passkit.configuration.authenticate_dashboard_with)
12+
end
13+
end
14+
end
15+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Passkit
2+
module Dashboard
3+
class LogsController < ApplicationController
4+
def index
5+
@logs = Passkit::Log.order(created_at: :desc).first(100)
6+
end
7+
end
8+
end
9+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Passkit
2+
module Dashboard
3+
class PassesController < ApplicationController
4+
def index
5+
@passes = Passkit::Pass.order(created_at: :desc).includes(:devices).first(100)
6+
end
7+
end
8+
end
9+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module Passkit
2+
module Dashboard
3+
class PreviewsController < ApplicationController
4+
def index
5+
end
6+
7+
def show
8+
builder = Passkit.configuration.available_passes[params[:class_name]]
9+
send_file Factory.create_pass(params[:class_name].constantize, builder.call)
10+
end
11+
end
12+
end
13+
end

app/controllers/passkit/logs_controller.rb

-9
This file was deleted.

app/controllers/passkit/passes_controller.rb

-9
This file was deleted.

app/controllers/passkit/previews_controller.rb

-13
This file was deleted.

app/views/passkit/previews/index.html.erb app/views/passkit/dashboard/previews/index.html.erb

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<% Passkit.configuration.available_passes.each do |pass_class_name, _builder_function| %>
1616
<article>
1717
<h2><%= pass_class_name %></h2>
18-
<%= link_to 'Generate and download', preview_path(pass_class_name) %>
18+
<%= link_to 'Generate and download', dashboard_preview_path(pass_class_name) %>
1919
</article>
2020
<% end %>
2121
</main>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<nav>
2-
<%=link_to 'Logs', logs_path %>
3-
<%=link_to 'Passes', passes_path %>
4-
<%=link_to 'Passes Previews', previews_path %>
2+
<%=link_to 'Logs', dashboard_logs_path %>
3+
<%=link_to 'Passes', dashboard_passes_path %>
4+
<%=link_to 'Passes Previews', dashboard_previews_path %>
55
</nav>

config/routes.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
end
1515
end
1616

17-
unless Rails.env.production?
17+
namespace :dashboard do
1818
resources :previews, only: [:index, :show], param: :class_name
1919
resources :logs, only: [:index]
2020
resources :passes, only: [:index]

lib/passkit.rb

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class << self
1717

1818
def self.configure
1919
self.configuration ||= Configuration.new
20-
yield(configuration)
20+
yield(configuration) if block_given?
2121
end
2222

2323
class Configuration
@@ -29,6 +29,16 @@ class Configuration
2929
:apple_team_identifier,
3030
:pass_type_identifier
3131

32+
DEFAULT_AUTHENTICATION = proc do
33+
authenticate_or_request_with_http_basic("Passkit Dashboard. Login required") do |username, password|
34+
username == ENV["PASSKIT_DASHBOARD_USERNAME"] && password == ENV["PASSKIT_DASHBOARD_PASSWORD"]
35+
end
36+
end
37+
def authenticate_dashboard_with(&block)
38+
@authenticate = block if block
39+
@authenticate || DEFAULT_AUTHENTICATION
40+
end
41+
3242
def initialize
3343
@available_passes = {"Passkit::ExampleStoreCard" => -> {}}
3444
@web_service_host = ENV["PASSKIT_WEB_SERVICE_HOST"] || (raise "Please set PASSKIT_WEB_SERVICE_HOST")

lib/passkit/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module Passkit
4-
VERSION = "0.3.3"
4+
VERSION = "0.4.0"
55
end

passkit.gemspec

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Gem::Specification.new do |spec|
3737
spec.add_development_dependency "sqlite3", "~> 1.4"
3838
spec.add_development_dependency "sprockets-rails", "~> 3.0"
3939
spec.add_development_dependency "dotenv"
40+
spec.add_development_dependency "capybara"
41+
spec.add_development_dependency "selenium-webdriver"
42+
spec.add_development_dependency "webrick"
4043
spec.add_development_dependency "standard", "~> 1.9"
4144

4245
# For more information and examples about making a new gem, check out our
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Passkit.configure do |_config|
2+
end

test/rails_helper.rb

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)]
1414
ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__)
1515
require "rails/test_help"
16+
require "capybara/rails"
17+
18+
Capybara.server = :webrick
1619

1720
# Load fixtures from the engine
1821
if ActiveSupport::TestCase.respond_to?(:fixture_path=)

test/system/logs_dashboard_test.rb

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
require "rails_helper"
2+
3+
class LogsDashboardTest < ActionDispatch::SystemTestCase
4+
include Passkit::Engine.routes.url_helpers
5+
6+
setup do
7+
@routes = Passkit::Engine.routes
8+
end
9+
10+
def authorize
11+
visit "http://#{ENV["PASSKIT_DASHBOARD_USERNAME"]}:#{ENV["PASSKIT_DASHBOARD_PASSWORD"]}@#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}/passkit/dashboard/logs"
12+
end
13+
14+
test "visiting the logs dashboard" do
15+
Passkit::Log.create!(content: "[today] shit happened")
16+
Passkit::Log.create!(content: "[tomorrow] shit will happen")
17+
18+
authorize
19+
20+
visit dashboard_logs_path
21+
22+
assert_selector "h1", text: "Passkit Logs"
23+
assert_content "shit happened"
24+
assert_content "shit will happen"
25+
assert_no_content "today"
26+
assert_no_content "tomorrow"
27+
end
28+
end

0 commit comments

Comments
 (0)