diff --git a/.gitignore b/.gitignore
index 030b5a87..b9505882 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ doc/
tests/coverage
config.yml
.DS_Store
+domains
diff --git a/app.rb b/app.rb
index 9c1d1d25..cee003f5 100644
--- a/app.rb
+++ b/app.rb
@@ -503,6 +503,33 @@ get '/password_reset_confirm' do
redirect '/'
end
+get '/custom_domain' do
+ slim :custom_domain
+end
+
+post '/custom_domain' do
+ require_login
+ original_domain = current_site.domain
+ current_site.domain = params[:domain]
+ if current_site.valid?
+
+ DB.transaction do
+ current_site.save
+
+ if !params[:domain].empty? && !params[:domain].nil?
+ File.open(File.join(DIR_ROOT, 'domains', "#{current_site.username}.conf"), 'w') do |file|
+ file.write erb(:'templates/domain', layout: false)
+ end
+ end
+
+ end
+ flash[:success] = 'The domain has been successfully updated.'
+ redirect '/custom_domain'
+ else
+ slim :custom_domain
+ end
+end
+
get '/contact' do
slim :'contact'
end
diff --git a/migrations/008_add_nsfw_flag.rb b/migrations/008_add_nsfw_flag.rb
index 36b5ec53..365b6fe9 100644
--- a/migrations/008_add_nsfw_flag.rb
+++ b/migrations/008_add_nsfw_flag.rb
@@ -4,6 +4,6 @@ Sequel.migration do
}
down {
- DB.add_column :sites, :is_nsfw
+ DB.drop_column :sites, :is_nsfw
}
end
\ No newline at end of file
diff --git a/migrations/017_add_domain.rb b/migrations/017_add_domain.rb
new file mode 100644
index 00000000..a6e686de
--- /dev/null
+++ b/migrations/017_add_domain.rb
@@ -0,0 +1,9 @@
+Sequel.migration do
+ up {
+ DB.add_column :sites, :domain, :text, default: nil
+ }
+
+ down {
+ DB.drop_column :sites, :domain
+ }
+end
\ No newline at end of file
diff --git a/models/site.rb b/models/site.rb
index 06ce799f..e7ad3252 100644
--- a/models/site.rb
+++ b/models/site.rb
@@ -95,6 +95,13 @@ class Site < Sequel::Model
if values[:password].nil? || (@password_length && @password_length < MINIMUM_PASSWORD_LENGTH)
errors.add :password, "Password must be at least #{MINIMUM_PASSWORD_LENGTH} characters."
end
+
+ if !values[:domain].nil? && !values[:domain].empty?
+ if !(values[:domain] =~ /^[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/i)
+ errors.add :domain, "Domain provided is not valid. Must take the form of domain.com"
+ end
+ end
+
end
def file_path
diff --git a/views/custom_domain.slim b/views/custom_domain.slim
new file mode 100644
index 00000000..1fb47c18
--- /dev/null
+++ b/views/custom_domain.slim
@@ -0,0 +1,27 @@
+.page
+ .content
+
+ h1.txt-Center Custom Domain
+ h3.txt-Center (advanced)
+
+ .txt-Center
+ - if !current_site.errors.empty?
+ .alert.alert-block.alert-error
+ - current_site.errors.each do |error|
+ p = error.last.first
+
+ .row.c-Row
+ .col.col-66
+ .content
+
+ p Adding a custom domain allows you to have a domain name attached to your web site. So if you had a domain like catsknitting.com, you could have it point to your NeoCities site!
+ p You will have to purchase a domain name from a registrar like Namecheap, and then add an A record to point your domain (catsknitting.com) to the following IP address:
+ p 5.9.136.200
+ p If you want to add a www subdomain, or use a wildcard that will answer to everything (*), you will have to make a CNAME pointing to catsknitting.com for www and/or *.
+ p After that, you can add the domain to the box below (just the catsknitting.com, don't add any subdomains), and your domain should come online within 5 minutes:
+ form method="POST" action="/custom_domain"
+ input name="csrf_token" type="hidden" value="#{csrf_token}"
+ input name="domain" type="text" placeholder="catsknitting.com" value="#{current_site.domain}"
+ br
+ input.btn-Action type="submit" value="Update Domain"
+ p NOTE: This is for advanced users, we cannot provide technical support for this feature. If you cannot make this work, please contact your domain registrar.
\ No newline at end of file
diff --git a/views/settings.slim b/views/settings.slim
index 856b0008..f26e238a 100644
--- a/views/settings.slim
+++ b/views/settings.slim
@@ -56,4 +56,11 @@
input name="is_nsfw" type="hidden" value="false"
p: strong My page contains objectionable (adult) content:
- input.btn-Action type="submit" value="Update"
\ No newline at end of file
+ input.btn-Action type="submit" value="Update"
+
+ .row
+ .col.col-33
+ .content
+ h2.eps.txt-Center Custom Domain
+ p.txt-Center: strong (advanced)
+ p You can configure a custom domain for your NeoCities site. Click Here for more information.
\ No newline at end of file
diff --git a/views/templates/domain.erb b/views/templates/domain.erb
new file mode 100644
index 00000000..db755fb0
--- /dev/null
+++ b/views/templates/domain.erb
@@ -0,0 +1,23 @@
+server {
+ listen 80;
+ server_name <%= current_site.domain %> *.<%= current_site.domain %>
+ access_log /var/log/nginx/neocities-domains.log neocitiesdomain;
+ root /home/web/neocities-web/public/sites/<%= current_site.username %>;
+ index /index.html;
+
+ error_page 404 = @notfound;
+
+ location @notfound {
+ try_files /not_found.html @notfound_root;
+ }
+
+ location @notfound_root {
+ root /home/web/neocities-web/public;
+ try_files /web_site_not_found.html =404;
+ }
+
+ location ~* \.(html|jpg|jpeg|png|gif|ico|css|js)$ {
+ # expires 20s;
+ log_not_found off;
+ }
+}
\ No newline at end of file