Skip to content

Commit

Permalink
Allow to mount dashboard in production
Browse files Browse the repository at this point in the history
  • Loading branch information
coorasse committed Oct 20, 2022
1 parent 93859fa commit 72b73e2
Show file tree
Hide file tree
Showing 21 changed files with 133 additions and 46 deletions.
2 changes: 2 additions & 0 deletions .example.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ PASSKIT_PRIVATE_P12_CERTIFICATE=path/to/certificate.p12
PASSKIT_APPLE_INTERMEDIATE_CERTIFICATE=path/to/AppleWWDRCA.cer
PASSKIT_APPLE_TEAM_IDENTIFIER=XXXXXXXXXX
PASSKIT_PASS_TYPE_IDENTIFIER=pass.com.example.pass
PASSKIT_DASHBOARD_USERNAME=admin
PASSKIT_DASHBOARD_PASSWORD=admin
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
## [0.4.0]

- Allow to use the dashboard also in production.
- Allow to protect the dashboard using different strategies. Basic auth is default.
- Breaking: now your Passkit dashboard is mounted under `/passkit/dashboard` instead of just `/passkit`.

## [0.3.3]

- Fix previews page
- Fix previews page.

## [0.3.2]

Expand All @@ -12,4 +18,4 @@

## [0.1.0]

- Initial release
- Initial release.
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ This gem provides everything necessary to distribute Wallet Passes in pkpass for
* Push notifications: this is the most wanted feature I believe. Pull requests are welcome!
* Google Wallet integration: we use https://walletpasses.io/ on Android to read .pkpass format.

## Apple documentation

