federal_offense 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +107 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/config/federal_offense_manifest.js +2 -0
  6. data/app/assets/javascripts/federal_offense/application.js +7 -0
  7. data/app/assets/javascripts/federal_offense/cable.js +18 -0
  8. data/app/assets/javascripts/federal_offense/vendor/action_cable.js +601 -0
  9. data/app/assets/stylesheets/federal_offense/application.css +33 -0
  10. data/app/assets/stylesheets/federal_offense/components/article.css +5 -0
  11. data/app/assets/stylesheets/federal_offense/components/aside.css +9 -0
  12. data/app/assets/stylesheets/federal_offense/components/empty.css +27 -0
  13. data/app/assets/stylesheets/federal_offense/components/link.css +4 -0
  14. data/app/assets/stylesheets/federal_offense/components/list.css +87 -0
  15. data/app/assets/stylesheets/federal_offense/components/main.css +9 -0
  16. data/app/assets/stylesheets/federal_offense/components/message.css +13 -0
  17. data/app/assets/stylesheets/federal_offense/components/nav.css +30 -0
  18. data/app/assets/stylesheets/federal_offense/components/section.css +6 -0
  19. data/app/assets/stylesheets/federal_offense/components/table.css +18 -0
  20. data/app/channels/federal_offense/application_cable/channel.rb +8 -0
  21. data/app/channels/federal_offense/application_cable/connection.rb +8 -0
  22. data/app/channels/federal_offense/inbox_channel.rb +16 -0
  23. data/app/controllers/federal_offense/application_controller.rb +6 -0
  24. data/app/controllers/federal_offense/messages_controller.rb +55 -0
  25. data/app/helpers/federal_offense/application_helper.rb +10 -0
  26. data/app/models/federal_offense/message.rb +141 -0
  27. data/app/views/federal_offense/messages/index.html.erb +6 -0
  28. data/app/views/federal_offense/messages/show.html.erb +30 -0
  29. data/app/views/layouts/federal_offense/application.html.erb +96 -0
  30. data/config/locales/en.yml +18 -0
  31. data/config/routes.rb +17 -0
  32. data/lib/federal_offense.rb +11 -0
  33. data/lib/federal_offense/engine.rb +57 -0
  34. data/lib/federal_offense/interceptor.rb +10 -0
  35. data/lib/federal_offense/version.rb +5 -0
  36. data/lib/tasks/federal_offense_tasks.rake +9 -0
  37. metadata +283 -0
