From 05711b6c7f4e89b1dcc1a87d43e46e8f2d5741c9 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Wed, 10 May 2017 22:40:01 -0700 Subject: [PATCH 01/10] Use https:// for password reset --- app/password_reset.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/password_reset.rb b/app/password_reset.rb index 2328c356..81383a9e 100644 --- a/app/password_reset.rb +++ b/app/password_reset.rb @@ -21,7 +21,7 @@ post '/send_password_reset' do body = <<-EOT Hello! This is the Neocities cat, and I have received a password reset request for your e-mail address. -Go to this URL to reset your password: http://neocities.org/password_reset_confirm?username=#{Rack::Utils.escape(site.username)}&token=#{token} +Go to this URL to reset your password: https://neocities.org/password_reset_confirm?username=#{Rack::Utils.escape(site.username)}&token=#{token} If you didn't request this password reset, you can ignore it. Or hide under a bed. Or take a nap. Your call. From 73ec6132836606044721e1afa3dd646579a12d02 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Wed, 10 May 2017 22:41:13 -0700 Subject: [PATCH 02/10] replace some http:// links with https:// --- views/_footer.erb | 2 +- views/_news.erb | 2 +- views/_share.erb | 10 +++++----- views/dashboard.erb | 2 +- views/permanent_web.erb | 4 ++-- views/templates/index.erb | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/views/_footer.erb b/views/_footer.erb index 8b5cfdaa..10423df3 100644 --- a/views/_footer.erb +++ b/views/_footer.erb @@ -3,7 +3,7 @@

- Neocities is open source. Follow us on Twitter or Facebook + Neocities is open source. Follow us on Twitter or Facebook

diff --git a/views/site_files/mount_info.erb b/views/site_files/mount_info.erb index c3015a9e..4b9e6f20 100644 --- a/views/site_files/mount_info.erb +++ b/views/site_files/mount_info.erb @@ -1,7 +1,7 @@

Mount your site

-

Now you can access your Neocities site as a drive on your computer!

+

Access your Neocities site as a drive on your computer

@@ -10,7 +10,7 @@

About

- Neocities now supports WebDAV, which allows you to mount your Neocities share on your computer. Now you can access and change your files on your own computer's file manager! + Neocities supports WebDAV, which allows you to mount your Neocities share on your computer.

<% if current_site.nil? %> @@ -22,20 +22,24 @@ This feature requires a supporter account. Click here to become a supporter.

<% else %> -

Instructions for Windows 7

+

Instructions for Windows

- Use these instructions, except use this URL to connect: https://neocities.org/webdav -
- Enter your login info when requested. -

+ Unfortunately, the WebDAV that comes with Windows file manager has issues with SSL, + and the problem has not yet been fixed. We recommend using a client like Cyberduck with Windows, which is free and has + WebDAV support. You can also try Mountain Duck + which will allow you to mount your Neocities site as a hard drive on your computer.

Instructions for OSX

- Use these instructions, and use this URL to connect: https://neocities.org/webdav -
- Enter login info when requested. + Use these instructions, and use this URL to connect: https://neocities.org/webdav +
+ Enter login info when requested. +

+ +

+ You can also try out Cyberduck or Mountain Duck if you run into any issues.

Instructions for Linux (Ubuntu)