* [Apple Wallet Passes](https://developer.apple.com/documentation/walletpasses)
* [Send Push Notifications](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns)

## Installation

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

### Dashboard

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

By default the dashboard is protected with basic auth. Set the credentials using these ENV variables:
* `PASSKIT_DASHBOARD_USERNAME`
* `PASSKIT_DASHBOARD_PASSWORD`

You can also change the authentication method used (see example below for Devise):

```ruby
# config/passkit.rb

Passkit.configure do |config|
config.authenticate_dashboard_with do
warden.authenticate! scope: :user
## redirect_to main_app.root_path unless warden.user.admin? # if you want to check a specific role
end
end
```

### Mailer Helpers

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


## Apple documentation

* [Apple Wallet Passes](https://developer.apple.com/documentation/walletpasses)
* [Send Push Notifications](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns)

## Development

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.
Expand Down
15 changes: 15 additions & 0 deletions app/controllers/passkit/dashboard/application_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Passkit
module Dashboard
class ApplicationController < ActionController::Base
layout "passkit/application"

before_action :_authenticate_dashboard!

private

def _authenticate_dashboard!
instance_eval(&Passkit.configuration.authenticate_dashboard_with)
end
end
end
end
9 changes: 9 additions & 0 deletions app/controllers/passkit/dashboard/logs_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Passkit
module Dashboard
class LogsController < ApplicationController
def index
@logs = Passkit::Log.order(created_at: :desc).first(100)
end
end
end
end
9 changes: 9 additions & 0 deletions app/controllers/passkit/dashboard/passes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Passkit
module Dashboard
class PassesController < ApplicationController
def index
@passes = Passkit::Pass.order(created_at: :desc).includes(:devices).first(100)
end
end
end
end
13 changes: 13 additions & 0 deletions app/controllers/passkit/dashboard/previews_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Passkit
module Dashboard
class PreviewsController < ApplicationController
def index
end

def show
builder = Passkit.configuration.available_passes[params[:class_name]]
send_file Factory.create_pass(params[:class_name].constantize, builder.call)
end
end
end
end
9 changes: 0 additions & 9 deletions app/controllers/passkit/logs_controller.rb

This file was deleted.

9 changes: 0 additions & 9 deletions app/controllers/passkit/passes_controller.rb

This file was deleted.

13 changes: 0 additions & 13 deletions app/controllers/passkit/previews_controller.rb

This file was deleted.

File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<% Passkit.configuration.available_passes.each do |pass_class_name, _builder_function| %>
<article>
<h2><%= pass_class_name %></h2>
<%= link_to 'Generate and download', preview_path(pass_class_name) %>
<%= link_to 'Generate and download', dashboard_preview_path(pass_class_name) %>
</article>
<% end %>
</main>
6 changes: 3 additions & 3 deletions app/views/shared/passkit/_navigation.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<nav>
<%=link_to 'Logs', logs_path %>
<%=link_to 'Passes', passes_path %>
<%=link_to 'Passes Previews', previews_path %>
<%=link_to 'Logs', dashboard_logs_path %>
<%=link_to 'Passes', dashboard_passes_path %>
<%=link_to 'Passes Previews', dashboard_previews_path %>
</nav>
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
end
end

unless Rails.env.production?
namespace :dashboard do
resources :previews, only: [:index, :show], param: :class_name
resources :logs, only: [:index]
resources :passes, only: [:index]
Expand Down
12 changes: 11 additions & 1 deletion lib/passkit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class << self

def self.configure
self.configuration ||= Configuration.new
yield(configuration)
yield(configuration) if block_given?
end

class Configuration
Expand All @@ -29,6 +29,16 @@ class Configuration
:apple_team_identifier,
:pass_type_identifier

DEFAULT_AUTHENTICATION = proc do
authenticate_or_request_with_http_basic("Passkit Dashboard. Login required") do |username, password|
username == ENV["PASSKIT_DASHBOARD_USERNAME"] && password == ENV["PASSKIT_DASHBOARD_PASSWORD"]
end
end
def authenticate_dashboard_with(&block)
@authenticate = block if block
@authenticate || DEFAULT_AUTHENTICATION
end

def initialize
@available_passes = {"Passkit::ExampleStoreCard" => -> {}}
@web_service_host = ENV["PASSKIT_WEB_SERVICE_HOST"] || (raise "Please set PASSKIT_WEB_SERVICE_HOST")
Expand Down
2 changes: 1 addition & 1 deletion lib/passkit/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Passkit
VERSION = "0.3.3"
VERSION = "0.4.0"
end
3 changes: 3 additions & 0 deletions passkit.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "sqlite3", "~> 1.4"
spec.add_development_dependency "sprockets-rails", "~> 3.0"
spec.add_development_dependency "dotenv"
spec.add_development_dependency "capybara"
spec.add_development_dependency "selenium-webdriver"
spec.add_development_dependency "webrick"
spec.add_development_dependency "standard", "~> 1.9"

# For more information and examples about making a new gem, check out our
Expand Down
2 changes: 2 additions & 0 deletions test/dummy/config/initializers/passkit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Passkit.configure do |_config|
end
3 changes: 3 additions & 0 deletions test/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)]
ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__)
require "rails/test_help"
require "capybara/rails"

Capybara.server = :webrick

# Load fixtures from the engine
if ActiveSupport::TestCase.respond_to?(:fixture_path=)
Expand Down
28 changes: 28 additions & 0 deletions test/system/logs_dashboard_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require "rails_helper"

class LogsDashboardTest < ActionDispatch::SystemTestCase
include Passkit::Engine.routes.url_helpers

setup do
@routes = Passkit::Engine.routes
end

def authorize
visit "http://#{ENV["PASSKIT_DASHBOARD_USERNAME"]}:#{ENV["PASSKIT_DASHBOARD_PASSWORD"]}@#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}/passkit/dashboard/logs"
end

test "visiting the logs dashboard" do
Passkit::Log.create!(content: "[today] shit happened")
Passkit::Log.create!(content: "[tomorrow] shit will happen")

authorize

visit dashboard_logs_path

assert_selector "h1", text: "Passkit Logs"
assert_content "shit happened"
assert_content "shit will happen"
assert_no_content "today"
assert_no_content "tomorrow"
end
end

0 comments on commit 72b73e2

Please sign in to comment.