@@ -0,0 +1,6 @@
1
+ <% if messages.any? %>
2
+ <div class="empty">
3
+ <div class="empty-title"><%= t("federal_offense.unselected.title") %></div>
4
+ <div class="empty-subtitle"><%= t("federal_offense.unselected.subtitle") %></div>
5
+ </div>
6
+ <% end %>
@@ -0,0 +1,30 @@
1
+ <header class="message-header">
2
+ <table>
3
+ <tbody>
4
+ <tr>
5
+ <th><%= t("federal_offense.attributes.date") %></th>
6
+ <td><%= message.date %></td>
7
+ </tr>
8
+ <tr>
9
+ <th><%= t("federal_offense.attributes.from") %></th>
10
+ <td><%= message_array(message.from) %></td>
11
+ </tr>
12
+ <tr>
13
+ <th><%= t("federal_offense.attributes.to") %></th>
14
+ <td><%= message_array(message.to) %></td>
15
+ </tr>
16
+ <tr>
17
+ <th><%= t("federal_offense.attributes.subject") %></th>
18
+ <td><%= message.subject %></td>
19
+ </tr>
20
+ </tbody>
21
+ </table>
22
+ </header>
23
+ <iframe class="message-body" src="<%= federal_offense.message_path(message.id, raw: true) %>">
24
+ </iframe>
25
+ <%# <footer class="message-footer">
26
+ <ul class="tabs">
27
+ <li class="tab"><a href="#html">HTML</a></li>
28
+ <li class="tab"><a href="#text">Text</a></li>
29
+ </ul>
30
+ </footer> %>
@@ -0,0 +1,96 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Federal Offense: <%= message ? message.subject : "Inbox#{" (#{messages.size})" if messages.any?}" %></title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+ <%= stylesheet_link_tag "federal_offense/application", media: "all" %>
8
+ <% if FederalOffense.action_cable %>
9
+ <meta name="action-cable-url" content="<%= "#{federal_offense.messages_path}#{FederalOffense::Engine.cable_config.mount_path}" %>" />
10
+ <% end %>
11
+ </head>
12
+ <body>
13
+ <main>
14
+ <nav>
15
+ <ul class="nav-items">
16
+ <li class="nav-item nav-item--logo"><%= link_to "Federal Offense", federal_offense.messages_path %></li>
17
+ <li class="nav-item nav-item--subnav">
18
+ <ul class="nav-items">
19
+ <li class="nav-item">
20
+ <% if message.present? %>
21
+ <%=
22
+ link_to(
23
+ t("federal_offense.destroy.one"),
24
+ federal_offense.destroy_message_path(message.id),
25
+ data: {confirm: t("federal_offense.destroy.confirm_one")},
26
+ method: :post,
27
+ )
28
+ %>
29
+ <% else %>
30
+ <%=
31
+ link_to(
32
+ t("federal_offense.destroy.one"),
33
+ "#",
34
+ class: "nav-item-disabled",
35
+ disabled: true,
36
+ )
37
+ %>
38
+ <% end %>
39
+ </li>
40
+ <li class="nav-item">
41
+ <% if messages.any? %>
42
+ <%=
43
+ link_to(
44
+ t("federal_offense.destroy.all"),
45
+ federal_offense.destroy_all_messages_path,
46
+ data: {confirm: t("federal_offense.destroy.confirm_all")},
47
+ method: :post,
48
+ )
49
+ %>
50
+ <% else %>
51
+ <%=
52
+ link_to(
53
+ t("federal_offense.destroy.all"),
54
+ "#",
55
+ class: "nav-item-disabled",
56
+ disabled: true,
57
+ )
58
+ %>
59
+ <% end %>
60
+ </li>
61
+ </ul>
62
+ </li>
63
+ </ul>
64
+ </nav>
65
+ <article>
66
+ <aside>
67
+ <ul class="list">
68
+ <% if messages.any? %>
69
+ <% messages.each do |message| %>
70
+ <li class="list-item list-item--has-link list-item--<%= message.read? ? "read" : "unread" %><%= " list-item--active" if message == self.message %>">
71
+ <%= link_to federal_offense.message_path(message.id), class: "list-item-link" do %>
72
+ <span class="list-item-subtitle"><%= message_array(message.from) %></span>
73
+ <span class="list-item-title"><%= message.subject %></span>
74
+ <span class="list-item-body"><%= message.preview %></span>
75
+ <% end%>
76
+ </li>
77
+ <% end %>
78
+ <% else %>
79
+ <li class="list-item empty">
80
+ <div class="empty-title"><%= t("federal_offense.empty.title") %></div>
81
+ <div class="empty-subtitle"><%= t("federal_offense.empty.subtitle") %></div>
82
+ </li>
83
+ <% end %>
84
+ </ul>
85
+ </aside>
86
+ <% if messages.any? %>
87
+ <section>
88
+ <%= yield %>
89
+ </section>
90
+ <% end %>
91
+ </article>
92
+ </main>
93
+ <%= javascript_include_tag "federal_offense/application" %>
94
+ <%= javascript_include_tag "federal_offense/cable" if FederalOffense.action_cable %>
95
+ </body>
96
+ </html>
@@ -0,0 +1,18 @@
1
+ en:
2
+ federal_offense:
3
+ attributes:
4
+ date: "Date"
5
+ from: "From"
6
+ subject: "Subject"
7
+ to: "To"
8
+ destroy:
9
+ all: "Clear Inbox"
10
+ one: "Delete This Message"
11
+ confirm_all: "Are you sure you want to delete all the messages in the inbox?"
12
+ confirm_one: "Are you sure you want to delete this message?"
13
+ empty:
14
+ title: "Nothing to see here!"
15
+ subtitle: "Generate a message from ActionMailer and then come back here"
16
+ unselected:
17
+ title: "Select a message to view it here"
18
+ subtitle: "← look over there"
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ FederalOffense::Engine.routes.draw do |*args|
4
+ if FederalOffense::Engine.cable_server
5
+ mount FederalOffense::Engine.cable_server => FederalOffense::Engine.cable_config.mount_path
6
+ end
7
+
8
+ resources :messages, only: %i[index show], path: "" do
9
+ member do
10
+ post :destroy, as: :destroy, path: "destroy"
11
+ end
12
+
13
+ collection do
14
+ post :destroy_all
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "federal_offense/version"
4
+
5
+ module FederalOffense
6
+ class << self
7
+ attr_accessor :action_cable
8
+ end
9
+ end
10
+
11
+ require "federal_offense/engine" if defined? Rails
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "federal_offense/interceptor"
4
+
5
+ module FederalOffense
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace FederalOffense
8
+
9
+ class << self
10
+ attr_accessor :cable_server
11
+
12
+ def cable_config
13
+ @cable_config ||= ActionCable::Server::Configuration.new.tap do |config|
14
+ config.logger = Rails.logger
15
+ config.connection_class = -> { FederalOffense::ApplicationCable::Connection }
16
+ config.mount_path = "cable"
17
+ end
18
+ end
19
+ end
20
+
21
+ # Precompile the assets we need to run this thing
22
+ initializer "federal_offense.assets.precompile" do |app|
23
+ app.config.assets.precompile += %w[federal_offense/application.css federal_offense/application.js federal_offense/cable.js]
24
+ end
25
+
26
+ # Register as an interceptor of outbound emails
27
+ initializer "action_mailer" do |app|
28
+ if Rails.env.production?
29
+ abort %{[FEDERAL OFFENSE] CRITICAL NIGHTMARE SCENARIO: YOU INSTALLED FEDERAL OFFENSE IN PRODUCTION\n\nPlease ensure `gem "federal_offense"` appears only in your development Gemfile group (and maybe test, but even that's stretching it).}
30
+ end
31
+
32
+ ActionMailer::Base.register_interceptor(FederalOffense::Interceptor)
33
+ end
34
+
35
+ # Enable ActionCable connections in the inbox for auto-reload
36
+ initializer "action_cable_connection" do |app|
37
+ # Find cable configs
38
+ federal_offense_config_path = Rails.root.join("config", "federal_offense_cable.yml")
39
+ app_config_path = Rails.root.join("config", "cable.yml")
40
+
41
+ # Determine which config we're going to use
42
+ config = if File.exist?(federal_offense_config_path)
43
+ app.config_for(federal_offense_config_path).with_indifferent_access
44
+ elsif File.exist?(app_config_path)
45
+ app.config_for(app_config_path).with_indifferent_access
46
+ else
47
+ # Default to an async cable cause whatever
48
+ {adapter: "async"}
49
+ end
50
+
51
+ # Assign the values to the cable config and create a server
52
+ self.class.cable_config.cable = config
53
+ self.class.cable_server = ActionCable::Server::Base.new(config: self.class.cable_config)
54
+ FederalOffense.action_cable = true
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FederalOffense
4
+ class Interceptor
5
+ def self.delivering_email(message)
6
+ FederalOffense::Message.create(message)
7
+ FederalOffense::InboxChannel.broadcast!
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FederalOffense
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :federal_offense do
4
+ desc "Clear out the cached messages in Federal Offense"
5
+ task clear_inbox: :environment do
6
+ require "federal_offense"
7
+ FederalOffense::Message.destroy_all
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,283 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: federal_offense
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Flip Sasser
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 6.0.3.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '6.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 6.0.3.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: capybara
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: pry-rails
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.9'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.9'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec-rails
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.8'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.8'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop-ordered_methods
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.6'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.6'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop-performance
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 1.5.2
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 1.5.2
131
+ - !ruby/object:Gem::Dependency
132
+ name: rubocop-rails
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 2.5.2
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: 2.5.2
145
+ - !ruby/object:Gem::Dependency
146
+ name: rubocop-rspec
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '1.39'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '1.39'
159
+ - !ruby/object:Gem::Dependency
160
+ name: simplecov
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: sqlite3
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: standard
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '0.4'
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: '0.4'
201
+ - !ruby/object:Gem::Dependency
202
+ name: timecop
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ description: Federal Offense intercepts outbound emails in Rails and allows you to
216
+ preview them in a user-configurable mounted location
217
+ email:
218
+ - hello@flipsasser.com
219
+ executables: []
220
+ extensions: []
221
+ extra_rdoc_files: []
222
+ files:
223
+ - MIT-LICENSE
224
+ - README.md
225
+ - Rakefile
226
+ - app/assets/config/federal_offense_manifest.js
227
+ - app/assets/javascripts/federal_offense/application.js
228
+ - app/assets/javascripts/federal_offense/cable.js
229
+ - app/assets/javascripts/federal_offense/vendor/action_cable.js
230
+ - app/assets/stylesheets/federal_offense/application.css
231
+ - app/assets/stylesheets/federal_offense/components/article.css
232
+ - app/assets/stylesheets/federal_offense/components/aside.css
233
+ - app/assets/stylesheets/federal_offense/components/empty.css
234
+ - app/assets/stylesheets/federal_offense/components/link.css
235
+ - app/assets/stylesheets/federal_offense/components/list.css
236
+ - app/assets/stylesheets/federal_offense/components/main.css
237
+ - app/assets/stylesheets/federal_offense/components/message.css
238
+ - app/assets/stylesheets/federal_offense/components/nav.css
239
+ - app/assets/stylesheets/federal_offense/components/section.css
240
+ - app/assets/stylesheets/federal_offense/components/table.css
241
+ - app/channels/federal_offense/application_cable/channel.rb
242
+ - app/channels/federal_offense/application_cable/connection.rb
243
+ - app/channels/federal_offense/inbox_channel.rb
244
+ - app/controllers/federal_offense/application_controller.rb
245
+ - app/controllers/federal_offense/messages_controller.rb
246
+ - app/helpers/federal_offense/application_helper.rb
247
+ - app/models/federal_offense/message.rb
248
+ - app/views/federal_offense/messages/index.html.erb
249
+ - app/views/federal_offense/messages/show.html.erb
250
+ - app/views/layouts/federal_offense/application.html.erb
251
+ - config/locales/en.yml
252
+ - config/routes.rb
253
+ - lib/federal_offense.rb
254
+ - lib/federal_offense/engine.rb
255
+ - lib/federal_offense/interceptor.rb
256
+ - lib/federal_offense/version.rb
257
+ - lib/tasks/federal_offense_tasks.rake
258
+ homepage: https://github.com/flipsasser/federal_offense
259
+ licenses:
260
+ - MIT
261
+ metadata:
262
+ homepage_uri: https://github.com/flipsasser/federal_offense
263
+ source_code_uri: https://github.com/flipsasser/federal_offense
264
+ post_install_message:
265
+ rdoc_options: []
266
+ require_paths:
267
+ - lib
268
+ required_ruby_version: !ruby/object:Gem::Requirement
269
+ requirements:
270
+ - - ">="
271
+ - !ruby/object:Gem::Version
272
+ version: 2.3.0
273
+ required_rubygems_version: !ruby/object:Gem::Requirement
274
+ requirements:
275
+ - - ">="
276
+ - !ruby/object:Gem::Version
277
+ version: '0'
278
+ requirements: []
279
+ rubygems_version: 3.0.3
280
+ signing_key:
281
+ specification_version: 4
282
+ summary: Everyone knows it's a federal offense to mess with the mail!
283
+ test_files: []