From 4a2926508e21e5d43193f96aed111172c25a0ff4 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 21 May 2017 17:32:26 -0500 Subject: [PATCH 08/10] api: add upload_hash for checking file hash before uploading --- app/api.rb | 16 ++++++++++++++++ models/site.rb | 6 ++++++ tests/api_tests.rb | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/app/api.rb b/app/api.rb index 18036eba..5faa25e4 100644 --- a/app/api.rb +++ b/app/api.rb @@ -5,6 +5,22 @@ get '/api' do erb :'api' end +post '/api/upload_hash' do + require_api_credentials + + res = {} + + if params[:files].blank? || !params[:files].is_a?(Hash) + api_error 400, 'no_file_hashes_provided', 'no file hashes provided' + end + + params[:files].each do |k,v| + res[k] = current_site.sha1_hash_match? k, v + end + + api_success files: res +end + get '/api/list' do require_api_credentials diff --git a/models/site.rb b/models/site.rb index cf3ce200..928d7088 100644 --- a/models/site.rb +++ b/models/site.rb @@ -1512,6 +1512,12 @@ class Site < Sequel::Model save_changes validate: false end + def sha1_hash_match?(path, sha1_hash) + relative_path = scrubbed_path path + site_file = site_files_dataset.where(path: relative_path, sha1_hash: sha1_hash).first + !site_file.nil? + end + private def store_file(path, uploaded, opts={}) diff --git a/tests/api_tests.rb b/tests/api_tests.rb index 5e894c11..30e2d97c 100644 --- a/tests/api_tests.rb +++ b/tests/api_tests.rb @@ -222,6 +222,39 @@ describe 'api key' do end end +describe 'api upload hash' do + it 'succeeds' do + create_site + basic_authorize @user, @pass + test_hash = Digest::SHA1.file('./tests/files/test.jpg').hexdigest + + post '/api/upload', { + 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'), + 'test2.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + } + + post '/api/upload_hash', "files[test.jpg]" => test_hash, "files[test2.jpg]" => Digest::SHA1.hexdigest('herpderp') + + res[:result].must_equal 'success' + res[:files][:'test.jpg'].must_equal true + res[:files][:'test2.jpg'].must_equal false + end + + it 'throws error for missing data' do + create_site + basic_authorize @user, @pass + post '/api/upload_hash' + res[:error_type].must_equal 'no_file_hashes_provided' + end + + it 'throws errors for weird data' do + create_site + basic_authorize @user, @pass + post '/api/upload_hash', 'files[]' => 'DUMPSTER FIRE' + res[:error_type].must_equal 'no_file_hashes_provided' + end +end + describe 'api upload' do it 'fails with no auth' do post '/api/upload' From 61bf9012d686c02a1bc5964a67dbeb2096c05767 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 21 May 2017 20:12:47 -0700 Subject: [PATCH 09/10] dont set cookie for api calls --- app.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app.rb b/app.rb index 0dc4422a..52accc05 100644 --- a/app.rb +++ b/app.rb @@ -77,6 +77,12 @@ before do end end +after do + if @api + request.session_options[:skip] = true + end +end + #after do #response.headers['Content-Security-Policy'] = %{block-all-mixed-content; default-src 'self'; connect-src 'self' https://api.stripe.com; frame-src https://www.google.com/recaptcha/ https://js.stripe.com; script-src 'self' 'unsafe-inline' https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ https://js.stripe.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: } #end From bf089379aa75a818c8a54c7d86ed5f3a97e56f19 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sun, 21 May 2017 20:16:37 -0700 Subject: [PATCH 10/10] fixes for upload hash check, catch index.html delete scenario --- app/api.rb | 12 +++--------- tests/api_tests.rb | 16 +--------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/app/api.rb b/app/api.rb index 5faa25e4..60884132 100644 --- a/app/api.rb +++ b/app/api.rb @@ -7,17 +7,11 @@ end post '/api/upload_hash' do require_api_credentials - res = {} - - if params[:files].blank? || !params[:files].is_a?(Hash) - api_error 400, 'no_file_hashes_provided', 'no file hashes provided' - end - - params[:files].each do |k,v| + files = [] + params.each do |k,v| res[k] = current_site.sha1_hash_match? k, v end - api_success files: res end @@ -101,7 +95,7 @@ post '/api/delete' do api_error 400, 'missing_files', "#{path} was not found on your site, canceled deleting" end - if path == 'index.html' + if path == 'index.html' || path == '/index.html' api_error 400, 'cannot_delete_index', 'you cannot delete your index.html file, canceled deleting' end diff --git a/tests/api_tests.rb b/tests/api_tests.rb index 30e2d97c..e7fdc281 100644 --- a/tests/api_tests.rb +++ b/tests/api_tests.rb @@ -233,26 +233,12 @@ describe 'api upload hash' do 'test2.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') } - post '/api/upload_hash', "files[test.jpg]" => test_hash, "files[test2.jpg]" => Digest::SHA1.hexdigest('herpderp') + post '/api/upload_hash', "test.jpg" => test_hash, "test2.jpg" => Digest::SHA1.hexdigest('herpderp') res[:result].must_equal 'success' res[:files][:'test.jpg'].must_equal true res[:files][:'test2.jpg'].must_equal false end - - it 'throws error for missing data' do - create_site - basic_authorize @user, @pass - post '/api/upload_hash' - res[:error_type].must_equal 'no_file_hashes_provided' - end - - it 'throws errors for weird data' do - create_site - basic_authorize @user, @pass - post '/api/upload_hash', 'files[]' => 'DUMPSTER FIRE' - res[:error_type].must_equal 'no_file_hashes_provided' - end end describe 'api upload' do