/
autoload.rb
244 lines (204 loc) · 11.4 KB
/
autoload.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
##########################################################
##########################################################
## ______ _____ ##
## / ____/___ ____ / __(_)___ _ ##
## / / / __ \/ __ \/ /_/ / __ `/ ##
## / /___/ /_/ / / / / __/ / /_/ / ##
## \____/\____/_/ /_/_/ /_/\__, / ##
## /____/ ##
##########################################################
##########################################################
# => Load
# => This replaces individual requires with bundled gems
# => https://stackoverflow.com/a/1712669/1143732
require 'bundler'
# => Pulls in all Gems
# => Replaces the need for individual gems
Bundler.require :default, ENV.fetch("RACK_ENV", "development") if defined?(Bundler) # => ENVIRONMENT only used here, can do away with constant if necessary
##################################################
##################################################
## Zeitwerk ##
## This should really have bundler stuff ##
## https://www.oreilly.com/library/view/sinatra-up-and/9781449306847/ch04.html ##
loader = Zeitwerk::Loader.new
%w(app/controllers app/models app/helpers app/drops app/tags app/filters lib config).each do |d|
loader.push_dir(d)
end
loader.enable_reloading # you need to opt-in before setup
loader.inflector.inflect "omniauth" => "OmniAuth" # required to get the custom hmrc strategy to load
loader.inflector.inflect "hmrc" => "HMRC" # required to get the custom hmrc strategy to load
loader.setup
##################################################
##################################################
## ExecJS (RPECK 16/01/2020) ##
## This was required locally because Ruby 3.0.0 messed up the way in which File.open is called (the following file is changed on line 178) ##
require_relative '../lib/execjs/external_runtime' if Gem.win_platform?
##################################################
##################################################
# => Eager Loading
# => This is required to mitigate a number of conflicts/errors due to the eager loading at the end of the file
# => I had to include eager loading because of the way in which Liquid needed to load tags globally (which was not happening without the eager load)
%w(../lib/execjs ../config/deploy).each do |path|
loader.ignore("#{__dir__}/#{path}")
end
##################################################
##################################################
# => Base
# => This is used to give us a general set of config options
# => No, it's not the simplest way to do it, but it works
class Autoload < Sinatra::Base
# => Register
# => This allows us to call the various extensions for the system
register Sinatra::Auth # => My own Warden implementation extracted into a Sinatra module (./lib/sinatra/auth.rb)
register Sinatra::Cors # => Protects from unauthorized domain activity
register Sinatra::ConfigFile # => Allows us to use a config file (YAML) instead of declaring all settings here
register Sinatra::OmniAuth # => This is my own implementation of several routes which are required for omniauth. SHOULD BE MOVED ELSEWHERE
register Sinatra::Hooks # => lib/sinatra/hooks (allows us to use Wordpress-style hooks)
register Padrino::Helpers # => number_to_currency (https://github.com/padrino/padrino-framework/blob/master/padrino-helpers/lib/padrino-helpers.rb#L22)
register Sinatra::RespondWith # => http://sinatrarb.com/contrib/respond_with
register Sinatra::MultiRoute # => Multi Route (allows for route :put, :delete)
register Sinatra::Namespace # => Namespace (http://sinatrarb.com/contrib/namespace.html)
register Sinatra::I18nSupport # => Locales (https://www.rubydoc.info/gems/sinatra-support/1.2.2/Sinatra/I18nSupport) -- dependent on sinatra-support gem (!)
register Sinatra::ActiveRecordExtension # => Required to use the ActiveRecord extension for Sinatra
# => Rack (Flash/Sessions etc)
# => Allows us to use the "flash" object (rack-flash3)
# => Required to get redirect_with_flash working
use Rack::Deflater # => Compresses responses generated at server level
use Rack::Session::Cookie, secret: ENV.fetch("SECRET", "62uao31c7d7j7dy6se9hs5auxyupmay") # => could use enable :sessions instead (http://sinatrarb.com/faq.html#sessions)
use Rack::Flash, accessorize: [:notice, :error], sweep: true
use Rack::MethodOverride # => used for DELETE requests (logout etc) - https://stackoverflow.com/a/5169913 // http://sinatrarb.com/configuration.html#method_override---enabledisable-the-post-_method-hack
# => OmniAuth
# => This allows us to build the various providers required for connecting with Omniauth
# => https://gist.github.com/gorenje/2895009/87ca24478ee19eb7bfa557b98221a177d714e16c
use OmniAuth::Builder do
provider :hmrc_vat, ENV.fetch("HMRC_CLIENT_ID"), ENV.fetch("HMRC_CLIENT_SECRET")
end
# => HTMLCompressor
# => Used to minify HTML output (removes bloat and other nonsense)
unless settings.development?
use HtmlCompressor::Rack,
compress_css: false, # => already done by webpack
compress_javascript: false, # => already done by webpack
enabled: true,
preserve_line_breaks: false,
remove_comments: true,
remove_form_attributes: false,
remove_http_protocol: false,
remove_https_protocol: false,
remove_input_attributes: true,
remove_intertag_spaces: true,
remove_javascript_protocol: true,
remove_link_attributes: true,
remove_multi_spaces: true,
remove_quotes: true,
remove_script_attributes: true,
remove_style_attributes: true,
simple_boolean_attributes: true,
simple_doctype: false
end
# => Helpers
# => Allows us to manage the system at its core
helpers Sinatra::RequiredParams # => Required Parameters (ensures we have certain params for different routes)
helpers Sinatra::RedirectWithFlash # => Used to provide "flash" functionality with redirect helper
##########################################################
##########################################################
# => Development
# => Ensures we're only loading in development environment
configure :development do
register Sinatra::Reloader # => http://sinatrarb.com/contrib/reloader
end
# => Staging
# => Manage staging environment to ensure the system is protected from unwanted attention
configure :staging do
use Rack::Attack # => allows us to block access etc
Rack::Attack.safelist_ip("86.22.69.208")
Rack::Attack.blocklist("block all access") { |request| request.path.start_with? "/" }
end
# => Logging
# => Enable logging for production & development
# => https://nickcharlton.net/posts/structuring-sinatra-applications.html
configure :production do
enable :logging
end
##########################################################
##########################################################
# => Config
# => Allows us to define config options and Sinatra will automatically populate them in the config of the app
# => http://sinatrarb.com/contrib/config_file#label-Sinatra%3A%3AConfigFile
config_file File.join(__dir__,"/settings.yml")
# => Locales
# => This had to be included to ensure we can use the various locales required by Auth + others
load_locales File.join(root, "..", "config", "locales") # => requires Sinatra::I18nSupport
##########################################################
##########################################################
# => Terser
# => Quicker/better than Uglifier and supports ES6 (RPECK 16/01/2021)
Sprockets.register_compressor 'application/javascript', :terser, Terser::Compressor
# => Register
# => Needs to be below definitions
register Sinatra::AssetPipeline
##########################################################
##########################################################
# => Config
# => This is for the layout (calling sprockets helpers etc)
# => https://github.com/petebrowne/sprockets-helpers#setup
configure do
# => RailsAssets
# => Required to get Rails Assets gems working with Sprockets/Sinatra
# => https://github.com/rails-assets/rails-assets-sinatra#applicationrb
RailsAssets.load_paths.each { |path| settings.sprockets.append_path(path) } if defined?(RailsAssets)
# => Gems
# => Any gems in the "assets" group need to be loaded
Bundler.load.current_dependencies.select{|dep| dep.groups.include?(:assets) }.map(&:name).each do |gem| # => https://stackoverflow.com/a/35183285/1143732
%w[stylesheets javascripts].each do |item|
sprockets.append_path File.join(Bundler.rubygems.find_name(gem).first.full_gem_path, 'vendor', 'assets', item)
sprockets.append_path File.join(Bundler.rubygems.find_name(gem).first.full_gem_path, 'app', 'assets', item)
end
end
# => Paths
# => Used to add assets to asset pipeline
%w(stylesheets javascripts images fonts).each do |folder|
sprockets.append_path File.join(root, 'assets', folder)
sprockets.append_path File.join(root, '..', 'vendor', 'assets', folder)
end #paths
# => Pony
# => SMTP used to send email to account owner
# => https://github.com/benprew/pony#default-options
Pony.options = {
via: :smtp,
via_options: {
address: settings.smtp[:host],
port: settings.smtp[:port],
domain: settings.domain,
user_name: settings.smtp[:user],
password: settings.smtp[:password],
authentication: settings.smtp[:authentication],
enable_starttls_auto: settings.smtp[:starttls]
}
} #pony
# => Liquid
# => Allows us to define the Liquid templating system and other things here
Liquid::Template.file_system = Liquid::LocalFileSystem.new File.join(views, 'partials')
end #configure
##############################################################
##############################################################
# => Errors
# => https://blog.iphoting.com/blog/2012/04/22/custom-404-error-pages-with-sinatra-dot-rb/
# => https://github.com/vast/sinatra-redirect-with-flash
# => https://stackoverflow.com/questions/25299186/sinatra-error-handling-in-ruby
error 400..510 do
respond_with :index, name: "error" do |format|
format.js { {error: env['sinatra.error'].class.name.demodulize }.to_json }
format.html { redirect "/", error: env['sinatra.error'].class.name.demodulize }
end
end
##############################################################
##############################################################
end
##########################################################
##########################################################
# => Eagerload
# => This is used to laod the files that are required to run the app (I had to do this so the Liquid::Template could be registered)
loader.eager_load # => required to get the Liquid Tags to register globally (otherwise would have to do it manually for each one)
##########################################################
##########################################################