letter_opener_web_wally 2.0.1
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 +7 -0
- data/.github/workflows/brakeman-analysis.yml +36 -0
- data/.github/workflows/main.yml +29 -0
- data/.github/workflows/release-gem.yml +32 -0
- data/.gitignore +20 -0
- data/.rspec +4 -0
- data/.rubocop.yml +29 -0
- data/.rubocop_todo.yml +19 -0
- data/CHANGELOG.md +95 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +0 -0
- data/README.md +176 -0
- data/Rakefile +10 -0
- data/app/controllers/letter_opener_web/application_controller.rb +7 -0
- data/app/controllers/letter_opener_web/letters_controller.rb +77 -0
- data/app/models/letter_opener_web/aws_letter.rb +98 -0
- data/app/models/letter_opener_web/base_letter.rb +93 -0
- data/app/models/letter_opener_web/letter.rb +54 -0
- data/app/models/letter_opener_web/s3_message.rb +25 -0
- 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/app/views/layouts/letter_opener_web/js/_favcount.html.erb +104 -0
- data/app/views/layouts/letter_opener_web/js/_jquery.html.erb +7 -0
- data/app/views/layouts/letter_opener_web/letters.html.erb +15 -0
- 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 +24 -0
- data/bin/setup +6 -0
- data/config/routes.rb +9 -0
- data/letter_opener_web.gemspec +35 -0
- data/lib/letter_opener_web/delivery_method.rb +29 -0
- data/lib/letter_opener_web/engine.rb +20 -0
- data/lib/letter_opener_web/version.rb +5 -0
- data/lib/letter_opener_web.rb +52 -0
- data/script/pre-push +2 -0
- data/spec/controllers/letter_opener_web/letters_controller_spec.rb +282 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- 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 +4 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/javascript/packs/application.js +15 -0
- data/spec/dummy/app/jobs/application_job.rb +9 -0
- data/spec/dummy/app/mailers/application_mailer.rb +6 -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 +15 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config/application.rb +37 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +78 -0
- data/spec/dummy/config/environments/production.rb +122 -0
- data/spec/dummy/config/environments/test.rb +61 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +10 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +10 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +30 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +8 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +6 -0
- data/spec/dummy/config/initializers/permissions_policy.rb +13 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +45 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config.ru +8 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/storage/.keep +0 -0
- data/spec/letter_opener_web_spec.rb +47 -0
- data/spec/models/letter_opener_web/aws_letter_spec.rb +196 -0
- data/spec/models/letter_opener_web/letter_spec.rb +184 -0
- data/spec/rails_helper.rb +8 -0
- data/spec/spec_helper.rb +8 -0
- metadata +291 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a34ba978b666fa88474ab1697dfa5d323e7d15043ab62e308e5668169afdfcb9
|
4
|
+
data.tar.gz: d9966db09bb55a8087663f307544635260049d4c0ddaff8340b057ee1087ee3e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0df7f91a15f1777e24c2e0e1d1de818e9c2072f29c7331fb287ccebe87854d81218bc4f0835df61b8eafdf4b7d9be485747398c88fd151be5aefe6294c2ada49
|
7
|
+
data.tar.gz: bead6616179ea77f6b7fdc1d76e3d8452a8a40fec479a00226169a28409c59936c95db961eeee97bf0d77e591ee925efe9ba171ecc8960a3305e21f750a50865
|
@@ -0,0 +1,36 @@
|
|
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: [main]
|
9
|
+
pull_request:
|
10
|
+
# The branches below must be a subset of the branches above
|
11
|
+
branches: [main]
|
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, JRuby and TruffleRuby
|
26
|
+
uses: ruby/setup-ruby@v1.196.0
|
27
|
+
with:
|
28
|
+
ruby-version: 3.2
|
29
|
+
|
30
|
+
# Install dependencies
|
31
|
+
- name: Install dependencies
|
32
|
+
run: bundle install
|
33
|
+
|
34
|
+
# Run Brakeman
|
35
|
+
- name: Brakeman code scanning
|
36
|
+
uses: standardnotes/brakeman-action@v1.0.0
|
@@ -0,0 +1,29 @@
|
|
1
|
+
name: Run tests
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [main]
|
6
|
+
pull_request:
|
7
|
+
branches: [main]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- name: Checkout repository
|
14
|
+
uses: actions/checkout@v2
|
15
|
+
|
16
|
+
- name: Set up Ruby 3.2
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: 3.2
|
20
|
+
bundler-cache: true
|
21
|
+
|
22
|
+
- name: Install dependencies
|
23
|
+
run: bundle install
|
24
|
+
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rake
|
27
|
+
|
28
|
+
- name: Build gem
|
29
|
+
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.2
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: 3.2
|
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
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
---
|
2
|
+
inherit_from: .rubocop_todo.yml
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
NewCops: enable
|
6
|
+
TargetRubyVersion: 3.2
|
7
|
+
Exclude:
|
8
|
+
- "spec/dummy/bin/**/*"
|
9
|
+
- "tmp/**/*"
|
10
|
+
- "vendor/**/*"
|
11
|
+
|
12
|
+
Metrics/BlockLength:
|
13
|
+
Exclude:
|
14
|
+
- spec/**/*_spec.rb
|
15
|
+
|
16
|
+
Layout/LineLength:
|
17
|
+
Max: 120
|
18
|
+
|
19
|
+
Style/Documentation:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Metrics/MethodLength:
|
23
|
+
Max: 20
|
24
|
+
|
25
|
+
Metrics/AbcSize:
|
26
|
+
Max: 25
|
27
|
+
|
28
|
+
Gemspec/DevelopmentDependencies:
|
29
|
+
Enabled: false
|
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
ADDED
@@ -0,0 +1,95 @@
|
|
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)
|
23
|
+
|
24
|
+
## [1.3.4](https://github.com/fgrehm/letter_opener_web/compare/v1.3.3...v1.3.4) (Apr 04, 2018)
|
25
|
+
|
26
|
+
### Fixed
|
27
|
+
|
28
|
+
- Due to a load order issue, sometimes the main `ApplicationController` was used by this gem (unnecessary) [#82](https://github.com/fgrehm/letter_opener_web/pull/82)
|
29
|
+
|
30
|
+
## [1.3.3](https://github.com/fgrehm/letter_opener_web/compare/v1.3.2...v1.3.3) (Jan 29, 2018)
|
31
|
+
|
32
|
+
- Set `LAUNCHY_DRY_RUN` explicitly to avoid `Launchy::CommandNotFoundError` [#75](https://github.com/fgrehm/letter_opener_web/pull/75)
|
33
|
+
- Update Ruby matrix for test to include more recent versions [#77](https://github.com/fgrehm/letter_opener_web/pull/77)
|
34
|
+
|
35
|
+
## [1.3.2](https://github.com/fgrehm/letter_opener_web/compare/v1.3.1...v1.3.2) (Jan 14, 2018)
|
36
|
+
|
37
|
+
- Disable Launchy with ENV to avoid redefining the whole delivery method [#73](https://github.com/fgrehm/letter_opener_web/pull/73)
|
38
|
+
- Fix new Rubocop warnings [#72](https://github.com/fgrehm/letter_opener_web/pull/72)
|
39
|
+
- Hover state fixed to only highlight `tbody>tr` [#70](https://github.com/fgrehm/letter_opener_web/pull/70)
|
40
|
+
- Use `ActiveSupport.on_load` to make sure we don't have load order issues [#66](https://github.com/fgrehm/letter_opener_web/pull/66)
|
41
|
+
|
42
|
+
## [1.3.1](https://github.com/fgrehm/letter_opener_web/compare/v1.3.0...v1.3.1) (Feb 04, 2017)
|
43
|
+
|
44
|
+
- Remove warnings about unused variables [#45](https://github.com/fgrehm/letter_opener_web/pull/45)
|
45
|
+
- Remove Rails 5 deprecation warnings [#54](https://github.com/fgrehm/letter_opener_web/pull/54)
|
46
|
+
|
47
|
+
## [1.3.0](https://github.com/fgrehm/letter_opener_web/compare/v1.2.3...v1.3.0) (Feb 02, 2015)
|
48
|
+
|
49
|
+
- Depend on `railties` and `actionmailer` [#38](https://github.com/fgrehm/letter_opener_web/pull/38)
|
50
|
+
|
51
|
+
## [1.2.3](https://github.com/fgrehm/letter_opener_web/compare/v1.2.2...v1.2.3) (Sep 12, 2014)
|
52
|
+
|
53
|
+
- Fix exception with `sprockets-rails` >= `2.1.4` [#32](https://github.com/fgrehm/letter_opener_web/issues/32) / [#33](https://github.com/fgrehm/letter_opener_web/pull/33)
|
54
|
+
|
55
|
+
## [1.2.2](https://github.com/fgrehm/letter_opener_web/compare/v1.2.1...v1.2.2) (Jul 17, 2014)
|
56
|
+
|
57
|
+
- Precompile glyphicons [#30](https://github.com/fgrehm/letter_opener_web/pull/30)
|
58
|
+
- Display letters count on the favicon [#29](https://github.com/fgrehm/letter_opener_web/pull/29)
|
59
|
+
- Validate params passed in to the LettersController and return a 404 in case an email can't be found [#28](https://github.com/fgrehm/letter_opener_web/pull/28)
|
60
|
+
|
61
|
+
## [1.2.1](https://github.com/fgrehm/letter_opener_web/compare/v1.2.0...v1.2.1) (Apr 07, 2014)
|
62
|
+
|
63
|
+
- Improve Rails 3 compatibility [#26](https://github.com/fgrehm/letter_opener_web/pull/26) / [#27](https://github.com/fgrehm/letter_opener_web/pull/27)
|
64
|
+
|
65
|
+
## [1.2.0](https://github.com/fgrehm/letter_opener_web/compare/v1.1.3...v1.2.0) (Apr 07, 2014)
|
66
|
+
|
67
|
+
- Add support for removing a single email [#23](https://github.com/fgrehm/letter_opener_web/pull/23)
|
68
|
+
- Move vendored assets into the `letter_opener_web` folder [#24](https://github.com/fgrehm/letter_opener_web/issues/24)
|
69
|
+
- Avoid matching `<address>` when changing email links to open on new tabs [#22](https://github.com/fgrehm/letter_opener_web/pull/22)
|
70
|
+
|
71
|
+
## [1.1.3](https://github.com/fgrehm/letter_opener_web/compare/v1.1.2...v1.1.3) (Feb 21, 2014)
|
72
|
+
|
73
|
+
- Include assets into `precompile` list [#21](https://github.com/fgrehm/letter_opener_web/pull/21)
|
74
|
+
|
75
|
+
## [1.1.2](https://github.com/fgrehm/letter_opener_web/compare/v1.1.1...v1.1.2) (Dec 12, 2013)
|
76
|
+
|
77
|
+
- Nicely handle empty links [#18](https://github.com/fgrehm/letter_opener_web/pull/18)
|
78
|
+
|
79
|
+
## [1.1.1](https://github.com/fgrehm/letter_opener_web/compare/v1.1.0...v1.1.1) (Oct 15, 2013)
|
80
|
+
|
81
|
+
- Fix deprecation warning on Rails 4 [#17](https://github.com/fgrehm/letter_opener_web/pull/17)
|
82
|
+
|
83
|
+
## [1.1.0](https://github.com/fgrehm/letter_opener_web/compare/v1.0.3...v1.1.0) (Aug 29, 2013)
|
84
|
+
|
85
|
+
- "Relax" Rails dependency in order to use the gem on 4.0 [#15](https://github.com/fgrehm/letter_opener_web/issues/15)
|
86
|
+
|
87
|
+
## [1.0.3](https://github.com/fgrehm/letter_opener_web/compare/v1.0.2...v1.0.3) (May 29, 2013)
|
88
|
+
|
89
|
+
- Fix clear button [#12](https://github.com/fgrehm/letter_opener_web/issues/12), tks to [@grumpit](https://github.com/grumpit)
|
90
|
+
|
91
|
+
## Previous
|
92
|
+
|
93
|
+
The changelog began with version 1.0.3 so any changes prior to that
|
94
|
+
can be seen by checking the tagged releases and reading git commit
|
95
|
+
messages.
|
data/Gemfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'http://rubygems.org'
|
4
|
+
|
5
|
+
# Declare your gem's dependencies in letter_opener_web.gemspec.
|
6
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
7
|
+
# development dependencies will be added by default to the :development group.
|
8
|
+
gemspec
|
data/LICENSE.txt
ADDED
File without changes
|
data/README.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# letter_opener_web
|
2
|
+
|
3
|
+

|
4
|
+
[](http://badge.fury.io/rb/letter_opener_web)
|
5
|
+
[](https://codeclimate.com/github/fgrehm/letter_opener_web)
|
6
|
+
|
7
|
+
Gives [letter_opener](https://github.com/ryanb/letter_opener) an interface for
|
8
|
+
browsing sent emails.
|
9
|
+
|
10
|
+
Check out http://letter-opener-web.herokuapp.com to see it in action.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
First add the gem to your development environment and run the `bundle` command to install it.
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
group :development do
|
18
|
+
gem 'letter_opener_web', '~> 2.0'
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Add to your routes.rb:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
Your::Application.routes.draw do
|
28
|
+
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.configuration.delivery_method == :letter_opener_web
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
And make sure you have [`:letter_opener` delivery method](https://github.com/ryanb/letter_opener#rails-setup)
|
33
|
+
configured for your app. Then visit `http://localhost:3000/letter_opener` after
|
34
|
+
sending an email and have fun.
|
35
|
+
|
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:
|
39
|
+
|
40
|
+
```terminal
|
41
|
+
12:33:42 web.1 | Failure in opening /vagrant/tmp/letter_opener/1358825621_ba83a22/rich.html
|
42
|
+
with options {}: Unable to find a browser command. If this is unexpected, Please rerun with
|
43
|
+
environment variable LAUNCHY_DEBUG=true or the '-d' commandline option and file a bug at
|
44
|
+
https://github.com/copiousfreetime/launchy/issues/new
|
45
|
+
```
|
46
|
+
|
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`:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
config.action_mailer.delivery_method = :letter_opener_web
|
53
|
+
```
|
54
|
+
|
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):
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
LetterOpenerWeb.configure do |config|
|
60
|
+
config.letters_location = Rails.root.join('your', 'new', 'path')
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
Letter Opener Web can also be used with Amazon S3 to store letters instead of filesystem.
|
65
|
+
You can change the storage type by adding the following to an initializer (or indevelopment.rb):
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
LetterOpenerWeb.configure do |config|
|
69
|
+
config.letters_storage = :s3
|
70
|
+
config.letters_location = "any/prefix/you/want"
|
71
|
+
config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
72
|
+
config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
73
|
+
config.aws_region = ENV['AWS_REGION']
|
74
|
+
config.aws_bucket = ENV['AWS_BUCKET']
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
## Usage on pre-production environments
|
79
|
+
|
80
|
+
Some people use this gem on staging / pre-production environments to avoid having real emails
|
81
|
+
being sent out. To set that up you'll need to:
|
82
|
+
|
83
|
+
1. Move the gem out of the `development` group in your `Gemfile`
|
84
|
+
2. Set `config.action_mailer.delivery_method` on the appropriate `config/environments/<env>.rb`
|
85
|
+
3. Enable the route for the environments on your `routes.rb`.
|
86
|
+
|
87
|
+
In other words, your `Gemfile` will have:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
gem 'letter_opener_web'
|
91
|
+
```
|
92
|
+
|
93
|
+
And your `routes.rb`:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
Your::Application.routes.draw do
|
97
|
+
# If you have a dedicated config/environments/staging.rb
|
98
|
+
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.staging?
|
99
|
+
|
100
|
+
# If you use RAILS_ENV=production in staging environments, you'll need another
|
101
|
+
# way to disable it in "real production"
|
102
|
+
mount LetterOpenerWeb::Engine, at: "/letter_opener" unless ENV["PRODUCTION_FOR_REAL"]
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
You might also want to have a look at the sources for the [demo](http://letter-opener-web.herokuapp.com)
|
107
|
+
available at https://github.com/fgrehm/letter_opener_web_demo.
|
108
|
+
|
109
|
+
### Usage with Amazon S3 to support multiple separated instances
|
110
|
+
|
111
|
+
If you are using this gem on Heroku and your application is not using one Dyno or your have containerized setup, the default configuration won't work as the e-mail is saved on the server. You can use S3 bucket instead.
|
112
|
+
|
113
|
+
**1. Configure AWS environment:**
|
114
|
+
|
115
|
+
* Create new non-public bucket, note the name and the region
|
116
|
+
* Create new user using IAM or use existing one for which you already have `aws_access_key_id` and `aws_secret_access_key`
|
117
|
+
* Assign proper policy to the user. Replace `your-bucket-name` with the name of the bucket you have created
|
118
|
+
|
119
|
+
```json
|
120
|
+
{
|
121
|
+
"Version": "2012-10-17",
|
122
|
+
"Statement": [
|
123
|
+
{
|
124
|
+
"Sid": "VisualEditor0",
|
125
|
+
"Effect": "Allow",
|
126
|
+
"Action": [
|
127
|
+
"s3:PutObject",
|
128
|
+
"s3:PutObjectAcl",
|
129
|
+
"s3:GetObject",
|
130
|
+
"s3:DeleteObject*"
|
131
|
+
],
|
132
|
+
"Resource": "arn:aws:s3:::your-bucket-name/*"
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"Sid": "VisualEditor1",
|
136
|
+
"Effect": "Allow",
|
137
|
+
"Action": [
|
138
|
+
"s3:ListBucket"
|
139
|
+
],
|
140
|
+
"Resource": "arn:aws:s3:::your-bucket-name"
|
141
|
+
}
|
142
|
+
]
|
143
|
+
}
|
144
|
+
```
|
145
|
+
|
146
|
+
**2. Update gem configuration:**
|
147
|
+
|
148
|
+
Add the following configuration to the initializer (or environment files):
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
LetterOpenerWeb.configure do |config|
|
152
|
+
config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
153
|
+
config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
154
|
+
config.aws_region = ENV['AWS_REGION']
|
155
|
+
config.aws_bucket = ENV['AWS_BUCKET']
|
156
|
+
config.letters_storage = :s3
|
157
|
+
config.letters_location = "any prefix you want"
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
When you send e-mail with attachment(s), the presigned link is generated to attachment that is valid for 1 week.
|
162
|
+
|
163
|
+
## Acknowledgements
|
164
|
+
|
165
|
+
Special thanks to [@alexrothenberg](https://github.com/alexrothenberg) for some
|
166
|
+
ideas on [this pull request](https://github.com/ryanb/letter_opener/pull/12) and
|
167
|
+
[@pseudomuto](https://github.com/pseudomuto) for keeping the project alive for a
|
168
|
+
few years.
|
169
|
+
|
170
|
+
## Contributing
|
171
|
+
|
172
|
+
1. Fork it and run `bin/setup`
|
173
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
174
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
175
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
176
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless Rails.respond_to?(:autoloaders) && Rails.autoloaders.zeitwerk_enabled?
|
4
|
+
require_dependency 'letter_opener_web/application_controller'
|
5
|
+
end
|
6
|
+
|
7
|
+
module LetterOpenerWeb
|
8
|
+
class LettersController < ApplicationController
|
9
|
+
before_action :check_style, only: :show
|
10
|
+
before_action :load_letter, only: %i[show attachment destroy]
|
11
|
+
before_action :letter_params, only: %i[show attachment]
|
12
|
+
|
13
|
+
def index
|
14
|
+
@letters = letter_model.search
|
15
|
+
end
|
16
|
+
|
17
|
+
def show
|
18
|
+
text = @letter.send("#{letter_params[:style]}_text")
|
19
|
+
.gsub('"plain.html"', "\"#{routes.letter_path(id: @letter.id, style: 'plain')}\"")
|
20
|
+
.gsub('"rich.html"', "\"#{routes.letter_path(id: @letter.id, style: 'rich')}\"")
|
21
|
+
|
22
|
+
render html: text.html_safe
|
23
|
+
end
|
24
|
+
|
25
|
+
def attachment
|
26
|
+
filename = "#{letter_params[:file]}.#{letter_params[:format]}"
|
27
|
+
file = @letter.attachments[filename]
|
28
|
+
|
29
|
+
return render plain: 'Attachment not found!', status: 404 unless file.present?
|
30
|
+
return redirect_to(file, allow_other_host: true) if LetterOpenerWeb.config.letters_storage == :s3
|
31
|
+
|
32
|
+
send_file(file, filename:, disposition: 'inline')
|
33
|
+
end
|
34
|
+
|
35
|
+
def clear
|
36
|
+
letter_model.destroy_all
|
37
|
+
redirect_to routes.letters_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy
|
41
|
+
@letter.delete
|
42
|
+
respond_to do |format|
|
43
|
+
format.html { redirect_to routes.letters_path }
|
44
|
+
format.js { render js: "window.location='#{routes.letters_path}'" }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def letter_params
|
51
|
+
params.permit(:style, :file, :format, :id)
|
52
|
+
end
|
53
|
+
|
54
|
+
def check_style
|
55
|
+
letter_params[:style] = 'rich' unless %w[plain rich].include?(letter_params[:style])
|
56
|
+
end
|
57
|
+
|
58
|
+
def load_letter
|
59
|
+
@letter = letter_model.find(letter_params[:id])
|
60
|
+
|
61
|
+
head :not_found unless @letter.valid?
|
62
|
+
end
|
63
|
+
|
64
|
+
def routes
|
65
|
+
LetterOpenerWeb.railtie_routes_url_helpers
|
66
|
+
end
|
67
|
+
|
68
|
+
def letter_model
|
69
|
+
case LetterOpenerWeb.config.letters_storage
|
70
|
+
when :s3
|
71
|
+
LetterOpenerWeb::AwsLetter
|
72
|
+
else
|
73
|
+
LetterOpenerWeb::Letter
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LetterOpenerWeb
|
4
|
+
class AwsLetter < BaseLetter
|
5
|
+
def self.aws_list_letters(path = [], **)
|
6
|
+
LetterOpenerWeb
|
7
|
+
.aws_client
|
8
|
+
.list_objects_v2(
|
9
|
+
bucket: LetterOpenerWeb.config.aws_bucket,
|
10
|
+
prefix: File.join([letters_location, *path].compact),
|
11
|
+
**
|
12
|
+
)
|
13
|
+
end
|
14
|
+
delegate :aws_list_letters, to: :class
|
15
|
+
|
16
|
+
def self.search
|
17
|
+
letters = aws_list_letters(delimiter: '.html').common_prefixes.map do |prefix|
|
18
|
+
new(id: File.basename(File.dirname(prefix.prefix)))
|
19
|
+
end
|
20
|
+
|
21
|
+
letters.reverse
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.destroy_all
|
25
|
+
letters = aws_list_letters.contents.map(&:key)
|
26
|
+
|
27
|
+
LetterOpenerWeb.aws_client.delete_objects(
|
28
|
+
bucket: LetterOpenerWeb.config.aws_bucket,
|
29
|
+
delete: {
|
30
|
+
objects: letters.map { |key| { key: } },
|
31
|
+
quiet: false
|
32
|
+
}
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def attachments
|
37
|
+
@attachments ||= aws_list_letters([id, 'attachments/']).contents.each_with_object({}) do |file, hash|
|
38
|
+
hash[File.basename(file.key)] = attachment_url(file.key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete
|
43
|
+
return unless valid?
|
44
|
+
|
45
|
+
letters = aws_list_letters([id]).contents.map(&:key)
|
46
|
+
|
47
|
+
LetterOpenerWeb.aws_client.delete_objects(
|
48
|
+
bucket: LetterOpenerWeb.config.aws_bucket,
|
49
|
+
delete: {
|
50
|
+
objects: letters.map { |key| { key: } },
|
51
|
+
quiet: false
|
52
|
+
}
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def valid?
|
57
|
+
aws_list_letters([id]).contents.any?
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def attachment_url(key)
|
63
|
+
bucket = Aws::S3::Bucket.new(
|
64
|
+
name: LetterOpenerWeb.config.aws_bucket, client: LetterOpenerWeb.aws_client
|
65
|
+
)
|
66
|
+
|
67
|
+
obj = bucket.object(key)
|
68
|
+
obj.presigned_url(:get, expires_in: 1.week.to_i)
|
69
|
+
end
|
70
|
+
|
71
|
+
def objects
|
72
|
+
@objects ||= {}
|
73
|
+
end
|
74
|
+
|
75
|
+
def read_file(style)
|
76
|
+
return objects[style] if objects.key?(style)
|
77
|
+
|
78
|
+
response = LetterOpenerWeb.aws_client
|
79
|
+
.get_object(
|
80
|
+
bucket: LetterOpenerWeb.config.aws_bucket,
|
81
|
+
key: File.join(letters_location, id, "#{style}.html")
|
82
|
+
)
|
83
|
+
|
84
|
+
response.body.read.tap do |value|
|
85
|
+
objects[style] = value
|
86
|
+
end
|
87
|
+
rescue Aws::S3::Errors::NoSuchKey
|
88
|
+
''
|
89
|
+
end
|
90
|
+
|
91
|
+
def style_exists?(style)
|
92
|
+
return !objects[style].empty? if objects.key?(style)
|
93
|
+
|
94
|
+
objects[style] = read_file(style)
|
95
|
+
!objects[style].empty?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|