letter_opener_web 1.3.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/brakeman-analysis.yml +46 -0
- data/.github/workflows/main.yml +34 -0
- data/.github/workflows/release-gem.yml +32 -0
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/.rubocop.yml +5 -16
- data/.rubocop_todo.yml +19 -0
- data/CHANGELOG.md +22 -1
- data/Gemfile +4 -0
- data/LICENSE.txt +1 -1
- data/README.md +33 -24
- data/app/controllers/letter_opener_web/application_controller.rb +1 -0
- data/app/controllers/letter_opener_web/letters_controller.rb +14 -7
- data/app/models/letter_opener_web/letter.rb +37 -5
- data/app/views/layouts/letter_opener_web/_javascripts.html.erb +31 -0
- data/app/views/layouts/letter_opener_web/_styles.html.erb +3 -0
- data/{vendor/assets/javascripts/letter_opener_web/favcount.js → app/views/layouts/letter_opener_web/js/_favcount.html.erb} +9 -7
- data/app/views/layouts/letter_opener_web/js/_jquery.html.erb +7 -0
- data/app/views/layouts/letter_opener_web/letters.html.erb +5 -3
- data/app/views/layouts/letter_opener_web/styles/_bootstrap.html.erb +9 -0
- data/app/views/layouts/letter_opener_web/styles/_icon.html.erb +2 -0
- data/app/views/layouts/letter_opener_web/styles/_letters.html.erb +70 -0
- data/app/views/letter_opener_web/letters/_item.html.erb +10 -0
- data/app/views/letter_opener_web/letters/index.html.erb +11 -46
- data/config/routes.rb +5 -5
- data/letter_opener_web.gemspec +19 -15
- data/lib/letter_opener_web/delivery_method.rb +1 -1
- data/lib/letter_opener_web/engine.rb +0 -10
- data/lib/letter_opener_web/version.rb +1 -1
- data/lib/letter_opener_web.rb +1 -0
- data/spec/controllers/letter_opener_web/letters_controller_spec.rb +22 -11
- data/spec/dummy/app/assets/config/manifest.js +0 -2
- data/spec/dummy/app/assets/stylesheets/application.css +0 -16
- data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
- data/spec/dummy/app/controllers/application_controller.rb +0 -1
- data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +2 -0
- data/spec/dummy/app/jobs/application_job.rb +9 -0
- data/spec/dummy/app/models/application_record.rb +5 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +4 -7
- data/spec/dummy/bin/rails +2 -4
- data/spec/dummy/bin/rake +2 -4
- data/spec/dummy/bin/setup +7 -10
- data/spec/dummy/config/application.rb +21 -7
- data/spec/dummy/config/environments/development.rb +44 -6
- data/spec/dummy/config/environments/production.rb +51 -14
- data/spec/dummy/config/environments/test.rb +30 -6
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -4
- data/spec/dummy/config/initializers/assets.rb +5 -5
- data/spec/dummy/config/initializers/backtrace_silencers.rb +5 -3
- data/spec/dummy/config/initializers/content_security_policy.rb +29 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
- data/spec/dummy/config/initializers/permissions_policy.rb +12 -0
- data/spec/dummy/config/locales/en.yml +11 -1
- data/spec/dummy/config/puma.rb +18 -22
- data/spec/dummy/config/routes.rb +1 -4
- data/spec/dummy/config.ru +1 -0
- data/spec/dummy/public/404.html +6 -6
- data/spec/dummy/public/422.html +6 -6
- data/spec/dummy/public/500.html +6 -6
- data/spec/dummy/storage/.keep +0 -0
- data/spec/letter_opener_web_spec.rb +2 -2
- data/spec/models/letter_opener_web/letter_spec.rb +62 -17
- data/spec/spec_helper.rb +8 -0
- metadata +91 -54
- data/.travis.yml +0 -26
- data/app/assets/javascripts/letter_opener_web/application.js +0 -30
- data/app/assets/stylesheets/letter_opener_web/application.css.erb +0 -54
- data/bin/rails +0 -11
- data/spec/dummy/app/controllers/home_controller.rb +0 -10
- data/spec/dummy/app/mailers/contact_mailer.rb +0 -14
- data/spec/dummy/app/views/contact_mailer/new_message.html.erb +0 -21
- data/spec/dummy/app/views/contact_mailer/new_message.text.erb +0 -3
- data/spec/dummy/app/views/home/index.html.erb +0 -50
- data/spec/dummy/bin/bundle +0 -5
- data/spec/dummy/bin/update +0 -31
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
- data/spec/dummy/config/initializers/session_store.rb +0 -5
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/config/spring.rb +0 -8
- data/vendor/assets/images/letter_opener_web/blue-dot.ico +0 -0
- data/vendor/assets/images/letter_opener_web/glyphicons-halflings-white.png +0 -0
- data/vendor/assets/images/letter_opener_web/glyphicons-halflings.png +0 -0
- data/vendor/assets/javascripts/letter_opener_web/bootstrap.min.js +0 -6
- data/vendor/assets/javascripts/letter_opener_web/jquery-1.8.3.min.js +0 -2
- data/vendor/assets/javascripts/letter_opener_web/jquery_ujs.js +0 -429
- data/vendor/assets/stylesheets/letter_opener_web/bootstrap.min.css +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3b31a75a1e88a4e79a2c79ef92da951522caf6ffbd7ab684b53a46b0982efd85
|
|
4
|
+
data.tar.gz: a4f6a87162bdcc3d28632f192f97aaba812939697c08c86904a36aa4ce9b6da8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
---
|
|
2
|
+
inherit_from: .rubocop_todo.yml
|
|
3
|
+
|
|
2
4
|
AllCops:
|
|
3
|
-
|
|
5
|
+
NewCops: enable
|
|
6
|
+
TargetRubyVersion: 2.7
|
|
4
7
|
Exclude:
|
|
5
|
-
- "bin/**/*"
|
|
6
8
|
- "spec/dummy/bin/**/*"
|
|
7
9
|
- "tmp/**/*"
|
|
8
10
|
- "vendor/**/*"
|
|
9
11
|
|
|
10
|
-
# not available in older versions of Ruby
|
|
11
|
-
Layout/IndentHeredoc:
|
|
12
|
-
Enabled: false
|
|
13
|
-
|
|
14
|
-
Style/Documentation:
|
|
15
|
-
Enabled: false
|
|
16
|
-
|
|
17
|
-
Style/ClassAndModuleChildren:
|
|
18
|
-
EnforcedStyle: nested
|
|
19
|
-
|
|
20
|
-
Style/SingleLineBlockParams:
|
|
21
|
-
Enabled: false
|
|
22
|
-
|
|
23
12
|
Metrics/BlockLength:
|
|
24
13
|
Exclude:
|
|
25
14
|
- spec/**/*_spec.rb
|
|
26
15
|
|
|
27
|
-
|
|
16
|
+
Layout/LineLength:
|
|
28
17
|
Max: 120
|
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,4 +1,25 @@
|
|
|
1
|
-
## [
|
|
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
|
+
|
|
14
|
+
## [1.4.1](https://github.com/fgrehm/letter_opener_web/compare/v1.4.0...v1.4.1) (Oct 5, 2021)
|
|
15
|
+
|
|
16
|
+
- Ensure letter is within letters base path [#110](https://github.com/fgrehm/letter_opener_web/pull/110)
|
|
17
|
+
|
|
18
|
+
## [1.4.0](https://github.com/fgrehm/letter_opener_web/compare/v1.3.4...v1.4.0) (Jan 29, 2020)
|
|
19
|
+
|
|
20
|
+
- Removed the dependency on the asset pipeline. Good news for API-only apps! [#83](https://github.com/fgrehm/letter_opener_web/pull/83)
|
|
21
|
+
- Avoid `require_dependency` if Zeitwerk is enabled [#98](https://github.com/fgrehm/letter_opener_web/pull/98)
|
|
22
|
+
- Drop support for old rubies and rails. Ruby 2.5+ is supported and Rails 4 is no longer tested [#100](https://github.com/fgrehm/letter_opener_web/pull/100)
|
|
2
23
|
|
|
3
24
|
## [1.3.4](https://github.com/fgrehm/letter_opener_web/compare/v1.3.3...v1.3.4) (Apr 04, 2018)
|
|
4
25
|
|
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# letter_opener_web
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
|
+
[](http://badge.fury.io/rb/letter_opener_web)
|
|
5
|
+
[](https://codeclimate.com/github/fgrehm/letter_opener_web)
|
|
4
6
|
|
|
5
7
|
Gives [letter_opener](https://github.com/ryanb/letter_opener) an interface for
|
|
6
8
|
browsing sent emails.
|
|
@@ -13,7 +15,7 @@ First add the gem to your development environment and run the `bundle` command t
|
|
|
13
15
|
|
|
14
16
|
```ruby
|
|
15
17
|
group :development do
|
|
16
|
-
gem 'letter_opener_web'
|
|
18
|
+
gem 'letter_opener_web', '~> 2.0'
|
|
17
19
|
end
|
|
18
20
|
```
|
|
19
21
|
|
|
@@ -23,9 +25,7 @@ Add to your routes.rb:
|
|
|
23
25
|
|
|
24
26
|
```ruby
|
|
25
27
|
Your::Application.routes.draw do
|
|
26
|
-
if Rails.env.development?
|
|
27
|
-
mount LetterOpenerWeb::Engine, at: "/letter_opener"
|
|
28
|
-
end
|
|
28
|
+
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
|
|
29
29
|
end
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -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
|
|
37
|
-
might want to skip `letter_opener`'s `launchy` calls and avoid messages
|
|
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
|
|
47
|
-
can set `:letter_opener_web` as
|
|
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
|
|
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,13 +61,16 @@ LetterOpenerWeb.configure do |config|
|
|
|
63
61
|
end
|
|
64
62
|
```
|
|
65
63
|
|
|
66
|
-
## Usage on
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
the route for
|
|
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
|
-
In
|
|
73
|
+
In other words, your `Gemfile` will have:
|
|
73
74
|
|
|
74
75
|
```ruby
|
|
75
76
|
gem 'letter_opener_web'
|
|
@@ -79,20 +80,28 @@ And your `routes.rb`:
|
|
|
79
80
|
|
|
80
81
|
```ruby
|
|
81
82
|
Your::Application.routes.draw do
|
|
82
|
-
|
|
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
|
|
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
|
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
unless Rails.respond_to?(:autoloaders) && Rails.autoloaders.zeitwerk_enabled?
|
|
4
|
+
require_dependency 'letter_opener_web/application_controller'
|
|
5
|
+
end
|
|
4
6
|
|
|
5
7
|
module LetterOpenerWeb
|
|
6
8
|
class LettersController < ApplicationController
|
|
7
|
-
before_action :check_style, only:
|
|
9
|
+
before_action :check_style, only: :show
|
|
8
10
|
before_action :load_letter, only: %i[show attachment destroy]
|
|
9
11
|
|
|
10
12
|
def index
|
|
11
|
-
@letters = Letter.search
|
|
13
|
+
@letters = LetterOpenerWeb::Letter.search
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def show
|
|
@@ -24,17 +26,21 @@ module LetterOpenerWeb
|
|
|
24
26
|
file = @letter.attachments[filename]
|
|
25
27
|
|
|
26
28
|
return render plain: 'Attachment not found!', status: 404 unless file.present?
|
|
29
|
+
|
|
27
30
|
send_file(file, filename: filename, disposition: 'inline')
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
def clear
|
|
31
|
-
Letter.destroy_all
|
|
34
|
+
LetterOpenerWeb::Letter.destroy_all
|
|
32
35
|
redirect_to routes.letters_path
|
|
33
36
|
end
|
|
34
37
|
|
|
35
38
|
def destroy
|
|
36
39
|
@letter.delete
|
|
37
|
-
|
|
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
|
|
38
44
|
end
|
|
39
45
|
|
|
40
46
|
private
|
|
@@ -44,8 +50,9 @@ module LetterOpenerWeb
|
|
|
44
50
|
end
|
|
45
51
|
|
|
46
52
|
def load_letter
|
|
47
|
-
@letter = Letter.find(params[:id])
|
|
48
|
-
|
|
53
|
+
@letter = LetterOpenerWeb::Letter.find(params[:id])
|
|
54
|
+
|
|
55
|
+
head :not_found unless @letter.valid?
|
|
49
56
|
end
|
|
50
57
|
|
|
51
58
|
def routes
|
|
@@ -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
|
|
@@ -56,17 +68,28 @@ module LetterOpenerWeb
|
|
|
56
68
|
end
|
|
57
69
|
|
|
58
70
|
def delete
|
|
59
|
-
|
|
71
|
+
return unless valid?
|
|
72
|
+
|
|
73
|
+
FileUtils.rm_rf(base_dir.to_s)
|
|
60
74
|
end
|
|
61
75
|
|
|
62
|
-
def
|
|
63
|
-
|
|
76
|
+
def valid?
|
|
77
|
+
exists? && base_dir_within_letters_location?
|
|
64
78
|
end
|
|
65
79
|
|
|
66
80
|
private
|
|
67
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
|
+
|
|
68
91
|
def base_dir
|
|
69
|
-
|
|
92
|
+
LetterOpenerWeb.config.letters_location.join(id).cleanpath
|
|
70
93
|
end
|
|
71
94
|
|
|
72
95
|
def read_file(style)
|
|
@@ -77,8 +100,16 @@ module LetterOpenerWeb
|
|
|
77
100
|
File.exist?("#{base_dir}/#{style}.html")
|
|
78
101
|
end
|
|
79
102
|
|
|
103
|
+
def exists?
|
|
104
|
+
File.exist?(base_dir)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def base_dir_within_letters_location?
|
|
108
|
+
base_dir.to_s.start_with?(LetterOpenerWeb.config.letters_location.to_s)
|
|
109
|
+
end
|
|
110
|
+
|
|
80
111
|
def adjust_link_targets(contents)
|
|
81
|
-
# We cannot feed the whole file to
|
|
112
|
+
# We cannot feed the whole file to a XML parser as some mails are
|
|
82
113
|
# "complete" (as in they have the whole <html> structure) and letter_opener
|
|
83
114
|
# prepends some information about the mail being sent, making REXML
|
|
84
115
|
# complain about it
|
|
@@ -86,6 +117,7 @@ module LetterOpenerWeb
|
|
|
86
117
|
fixed_link = fix_link_html(link)
|
|
87
118
|
xml = REXML::Document.new(fixed_link).root
|
|
88
119
|
next if xml.attributes['href'] =~ /(plain|rich).html/
|
|
120
|
+
|
|
89
121
|
xml.attributes['target'] = '_blank'
|
|
90
122
|
xml.add_text('') unless xml.text
|
|
91
123
|
contents.gsub!(link, xml.to_s)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<%= render "layouts/letter_opener_web/js/jquery" %>
|
|
2
|
+
<%= render "layouts/letter_opener_web/js/favcount" %>
|
|
3
|
+
|
|
4
|
+
<script nonce="<%= content_security_policy_nonce %>">
|
|
5
|
+
function update_favicon(favicon) {
|
|
6
|
+
favicon.set($('.letter-opener a').length);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
jQuery(function($) {
|
|
10
|
+
var favicon = new Favcount($('link[rel="icon"]').attr('href'));
|
|
11
|
+
update_favicon(favicon);
|
|
12
|
+
|
|
13
|
+
$('.letter-opener').on('click', 'a', function() {
|
|
14
|
+
var $this = $(this);
|
|
15
|
+
$('iframe').attr('src', $this.attr('href'));
|
|
16
|
+
$this.parents('.list-group').find('.active').removeClass('active');
|
|
17
|
+
$this.parent().addClass('active');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
$('.refresh').click(function(e) {
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
|
|
23
|
+
var wrapper = $('.letter-opener');
|
|
24
|
+
wrapper.find('div').text('Loading...');
|
|
25
|
+
wrapper.load(wrapper.data('letters-path') + ' .letter-opener', function() {
|
|
26
|
+
$('iframe').attr('src', $('.letter-opener a:first-child()').attr('href'));
|
|
27
|
+
update_favicon(favicon);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
</script>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<script nonce="<%= content_security_policy_nonce %>">
|
|
1
2
|
/*
|
|
2
3
|
* favcount.js v1.5.0
|
|
3
4
|
* http://chrishunt.co/favcount
|
|
@@ -46,11 +47,10 @@
|
|
|
46
47
|
|
|
47
48
|
function drawCanvas(canvas, opacity, font, img, count) {
|
|
48
49
|
var head = document.getElementsByTagName('head')[0],
|
|
49
|
-
favicon = document.
|
|
50
|
+
favicon = document.querySelector('link[rel=icon]'),
|
|
51
|
+
newFavicon = document.createElement('link'),
|
|
50
52
|
multiplier, fontSize, context, xOffset, yOffset, border, shadow;
|
|
51
53
|
|
|
52
|
-
favicon.rel = 'icon';
|
|
53
|
-
|
|
54
54
|
// Scale canvas elements based on favicon size
|
|
55
55
|
multiplier = img.width / 16;
|
|
56
56
|
fontSize = multiplier * 11;
|
|
@@ -89,14 +89,16 @@
|
|
|
89
89
|
);
|
|
90
90
|
|
|
91
91
|
// Replace favicon with new favicon
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
head.
|
|
92
|
+
newFavicon.rel = 'icon';
|
|
93
|
+
newFavicon.href = canvas.toDataURL('image/png');
|
|
94
|
+
if (favicon) { head.removeChild(favicon); }
|
|
95
|
+
head.appendChild(newFavicon);
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
this.Favcount = Favcount;
|
|
98
99
|
}).call(this);
|
|
99
100
|
|
|
100
101
|
(function(){
|
|
101
|
-
Favcount.VERSION = '1.5.
|
|
102
|
+
Favcount.VERSION = '1.5.1';
|
|
102
103
|
}).call(this);
|
|
104
|
+
</script>
|