letter_opener_web 1.4.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/brakeman-analysis.yml +46 -0
  3. data/.github/workflows/main.yml +34 -0
  4. data/.github/workflows/release-gem.yml +32 -0
  5. data/.rspec +1 -1
  6. data/.rubocop.yml +4 -13
  7. data/.rubocop_todo.yml +19 -0
  8. data/CHANGELOG.md +13 -0
  9. data/LICENSE.txt +1 -1
  10. data/README.md +29 -20
  11. data/app/controllers/letter_opener_web/application_controller.rb +1 -0
  12. data/app/controllers/letter_opener_web/letters_controller.rb +7 -4
  13. data/app/models/letter_opener_web/letter.rb +22 -1
  14. data/app/views/layouts/letter_opener_web/_javascripts.html.erb +26 -559
  15. data/app/views/layouts/letter_opener_web/_styles.html.erb +3 -63
  16. data/app/views/layouts/letter_opener_web/js/_favcount.html.erb +104 -0
  17. data/app/views/layouts/letter_opener_web/js/_jquery.html.erb +7 -0
  18. data/app/views/layouts/letter_opener_web/letters.html.erb +4 -3
  19. data/app/views/layouts/letter_opener_web/styles/_bootstrap.html.erb +9 -0
  20. data/app/views/layouts/letter_opener_web/styles/_icon.html.erb +2 -0
  21. data/app/views/layouts/letter_opener_web/styles/_letters.html.erb +70 -0
  22. data/app/views/letter_opener_web/letters/_item.html.erb +10 -0
  23. data/app/views/letter_opener_web/letters/index.html.erb +11 -46
  24. data/config/routes.rb +5 -5
  25. data/letter_opener_web.gemspec +11 -8
  26. data/lib/letter_opener_web/version.rb +1 -1
  27. data/lib/letter_opener_web.rb +1 -0
  28. data/spec/controllers/letter_opener_web/letters_controller_spec.rb +4 -4
  29. data/spec/dummy/app/assets/config/manifest.js +0 -2
  30. data/spec/dummy/app/assets/stylesheets/application.css +0 -16
  31. data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
  32. data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
  33. data/spec/dummy/app/controllers/application_controller.rb +0 -1
  34. data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +2 -0
  35. data/spec/dummy/app/jobs/application_job.rb +9 -0
  36. data/spec/dummy/app/models/application_record.rb +5 -0
  37. data/spec/dummy/app/models/concerns/.keep +0 -0
  38. data/spec/dummy/app/views/layouts/application.html.erb +4 -7
  39. data/spec/dummy/bin/rails +2 -4
  40. data/spec/dummy/bin/rake +2 -4
  41. data/spec/dummy/bin/setup +7 -10
  42. data/spec/dummy/config/application.rb +21 -7
  43. data/spec/dummy/config/environments/development.rb +44 -6
  44. data/spec/dummy/config/environments/production.rb +51 -14
  45. data/spec/dummy/config/environments/test.rb +30 -6
  46. data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -4
  47. data/spec/dummy/config/initializers/assets.rb +5 -5
  48. data/spec/dummy/config/initializers/backtrace_silencers.rb +5 -3
  49. data/spec/dummy/config/initializers/content_security_policy.rb +29 -0
  50. data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
  51. data/spec/dummy/config/initializers/permissions_policy.rb +12 -0
  52. data/spec/dummy/config/locales/en.yml +11 -1
  53. data/spec/dummy/config/puma.rb +18 -22
  54. data/spec/dummy/config/routes.rb +1 -4
  55. data/spec/dummy/config.ru +1 -0
  56. data/spec/dummy/public/404.html +6 -6
  57. data/spec/dummy/public/422.html +6 -6
  58. data/spec/dummy/public/500.html +6 -6
  59. data/spec/dummy/storage/.keep +0 -0
  60. data/spec/letter_opener_web_spec.rb +2 -2
  61. data/spec/models/letter_opener_web/letter_spec.rb +48 -14
  62. metadata +87 -42
  63. data/.travis.yml +0 -23
  64. data/spec/dummy/app/controllers/home_controller.rb +0 -10
  65. data/spec/dummy/app/mailers/contact_mailer.rb +0 -14
  66. data/spec/dummy/app/views/contact_mailer/new_message.html.erb +0 -21
  67. data/spec/dummy/app/views/contact_mailer/new_message.text.erb +0 -3
  68. data/spec/dummy/app/views/home/index.html.erb +0 -50
  69. data/spec/dummy/bin/bundle +0 -5
  70. data/spec/dummy/bin/update +0 -31
  71. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
  72. data/spec/dummy/config/initializers/session_store.rb +0 -5
  73. data/spec/dummy/config/secrets.yml +0 -22
  74. data/spec/dummy/config/spring.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf8f22bcc360d6d8da5a1e462a24faa5d8dfe4589a7cad91bebe688a06a1001c
