neocities/app.rb

146 lines
4.6 KiB
Ruby
Raw Permalink Normal View History

require './environment.rb'
require './app_helpers.rb'
2013-05-25 17:09:48 -07:00
use Rack::Session::Cookie, key: 'neocities',
path: '/',
expire_after: 31556926, # one year in seconds
secret: Base64.strict_decode64($config['session_secret']),
httponly: true,
same_site: :lax,
secure: ENV['RACK_ENV'] == 'production'
2013-05-25 17:09:48 -07:00
use Rack::TempfileReaper
2013-06-16 11:44:18 -07:00
helpers do
def site_change_file_display_class(filename)
return 'html' if filename.match(Site::HTML_REGEX)
return 'image' if filename.match(Site::IMAGE_REGEX)
'misc'
end
2014-08-01 11:56:51 -07:00
def csrf_token_input_html
%{<input name="csrf_token" type="hidden" value="#{csrf_token}">}
end
2020-11-25 18:54:04 -06:00
2020-11-26 01:45:23 -06:00
def hcaptcha_input
%{
<script src="https://hcaptcha.com/1/api.js" async defer></script>
2021-12-03 12:04:00 -06:00
<div id="captcha_input" class="h-captcha" data-sitekey="#{$config['hcaptcha_site_key']}"></div>
2020-11-26 01:45:23 -06:00
}
end
end
set :protection, :frame_options => "DENY"
2015-03-26 11:53:41 -07:00
GEOCITIES_NEIGHBORHOODS = %w{
area51
athens
augusta
baja
bourbonstreet
capecanaveral
capitolhill
collegepark
colosseum
enchantedforest
hollywood
motorcity
napavalley
nashville
petsburgh
pipeline
rainforest
researchtriangle
siliconvalley
soho
sunsetstrip
timessquare
televisioncity
tokyo
vienna
2022-07-18 18:51:31 +03:00
westhollywood
yosemite
}.freeze
def redirect_to_internet_archive_for_geocities_sites
match = request.path.match /^\/(\w+)\/.+$/i
if match && GEOCITIES_NEIGHBORHOODS.include?(match.captures.first.downcase)
redirect "https://wayback.archive.org/http://geocities.com/#{request.path}"
end
end
2025-04-15 15:34:47 -05:00
WHITELISTED_POST_PATHS = ['/create_validate_all', '/create_validate', '/create'].freeze
2013-06-22 19:52:03 -07:00
before do
if request.path.match /^\/api\//i
2014-04-10 22:36:02 -07:00
@api = true
2014-04-06 23:57:35 -04:00
content_type :json
elsif request.path.match /^\/webhooks\//
# Skips the CSRF/validation check for stripe web hooks
2024-04-08 15:39:04 -05:00
elsif current_site && current_site.email_not_validated? && !(request.path =~ /^\/site\/.+\/confirm_email|^\/settings\/change_email|^\/welcome|^\/supporter|^\/signout/)
redirect "/site/#{current_site.username}/confirm_email"
2024-04-08 15:39:04 -05:00
elsif current_site && current_site.phone_verification_needed? && !(request.path =~ /^\/site\/.+\/confirm_email|^\/settings\/change_email|^\/site\/.+\/confirm_phone|^\/welcome|^\/supporter|^\/signout/)
2023-11-09 14:55:48 -06:00
redirect "/site/#{current_site.username}/confirm_phone"
2024-04-08 17:45:20 -05:00
elsif current_site && current_site.tutorial_required && !(request.path =~ /^\/site\/.+\/confirm_email|^\/settings\/change_email|^\/site\/.+\/confirm_phone|^\/welcome|^\/supporter|^\/tutorial\/.+/)
2024-04-08 15:12:56 -05:00
redirect '/tutorial/html/1'
else
content_type :html, 'charset' => 'utf-8'
2025-04-15 15:34:47 -05:00
redirect '/' if request.post? && !WHITELISTED_POST_PATHS.include?(request.path_info) && !csrf_safe?
end
if params[:page]
params[:page] = params[:page].to_s
unless params[:page] =~ /^\d+$/ && params[:page].to_i > 0
params[:page] = '1'
end
end
if params[:tag]
begin
params.delete 'tag' if params[:tag].nil? || !params[:tag].is_a?(String) || params[:tag].strip.empty? || params[:tag].match?(Tag::INVALID_TAG_REGEX)
2025-04-23 04:49:48 +00:00
rescue Encoding::CompatibilityError, ArgumentError
params.delete 'tag'
end
end
end
2017-05-21 20:12:47 -07:00
after do
if @api || (!signed_in? && request.path == '/')
2017-05-21 20:12:47 -07:00
request.session_options[:skip] = true
else
# Set issue timestamp on session cookie if it doesn't exist yet
session['i'] = Time.now.to_i if session && !session['i'] && session['id']
2017-05-21 20:12:47 -07:00
end
unless self.class.development?
response.headers['Content-Security-Policy'] = %{default-src 'self' data: blob: 'unsafe-inline'; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval' https://hcaptcha.com https://*.hcaptcha.com https://js.stripe.com; style-src 'self' 'unsafe-inline' https://hcaptcha.com https://*.hcaptcha.com; connect-src 'self' https://hcaptcha.com https://*.hcaptcha.com https://api.stripe.com; frame-src 'self' https://hcaptcha.com https://*.hcaptcha.com https://js.stripe.com}
end
end
2013-07-13 10:45:15 -04:00
not_found do
2016-10-26 21:34:53 -05:00
api_not_found if @api
redirect_to_internet_archive_for_geocities_sites
2015-06-03 14:51:34 -07:00
@title = 'Not Found'
2014-04-22 15:03:29 -07:00
erb :'not_found'
2013-07-13 10:45:15 -04:00
end
2013-07-13 11:01:13 -04:00
error do
2024-04-09 18:06:25 -05:00
=begin
2013-07-13 11:01:13 -04:00
EmailWorker.perform_async({
from: 'web@neocities.org',
to: 'errors@neocities.org',
2014-04-29 00:03:48 -07:00
subject: "[Neocities Error] #{env['sinatra.error'].class}: #{env['sinatra.error'].message}",
2015-05-10 09:17:32 +00:00
body: erb(:'templates/email/error', layout: false),
no_footer: true
2013-07-13 11:01:13 -04:00
})
2024-04-09 18:06:25 -05:00
=end
2013-07-13 11:01:13 -04:00
2014-04-10 22:36:02 -07:00
if @api
2014-09-15 03:15:25 -07:00
api_error 500, 'server_error', 'there has been an unknown server error, please try again later'
2014-04-10 22:36:02 -07:00
end
2014-04-22 15:03:29 -07:00
erb :'error'
2013-07-13 11:01:13 -04:00
end
Dir['./app/**/*.rb'].each {|f| require f}