diff --git a/Gemfile b/Gemfile
index a39a03f..eef60c6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -50,6 +50,10 @@ gem 'kamal', '~> 1.3'
gem 'litestack', '~> 0.4.2'
+gem 'active_storage_validations', '~> 1.1'
+gem 'aws-sdk-s3', '~> 1.141'
+gem 'inline_svg', '~> 1.9'
+
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"
@@ -60,6 +64,8 @@ end
group :development do
# Use console on exceptions pages [https://github.com/rails/web-console]
+ gem 'annotate', '~> 3.2'
+ gem 'erb-formatter', '~> 0.6.0'
gem 'rubocop', '~> 1.59'
gem 'web-console'
@@ -69,11 +75,3 @@ group :development do
# Speed up commands on slow machines / big apps [https://github.com/rails/spring]
# gem "spring"
end
-
-gem 'inline_svg', '~> 1.9'
-
-gem 'annotate', '~> 3.2'
-
-gem 'erb-formatter', '~> 0.6.0'
-
-gem "active_storage_validations", "~> 1.1"
diff --git a/Gemfile.lock b/Gemfile.lock
index 1a69ddc..1a82eca 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -84,6 +84,22 @@ GEM
activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0)
ast (2.4.2)
+ aws-eventstream (1.3.0)
+ aws-partitions (1.868.0)
+ aws-sdk-core (3.190.0)
+ aws-eventstream (~> 1, >= 1.3.0)
+ aws-partitions (~> 1, >= 1.651.0)
+ aws-sigv4 (~> 1.8)
+ jmespath (~> 1, >= 1.6.1)
+ aws-sdk-kms (1.75.0)
+ aws-sdk-core (~> 3, >= 3.188.0)
+ aws-sigv4 (~> 1.1)
+ aws-sdk-s3 (1.141.0)
+ aws-sdk-core (~> 3, >= 3.189.0)
+ aws-sdk-kms (~> 1)
+ aws-sigv4 (~> 1.8)
+ aws-sigv4 (1.8.0)
+ aws-eventstream (~> 1, >= 1.0.2)
base64 (0.2.0)
bcrypt_pbkdf (1.1.0)
bigdecimal (3.1.4)
@@ -130,6 +146,7 @@ GEM
jbuilder (2.11.5)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
+ jmespath (1.6.2)
json (2.7.1)
kamal (1.3.0)
activesupport (>= 7.0)
@@ -302,6 +319,7 @@ PLATFORMS
DEPENDENCIES
active_storage_validations (~> 1.1)
annotate (~> 3.2)
+ aws-sdk-s3 (~> 1.141)
bootsnap
debug
erb-formatter (~> 0.6.0)
diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb
index 479fe79..c000e9c 100644
--- a/app/controllers/errors_controller.rb
+++ b/app/controllers/errors_controller.rb
@@ -1,9 +1,9 @@
class ErrorsController < ApplicationController
def not_found
- render status: 404
+ render status: :not_found
end
def internal_server_error
- render status: 500
+ render status: :internal_server_error
end
end
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 5a476b3..90a555b 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -2,7 +2,8 @@
class UploadsController < ApplicationController
include ActiveStorage::SetCurrent
- include ActionController::Live
+
+ skip_before_action :verify_authenticity_token, only: %i[upload preview]
def new
@upload = Upload.new(expiry: 10.minutes.from_now, remaining_uses: 1)
@@ -26,28 +27,28 @@ def upload
def preview
@upload = upload_scope.where(previewed: false).find_by!(key: params[:id])
@upload.update!(previewed: true)
- respond_to do |format|
- format.html { render :preview, status: :not_found }
- end
+ render :preview
end
def download
@upload = upload_scope.find_by!(key: params[:id])
@upload.decrement!(:remaining_uses)
- redirect_to rails_blob_path(@upload.data, disposition: 'attachment')
- # send_data @upload.data.download, filename: @upload.data.filename.to_s, content_type: @upload.data.content_type
+ redirect_to(@upload.data.url(disposition: 'attachment', filename: @upload.data.filename.to_s),
+ allow_other_host: true)
end
private
def upload_scope
- Upload.where('expiry > ?', DateTime.now).where('remaining_uses > ?', 0)
+ Upload
+ # Upload.where('expiry > ?', DateTime.now).where('remaining_uses > ?', 0)
end
# Only allow a list of trusted parameters through.
def upload_params
params
.require(:upload).permit(:data, :expiry, :remaining_uses)
+ .with_defaults(expiry: 10.minutes.from_now, remaining_uses: 1)
end
end
diff --git a/app/models/upload.rb b/app/models/upload.rb
index ed1d953..074d38b 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -21,6 +21,8 @@ class Upload < ApplicationRecord
validates :data, attached: true, size: { less_than: 512.kilobytes, message: 'is must be smaller than 512 kb' }
+ def url; end
+
def to_param
key
end
diff --git a/app/views/application/home.html.erb b/app/views/application/home.html.erb
index 375fd26..a41f9f1 100644
--- a/app/views/application/home.html.erb
+++ b/app/views/application/home.html.erb
@@ -71,7 +71,8 @@
- curl -X POST -F "data=@yourfile.txt" https://datadeaddrop.com/drop
+ curl -X POST -F "upload[data]=@your-file.txt"
+ https://datadeaddrop.com/u.json
@@ -117,7 +118,8 @@
- curl -O https://datadeaddrop.com/grab/your-easy-to-remember-url
+ curl -L http://datadeaddrop.com/d/your-secret-url.json >
+ your-file.txt
diff --git a/app/views/errors/internal_server_error.json.jbuilder b/app/views/errors/internal_server_error.json.jbuilder
new file mode 100644
index 0000000..1cca0c7
--- /dev/null
+++ b/app/views/errors/internal_server_error.json.jbuilder
@@ -0,0 +1,2 @@
+
+json.error "Not found"
diff --git a/app/views/errors/not_found.json.jbuilder b/app/views/errors/not_found.json.jbuilder
new file mode 100644
index 0000000..1cca0c7
--- /dev/null
+++ b/app/views/errors/not_found.json.jbuilder
@@ -0,0 +1,2 @@
+
+json.error "Not found"
diff --git a/app/views/uploads/_upload.json.jbuilder b/app/views/uploads/_upload.json.jbuilder
index 259d6b0..fce89e7 100644
--- a/app/views/uploads/_upload.json.jbuilder
+++ b/app/views/uploads/_upload.json.jbuilder
@@ -1,5 +1,5 @@
# frozen_string_literal: true
-json.extract! upload, :id, :path, :data, :expiry, :remaining_uses, :previewed, :created_at, :updated_at
-json.url upload_url(upload, format: :json)
-json.data url_for(upload.data)
+json.extract! upload, :key, :expiry, :remaining_uses, :created_at
+json.url Rails.application.routes.url_helpers.download_url(upload)
+json.name upload.data.filename.to_s
diff --git a/config/application.rb b/config/application.rb
index 798c662..6025d29 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -43,5 +43,7 @@ class Application < Rails::Application
# Use routes to render error pages
config.exceptions_app = routes
+
+ config.active_storage.draw_routes = false
end
end
diff --git a/config/credentials/development.yml.enc b/config/credentials/development.yml.enc
index 984674a..62a1156 100644
--- a/config/credentials/development.yml.enc
+++ b/config/credentials/development.yml.enc
@@ -1 +1 @@
-LiprxKVi8XEhjTywr2c4tXgDb8853hoHtCu7MBHqCV3eS/1H26OvLy+MWGF3bPGBqB+u0woHD5tpJ5d5nXc+jydyx2u9XxN6ozM8Ttg3rfiTW8fv5Ld2aMp5f6s8RgWUxt9wiT1PZmmVn5Bty8iOqVmjFZPIRh+mzRED7y9ZDENn9bq3r0s28EmH883FoqAzpVfbSFUr+cHhW3Ak7lyPMp27ZBXx0EmR7n+kVNz6n7qZtN/yhc0PR8X9wYlau7nAtwM2lAZYfOUVRPH9pVYwNwxX46D+tAqFyhXN94E1wMaQ2Jbtuot53RfChWcDFvcLFeDJh0bNOIe7j368vJ8qeEqNPZ//sneeTA8kA9MzkSf5PO1sGoIm/SJ7XeRtDNw2m9gzeNILjRpecIWYbSK6hoPJMIym--zZUM4heW6d0PimS4--uAWAPX3UFL+FJGL22zo9Kw==
\ No newline at end of file
+4sS2+n0Ick8STxrOAIIOaq5+xD/lPThoQJWY7MUF3v5G4nN1Uc0rpgRVoDazsEEJ0S2uK9rLjGpxX9LoPRZCvGSXMp4MUCUKe5kbR5TLcJvT/wNPM21yM6VTHkcJGBKtrqwx837Ds/IFSoFMEoZ2ny9RV1Zj3rWym73ePkJsRLKeLJ/5Vlw6uGR09xxjkR5BtDMBjGISl2xPjd1Wv5f9DjAa2b6NCDxbAYmlP/bjyWlxhIQp6hihzWuqK2C/7Osc+kgop0LtKdJTSo/4Cz65g2clR34kn+QwpV4VjK1QlUZsL8quG8osR63v2NNOgwTQe1uw4lWYAeWyB8OFwCW4hPePlxlrfAspP7m2GAAldfu5VfdxDjd7buYwpAxSV5hhGMc+xAASlkmjMAbudGgUODR/p77z--XBTbR6JVHGtqn2nr--q+7ZZYzW7tc976r8+RfASQ==
\ No newline at end of file
diff --git a/config/credentials/production.yml.enc b/config/credentials/production.yml.enc
index c80e09e..51a889b 100644
--- a/config/credentials/production.yml.enc
+++ b/config/credentials/production.yml.enc
@@ -1 +1 @@
-ONYihcJE6z85Sr3c+PSS16urjpkmxk8OajAE4WuusfIo8s5YnSrtyn7qkq8XZ3Qn73F1o+zatPGsQb2rfV3TmR9g5BfSxcJcwWTdoSRjS7QppMR7EiB5PP7O3wd5N3bG39pZ7qTHrzVg08AGrEL6yvs+RXTgUR2QFHsDoIJj3YlkwIBer8byCr9nC9nt3xSpqhzbxmdhMmd+KTsCFL/OlXdcOJvOwxHzhPUj0rImHk+yD5evHVac0gSule7ucbbfAVvOxZOm15J66k3qR+eRv+f1BKG4WjlwBdPXqmBA5TFOfU3WiQ/stfHJww+AuTH53b3cGKxoEHgycW7WEDzolxwHkur7NEC737vsR/0dW4X1eyYUsNVviOFeRGIvxPr85vC92Mf3yY5VmVZNBvn3WCD7kHYd--UjeTagvsRgXeDVxp--x0gK9KAI8+md42EmZZdsdQ==
\ No newline at end of file
+Xfq7VdD6WwiG6rq1lNFt0FoUu3e15SGkQ7QQJkHfzq/E+BoXVUwHHEZVElwemmWVumiHkL5MyX5qr0/pbu2BtpDt8HmFtyOWrLvql1vIGmPQkTxHpFjq6fh5XZ6lrzoTa2CAUeeWXuzVtab1N5itDtf4IppWPHJ7+cXf895cRrVbIA0jt906O8tjCjnvgeoA6YQgGebdp2PW93WfAzdnhgM37w8yeU+fcxxKRi095FQ9VZ7s25/f8yS5VAM0GBV+aS1j7b+y0qycToOc3huF9YE1aRdxNmrGk21bXdJ4ylcpryPNoFrXJGTpo1QZ9Nx8d21sr3cX3V5AanTGIXquqn9Gz+6+w8RVAldmx8dcmJuvW7XvFZuvz8McNWsJrlUZkQavSMMUEV/7t7datMim0T4wW1aQ+4BfsbvDEm2Tn0HmTja00mbncBSaChJwAiEnYTsdbp6evU3PmIp9qUGAr5A5eYrr--lOdUxq5SatVrCS+d--CF7k2/VNtrXfUl9I9lJWFg==
\ No newline at end of file
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 80e0587..f5176c2 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -14,7 +14,7 @@
config.eager_load = false
# Show full error reports.
- config.consider_all_requests_local = true
+ config.consider_all_requests_local = false
# Enable server timing
config.server_timing = true
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 8ae41a2..7805839 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -39,7 +39,7 @@
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
# Store uploaded files on the local file system (see config/storage.yml for options).
- config.active_storage.service = :local
+ config.active_storage.service = :amazon
# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
diff --git a/config/initializers/default_url_options.rb b/config/initializers/default_url_options.rb
new file mode 100644
index 0000000..296bfc7
--- /dev/null
+++ b/config/initializers/default_url_options.rb
@@ -0,0 +1,6 @@
+hosts = {
+ development: 'localhost:3000',
+ production: 'datadeaddrop.com'
+}.freeze
+
+Rails.application.routes.default_url_options[:host] = hosts[Rails.env.to_sym]
diff --git a/config/routes.rb b/config/routes.rb
index 4e255c5..98c913c 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -5,10 +5,10 @@
get 'errors/internal_server_error'
root 'application#home'
- get '/new', to: 'uploads#new', as: :new
- post '/upload', to: 'uploads#upload', as: :upload
- get '/download/:id/preview', to: 'uploads#preview', as: :preview
- get '/download/:id', to: 'uploads#download', as: :download
+ get '/n', to: 'uploads#new', as: :new
+ post '/u', to: 'uploads#upload', as: :upload
+ get '/p/:id', to: 'uploads#preview', as: :preview
+ get '/d/:id', to: 'uploads#download', as: :download
get 'up' => 'rails/health#show', as: :rails_health_check
# Preview error pages
@@ -17,4 +17,11 @@
match '/404', to: 'errors#not_found', via: :all
match '/500', to: 'errors#internal_server_error', via: :all
+
+ if Rails.application.config.active_storage.service == :local
+ scope ActiveStorage.routes_prefix do
+ get '/disk/:encoded_key/*filename' => 'active_storage/disk#show', as: :rails_disk_service
+ put '/disk/:encoded_token' => 'active_storage/disk#update', as: :update_rails_disk_service
+ end
+ end
end
diff --git a/config/storage.yml b/config/storage.yml
index 4942ab6..7537251 100644
--- a/config/storage.yml
+++ b/config/storage.yml
@@ -6,29 +6,9 @@ local:
service: Disk
root: <%= Rails.root.join("storage") %>
-# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
-# amazon:
-# service: S3
-# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
-# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
-# region: us-east-1
-# bucket: your_own_bucket-<%= Rails.env %>
-
-# Remember not to checkin your GCS keyfile to a repository
-# google:
-# service: GCS
-# project: your_project
-# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
-# bucket: your_own_bucket-<%= Rails.env %>
-
-# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
-# microsoft:
-# service: AzureStorage
-# storage_account_name: your_account_name
-# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
-# container: your_container_name-<%= Rails.env %>
-
-# mirror:
-# service: Mirror
-# primary: local
-# mirrors: [ amazon, google, microsoft ]
+amazon:
+ service: S3
+ access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
+ secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
+ region: eu-central-1
+ bucket: data-dead-drop