4
- data.tar.gz: f9cc899aee871f4d68ec12390be6470d62fba0b85123ecb38ae5a11e98899f42
3
+ metadata.gz: 3b31a75a1e88a4e79a2c79ef92da951522caf6ffbd7ab684b53a46b0982efd85
4
+ data.tar.gz: a4f6a87162bdcc3d28632f192f97aaba812939697c08c86904a36aa4ce9b6da8
5
5
  SHA512:
6
- metadata.gz: 79ecd487c5042e2acfd3627a38ee8379e8a372c06a64aaa8c01be30cddf01b123dc23ec80dafe1cc94f7924698ef80304066c1b06a5d776f8304a547ddaa11be
7
- data.tar.gz: c5fb0b7be26b025400c346a8d4850e834e890f578cfd6a849fd949d1b12c93999aaefef65c1e641e8a6fca2a25e866467f6f223527ed84cea94fb4022b07984e
6
+ metadata.gz: 7c4e1575132e8e895cdd5fdc881516396af19c3efabde95276727c39f106df67d7f0237ae009264f7b31dce15cfd8d83874f0f098fa1145ed2c5d2f4a77fd2d8
7
+ data.tar.gz: d3b2d72727adfe59f1c3468d832df6522d7792ee1d7e555a205ec2720a2c34e3ff7689cb38016e0561b89ed04ab94e364cdfca68235c4c0f9c1c1a630db140c5
@@ -0,0 +1,46 @@
1
+ # This workflow integrates Brakeman with GitHub's Code Scanning feature
2
+ # Brakeman is a static analysis security vulnerability scanner for Ruby on Rails applications
3
+
4
+ name: Brakeman Scan
5
+
6
+ on:
7
+ push:
8
+ branches: [ master ]
9
+ pull_request:
10
+ # The branches below must be a subset of the branches above
11
+ branches: [ master ]
12
+ schedule:
13
+ - cron: '21 4 * * 4'
14
+
15
+ jobs:
16
+ brakeman-scan:
17
+ name: Brakeman Scan
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ # Checkout the repository to the GitHub Actions runner
21
+ - name: Checkout
22
+ uses: actions/checkout@v2
23
+
24
+ # Customize the ruby version depending on your needs
25
+ - name: Setup Ruby
26
+ uses: actions/setup-ruby@v1
27
+ with:
28
+ ruby-version: '2.7'
29
+
30
+ - name: Setup Brakeman
31
+ env:
32
+ BRAKEMAN_VERSION: '4.10' # SARIF support is provided in Brakeman version 4.10+
33
+ run: |
34
+ gem install brakeman --version $BRAKEMAN_VERSION
35
+
36
+ # Execute Brakeman CLI and generate a SARIF output with the security issues identified during the analysis
37
+ - name: Scan
38
+ continue-on-error: true
39
+ run: |
40
+ brakeman -f sarif -o output.sarif.json .
41
+
42
+ # Upload the SARIF file generated in the previous step
43
+ - name: Upload SARIF
44
+ uses: github/codeql-action/upload-sarif@v1
45
+ with:
46
+ sarif_file: output.sarif.json
@@ -0,0 +1,34 @@
1
+ name: Run tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master, next ]
8
+
9
+ jobs:
10
+ test:
11
+
12
+ runs-on: ubuntu-latest
13
+
14
+ strategy:
15
+ matrix:
16
+ ruby-version: [2.7, 3.0]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+
21
+ - name: Set up Ruby ${{ matrix.ruby-version }}
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby-version }}
25
+ bundler-cache: true
26
+
27
+ - name: Install dependencies
28
+ run: bundle install
29
+
30
+ - name: Run tests
31
+ run: bundle exec rake
32
+
33
+ - name: Build gem
34
+ run: bundle exec rake build
@@ -0,0 +1,32 @@
1
+ name: Release gem
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ build:
10
+ name: Build + Publish
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+
16
+ - name: Set up Ruby 3.0
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: 3.0
20
+
21
+ - run: bundle install
22
+
23
+ - name: Publish to RubyGems
24
+ run: |
25
+ mkdir -p $HOME/.gem
26
+ touch $HOME/.gem/credentials
27
+ chmod 0600 $HOME/.gem/credentials
28
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
29
+ bundle exec rake build
30
+ gem push pkg/*.gem
31
+ env:
32
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
data/.rspec CHANGED
@@ -1,4 +1,4 @@
1
1
  --order rand
2
2
  --color
3
3
  --format progress
4
- --require spec_helper
4
+ --require rails_helper
data/.rubocop.yml CHANGED
@@ -1,23 +1,14 @@
1
1
  ---
2
+ inherit_from: .rubocop_todo.yml
3
+
2
4
  AllCops:
3
- TargetRubyVersion: 2.5
5
+ NewCops: enable
6
+ TargetRubyVersion: 2.7
4
7
  Exclude:
5
8
  - "spec/dummy/bin/**/*"
6
9
  - "tmp/**/*"
7
10
  - "vendor/**/*"
8
11
 
9
- Layout/HeredocIndentation:
10
- Enabled: false
11
-
12
- Style/Documentation:
13
- Enabled: false
14
-
15
- Style/ClassAndModuleChildren:
16
- EnforcedStyle: nested
17
-
18
- Style/SingleLineBlockParams:
19
- Enabled: false
20
-
21
12
  Metrics/BlockLength:
22
13
  Exclude:
23
14
  - spec/**/*_spec.rb
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,19 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2021-10-02 14:42:36 UTC using RuboCop version 1.22.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 5
10
+ # Configuration parameters: AllowedConstants.
11
+ Style/Documentation:
12
+ Exclude:
13
+ - 'spec/**/*'
14
+ - 'test/**/*'
15
+ - 'app/controllers/letter_opener_web/letters_controller.rb'
16
+ - 'app/models/letter_opener_web/letter.rb'
17
+ - 'lib/letter_opener_web.rb'
18
+ - 'lib/letter_opener_web/delivery_method.rb'
19
+ - 'lib/letter_opener_web/engine.rb'
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [v2.0.0](https://github.com/fgrehm/letter_opener_web/compare/v1.4.1...v2.0.0)
2
+
3
+ - Require Rails >= 5.2, run tests against Rails 6.1 [#113](https://github.com/fgrehm/letter_opener_web/pull/113)
4
+ - Inline CSS and Javascript, to avoid dependency on asset pipeline [#113](https://github.com/fgrehm/letter_opener_web/pull/113)
5
+ - Upgrade to Bootstrap 5.1.1 [#113](https://github.com/fgrehm/letter_opener_web/pull/113)
6
+ - Add rexml gem into dependency for Ruby 3.0 [#106](https://github.com/fgrehm/letter_opener_web/pull/106)
7
+ - Add routes for Rails API mode [#69](https://github.com/fgrehm/letter_opener_web/pull/69)
8
+ - Prevent name conflict with `Letter` class [#108](https://github.com/fgrehm/letter_opener_web/pull/108)
9
+ - Add Rails' built-in CSRF protection [#111](https://github.com/fgrehm/letter_opener_web/pull/111)
10
+ - Add Rails' CSP nonce to the script tag [#112](https://github.com/fgrehm/letter_opener_web/pull/112)
11
+ - Update dev dependencies [#113](https://github.com/fgrehm/letter_opener_web/pull/113)
12
+ - Switched to using GitHub actions as CI for the project [#113](https://github.com/fgrehm/letter_opener_web/pull/113)
13
+
1
14
  ## [1.4.1](https://github.com/fgrehm/letter_opener_web/compare/v1.4.0...v1.4.1) (Oct 5, 2021)
2
15
 
3
16
  - Ensure letter is within letters base path [#110](https://github.com/fgrehm/letter_opener_web/pull/110)
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2018 Fabio Rehm
1
+ Copyright (c) 2013-2021 Fabio Rehm
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # letter_opener_web
2
2
 
3
- [![Build Status](https://travis-ci.org/fgrehm/letter_opener_web.svg?branch=master)](https://travis-ci.org/fgrehm/letter_opener_web)
3
+ ![Build Status](https://github.com/fgrehm/letter_opener_web/actions/workflows/main.yml/badge.svg)
4
4
  [![Gem Version](https://badge.fury.io/rb/letter_opener_web.svg)](http://badge.fury.io/rb/letter_opener_web)
5
5
  [![Code Climate](https://codeclimate.com/github/fgrehm/letter_opener_web.svg)](https://codeclimate.com/github/fgrehm/letter_opener_web)
6
6
 
@@ -15,7 +15,7 @@ First add the gem to your development environment and run the `bundle` command t
15
15
 
16
16
  ```ruby
17
17
  group :development do
18
- gem 'letter_opener_web', '~> 1.0'
18
+ gem 'letter_opener_web', '~> 2.0'
19
19
  end
20
20
  ```
21
21
 
@@ -33,8 +33,9 @@ And make sure you have [`:letter_opener` delivery method](https://github.com/rya
33
33
  configured for your app. Then visit `http://localhost:3000/letter_opener` after
34
34
  sending an email and have fun.
35
35
 
36
- If you are running the app from a [Vagrant](http://vagrantup.com) machine, you
37
- might want to skip `letter_opener`'s `launchy` calls and avoid messages like these:
36
+ If you are running the app from a [Vagrant](http://vagrantup.com) machine or Docker
37
+ container, you might want to skip `letter_opener`'s `launchy` calls and avoid messages
38
+ like these:
38
39
 
39
40
  ```terminal
40
41
  12:33:42 web.1 | Failure in opening /vagrant/tmp/letter_opener/1358825621_ba83a22/rich.html
@@ -43,19 +44,16 @@ environment variable LAUNCHY_DEBUG=true or the '-d' commandline option and file
43
44
  https://github.com/copiousfreetime/launchy/issues/new
44
45
  ```
45
46
 
46
- In that case (or if you just want to browse mails using the web interface), you
47
- can set `:letter_opener_web` as your delivery method on your
48
- `config/environments/development.rb`:
47
+ In that case (or if you really just want to browse mails using the web interface and
48
+ don't care about opening emails automatically), you can set `:letter_opener_web` as
49
+ your delivery method on your `config/environments/development.rb`:
49
50
 
50
51
  ```ruby
51
52
  config.action_mailer.delivery_method = :letter_opener_web
52
-
53
- # If not everyone on the team is using vagrant
54
- config.action_mailer.delivery_method = ENV['USER'] == 'vagrant' ? :letter_opener_web : :letter_opener
55
53
  ```
56
54
 
57
- If you're using `:letter_opener_web` as your delivery method, you can change the location of the letters by adding the
58
- following to an initializer (or in development.rb):
55
+ If you're using `:letter_opener_web` as your delivery method, you can change the location of
56
+ the letters by adding the following to an initializer (or in development.rb):
59
57
 
60
58
  ```ruby
61
59
  LetterOpenerWeb.configure do |config|
@@ -63,11 +61,14 @@ LetterOpenerWeb.configure do |config|
63
61
  end
64
62
  ```
65
63
 
66
- ## Usage on Heroku
64
+ ## Usage on pre-production environments
65
+
66
+ Some people use this gem on staging / pre-production environments to avoid having real emails
67
+ being sent out. To set that up you'll need to:
67
68
 
68
- Some people use this gem on staging environments on Heroku and to set that up
69
- is just a matter of moving the gem out of the `development` group and enabling
70
- the route for all environments on your `routes.rb`.
69
+ 1. Move the gem out of the `development` group in your `Gemfile`
70
+ 2. Set `config.action_mailer.delivery_method` on the appropriate `config/environments/<env>.rb`
71
+ 3. Enable the route for the environments on your `routes.rb`.
71
72
 
72
73
  In other words, your `Gemfile` will have:
73
74
 
@@ -79,20 +80,28 @@ And your `routes.rb`:
79
80
 
80
81
  ```ruby
81
82
  Your::Application.routes.draw do
82
- mount LetterOpenerWeb::Engine, at: "/letter_opener"
83
+ # If you have a dedicated config/environments/staging.rb
84
+ mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.staging?
85
+
86
+ # If you use RAILS_ENV=production in staging environments, you'll need another
87
+ # way to disable it in "real production"
88
+ mount LetterOpenerWeb::Engine, at: "/letter_opener" unless ENV["PRODUCTION_FOR_REAL"]
83
89
  end
84
90
  ```
85
91
 
86
92
  You might also want to have a look at the sources for the [demo](http://letter-opener-web.herokuapp.com)
87
93
  available at https://github.com/fgrehm/letter_opener_web_demo.
88
94
 
89
- **NOTICE: Using this gem on Heroku will only work if your app has just one Dyno and does not send emails from background jobs. For updates on this matter please subscribe to [GH-35](https://github.com/fgrehm/letter_opener_web/issues/35)**
95
+ **NOTICE: Using this gem on Heroku will only work if your app has just one Dyno
96
+ and does not send emails from background jobs. For updates on this matter please
97
+ subscribe to [GH-35](https://github.com/fgrehm/letter_opener_web/issues/35)**
90
98
 
91
99
  ## Acknowledgements
92
100
 
93
101
  Special thanks to [@alexrothenberg](https://github.com/alexrothenberg) for some
94
- ideas on [this pull request](https://github.com/ryanb/letter_opener/pull/12).
95
-
102
+ ideas on [this pull request](https://github.com/ryanb/letter_opener/pull/12) and
103
+ [@pseudomuto](https://github.com/pseudomuto) for keeping the project alive for a
104
+ few years.
96
105
 
97
106
  ## Contributing
98
107
 
@@ -2,5 +2,6 @@
2
2
 
3
3
  module LetterOpenerWeb
4
4
  class ApplicationController < ActionController::Base
5
+ protect_from_forgery with: :exception, unless: -> { Rails.configuration.try(:api_only) }
5
6
  end
6
7
  end
@@ -10,7 +10,7 @@ module LetterOpenerWeb
10
10
  before_action :load_letter, only: %i[show attachment destroy]
11
11
 
12
12
  def index
13
- @letters = Letter.search
13
+ @letters = LetterOpenerWeb::Letter.search
14
14
  end
15
15
 
16
16
  def show
@@ -31,13 +31,16 @@ module LetterOpenerWeb
31
31
  end
32
32
 
33
33
  def clear
34
- Letter.destroy_all
34
+ LetterOpenerWeb::Letter.destroy_all
35
35
  redirect_to routes.letters_path
36
36
  end
37
37
 
38
38
  def destroy
39
39
  @letter.delete
40
- redirect_to routes.letters_path
40
+ respond_to do |format|
41
+ format.html { redirect_to routes.letters_path }
42
+ format.js { render js: "window.location='#{routes.letters_path}'" }
43
+ end
41
44
  end
42
45
 
43
46
  private
@@ -47,7 +50,7 @@ module LetterOpenerWeb
47
50
  end
48
51
 
49
52
  def load_letter
50
- @letter = Letter.find(params[:id])
53
+ @letter = LetterOpenerWeb::Letter.find(params[:id])
51
54
 
52
55
  head :not_found unless @letter.valid?
53
56
  end
@@ -33,6 +33,18 @@ module LetterOpenerWeb
33
33
  @sent_at = params[:sent_at]
34
34
  end
35
35
 
36
+ def headers
37
+ html = read_file(:rich) if style_exists?('rich')
38
+ html ||= read_file(:plain)
39
+
40
+ # NOTE: This is ugly, we should look into using nokogiri and making that a
41
+ # dependency of this gem
42
+ match_data = html.match(%r{<body>\s*<div[^>]+id="container">\s*<div[^>]+id="message_headers">\s*(<dl>.+</dl>)}m)
43
+ return remove_attachments_link(match_data[1]).html_safe if match_data && match_data[1].present?
44
+
45
+ 'UNABLE TO PARSE HEADERS'
46
+ end
47
+
36
48
  def plain_text
37
49
  @plain_text ||= adjust_link_targets(read_file(:plain))
38
50
  end
@@ -67,6 +79,15 @@ module LetterOpenerWeb
67
79
 
68
80
  private
69
81
 
82
+ def remove_attachments_link(headers)
83
+ xml = REXML::Document.new(headers)
84
+ if xml.root.elements.size == 10
85
+ xml.delete_element('//dd[last()]')
86
+ xml.delete_element('//dt[last()]')
87
+ end
88
+ xml.to_s
89
+ end
90
+
70
91
  def base_dir
71
92
  LetterOpenerWeb.config.letters_location.join(id).cleanpath
72
93
  end
@@ -88,7 +109,7 @@ module LetterOpenerWeb
88
109
  end
89
110
 
90
111
  def adjust_link_targets(contents)
91
- # We cannot feed the whole file to an XML parser as some mails are
112
+ # We cannot feed the whole file to a XML parser as some mails are
92
113
  # "complete" (as in they have the whole <html> structure) and letter_opener
93
114
  # prepends some information about the mail being sent, making REXML
94
115
  # complain about it