diff --git a/backend/migrations/20180618015850_initial.js b/backend/migrations/20180618015850_initial.js index a112e8261..b07908700 100644 --- a/backend/migrations/20180618015850_initial.js +++ b/backend/migrations/20180618015850_initial.js @@ -69,6 +69,9 @@ exports.up = function (knex/*, Promise*/) { table.json('domain_names').notNull(); table.string('forward_ip').notNull(); table.integer('forward_port').notNull().unsigned(); + table.string('root_dir').notNull(); + table.string('index_file').notNull(); + table.integer('static').notNull().unsigned().defaultTo(0); table.integer('access_list_id').notNull().unsigned().defaultTo(0); table.integer('certificate_id').notNull().unsigned().defaultTo(0); table.integer('ssl_forced').notNull().unsigned().defaultTo(0); diff --git a/backend/schema/definitions.json b/backend/schema/definitions.json index 9895b87ee..869d719ac 100644 --- a/backend/schema/definitions.json +++ b/backend/schema/definitions.json @@ -235,6 +235,11 @@ "description": "Should we cache assets", "example": true, "type": "boolean" + }, + "static": { + "description": "Should the proxy point to static files", + "example": true, + "type": "boolean" } } } diff --git a/backend/schema/endpoints/proxy-hosts.json b/backend/schema/endpoints/proxy-hosts.json index 9a3fff2fc..94c0ba7ad 100644 --- a/backend/schema/endpoints/proxy-hosts.json +++ b/backend/schema/endpoints/proxy-hosts.json @@ -24,14 +24,22 @@ }, "forward_host": { "type": "string", - "minLength": 1, + "minLength": 0, "maxLength": 255 }, "forward_port": { "type": "integer", - "minimum": 1, + "minimum": 0, "maximum": 65535 }, + "root_dir": { + "type": "string", + "minLength": 0, + }, + "index_file": { + "type": "string", + "minLength": 0, + }, "certificate_id": { "$ref": "../definitions.json#/definitions/certificate_id" }, @@ -53,6 +61,9 @@ "caching_enabled": { "$ref": "../definitions.json#/definitions/caching_enabled" }, + "static": { + "$ref": "../definitions.json#/definitions/static" + }, "allow_websocket_upgrade": { "description": "Allow Websocket Upgrade for all paths", "example": true, @@ -76,10 +87,7 @@ "items": { "type": "object", "required": [ - "forward_scheme", - "forward_host", - "forward_port", - "path" + "forward_scheme" ], "additionalProperties": false, "properties": { @@ -99,6 +107,15 @@ "forward_port": { "$ref": "#/definitions/forward_port" }, + "root_dir": { + "$ref": "#/definitions/root_dir" + }, + "index_file": { + "$ref": "#/definitions/index_file" + }, + "static": { + "$ref": "#/definitions/static" + }, "forward_path": { "type": "string" }, @@ -131,6 +148,12 @@ "forward_port": { "$ref": "#/definitions/forward_port" }, + "root_dir": { + "$ref": "#/definitions/root_dir" + }, + "index_file": { + "$ref": "#/definitions/index_file" + }, "certificate_id": { "$ref": "#/definitions/certificate_id" }, @@ -152,6 +175,9 @@ "caching_enabled": { "$ref": "#/definitions/caching_enabled" }, + "static": { + "$ref": "#/definitions/static" + }, "allow_websocket_upgrade": { "$ref": "#/definitions/allow_websocket_upgrade" }, @@ -204,9 +230,7 @@ "additionalProperties": false, "required": [ "domain_names", - "forward_scheme", - "forward_host", - "forward_port" + "forward_scheme" ], "properties": { "domain_names": { @@ -221,6 +245,12 @@ "forward_port": { "$ref": "#/definitions/forward_port" }, + "root_dir": { + "$ref": "#/definitions/root_dir" + }, + "index_file": { + "$ref": "#/definitions/index_file" + }, "certificate_id": { "$ref": "#/definitions/certificate_id" }, @@ -242,6 +272,9 @@ "caching_enabled": { "$ref": "#/definitions/caching_enabled" }, + "static": { + "$ref": "#/definitions/static" + }, "allow_websocket_upgrade": { "$ref": "#/definitions/allow_websocket_upgrade" }, @@ -294,6 +327,12 @@ "forward_port": { "$ref": "#/definitions/forward_port" }, + "root_dir": { + "$ref": "#/definitions/root_dir" + }, + "index_file": { + "$ref": "#/definitions/index_file" + }, "certificate_id": { "$ref": "#/definitions/certificate_id" }, @@ -315,6 +354,9 @@ "caching_enabled": { "$ref": "#/definitions/caching_enabled" }, + "static": { + "$ref": "#/definitions/static" + }, "allow_websocket_upgrade": { "$ref": "#/definitions/allow_websocket_upgrade" }, diff --git a/backend/templates/_listen.conf b/backend/templates/_listen.conf index 8f40bea2e..08ec53692 100644 --- a/backend/templates/_listen.conf +++ b/backend/templates/_listen.conf @@ -13,3 +13,8 @@ {% endif %} {% endif %} server_name {{ domain_names | join: " " }}; +{% if static == 1 or static == true %} + root {{ root_dir }}; + index {{ index_file }}; +{% endif %} + diff --git a/backend/templates/_location.conf b/backend/templates/_location.conf index 0b8894d11..72f3ea50b 100644 --- a/backend/templates/_location.conf +++ b/backend/templates/_location.conf @@ -1,9 +1,16 @@ location {{ path }} { - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Scheme $scheme; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }}; + + {% if static == 0 or static == false %} + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Scheme $scheme; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_pass {{ forward_scheme }}://{{ forward_host }}:{{ forward_port }}{{ forward_path }}; + {% else %} + alias {{ root_dir }}/$1; + try_files $uri /{{ index_file }} =200; + {% endif %} + {{ advanced_config }} } diff --git a/backend/templates/default.conf b/backend/templates/default.conf index 56b67090e..dfb0b1b8a 100644 --- a/backend/templates/default.conf +++ b/backend/templates/default.conf @@ -29,6 +29,7 @@ server { {%- if value == "html" %} root /data/nginx/default_www; + # root /var/www/test2; location / { try_files $uri /index.html; } diff --git a/backend/templates/proxy_host.conf b/backend/templates/proxy_host.conf index 17a521078..6f8ddd02a 100644 --- a/backend/templates/proxy_host.conf +++ b/backend/templates/proxy_host.conf @@ -52,8 +52,14 @@ server { proxy_http_version 1.1; {% endif %} - # Proxy! - include conf.d/include/proxy.conf; + {% if static == 1 or static == true %} + alias {{ root_dir }}/$1; + try_files $uri /{{index_file}} =200; + {% else %} + # Proxy! + include conf.d/include/proxy.conf; + + {% endif %} } {% endif %} diff --git a/frontend/js/app/nginx/proxy/form.ejs b/frontend/js/app/nginx/proxy/form.ejs index 1a4983013..5ca45a464 100644 --- a/frontend/js/app/nginx/proxy/form.ejs +++ b/frontend/js/app/nginx/proxy/form.ejs @@ -35,7 +35,7 @@
- + + + autocomplete="off" maxlength="255">
- - + + > +
+
+
+
+ + autocomplete="off" maxlength="255"> +
+
+
+
+ + autocomplete="off" maxlength="255">
@@ -81,6 +93,15 @@
+
+
+ +
+
diff --git a/frontend/js/app/nginx/proxy/form.js b/frontend/js/app/nginx/proxy/form.js index 8802b9582..63be89653 100644 --- a/frontend/js/app/nginx/proxy/form.js +++ b/frontend/js/app/nginx/proxy/form.js @@ -43,7 +43,10 @@ module.exports = Mn.View.extend({ dns_provider_credentials: 'textarea[name="meta[dns_provider_credentials]"]', propagation_seconds: 'input[name="meta[propagation_seconds]"]', forward_scheme: 'select[name="forward_scheme"]', - letsencrypt: '.letsencrypt' + letsencrypt: '.letsencrypt', + root_dir: 'input[name="root_dir"]', + index_file: 'input[name="index_file"]', + static: 'input[type="checkbox"].static-checkbox', }, regions: { @@ -113,7 +116,7 @@ module.exports = Mn.View.extend({ } else { this.ui.dns_provider.prop('required', false); this.ui.dns_provider_credentials.prop('required', false); - this.ui.dns_challenge_content.hide(); + this.ui.dns_challenge_content.hide(); } }, @@ -125,17 +128,26 @@ module.exports = Mn.View.extend({ this.ui.credentials_file_content.show(); } else { this.ui.dns_provider_credentials.prop('required', false); - this.ui.credentials_file_content.hide(); + this.ui.credentials_file_content.hide(); } }, 'click @ui.add_location_btn': function (e) { e.preventDefault(); - + const model = new ProxyLocationModel.Model(); this.locationsCollection.add(model); }, + 'click @ui.static': function(e){ + const map = {}; + let value = e.target.value + if(e.target.type == 'checkbox') value = e.target.checked; + map[e.target.name] = value; + this.model.set(map); + setTimeout(this.render.bind(this), 300) + }, + 'click @ui.save': function (e) { e.preventDefault(); this.ui.le_error_info.hide(); @@ -167,17 +179,18 @@ module.exports = Mn.View.extend({ data.hsts_enabled = !!data.hsts_enabled; data.hsts_subdomains = !!data.hsts_subdomains; data.ssl_forced = !!data.ssl_forced; - + data.static = !!data.static; + if (typeof data.meta === 'undefined') data.meta = {}; data.meta.letsencrypt_agree = data.meta.letsencrypt_agree == 1; data.meta.dns_challenge = data.meta.dns_challenge == 1; - + if(!data.meta.dns_challenge){ data.meta.dns_provider = undefined; data.meta.dns_provider_credentials = undefined; data.meta.propagation_seconds = undefined; } else { - if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined; + if(data.meta.propagation_seconds === '') data.meta.propagation_seconds = undefined; } if (typeof data.domain_names === 'string' && data.domain_names) { @@ -185,7 +198,7 @@ module.exports = Mn.View.extend({ } // Check for any domain names containing wildcards, which are not allowed with letsencrypt - if (data.certificate_id === 'new') { + if (data.certificate_id === 'new') { let domain_err = false; if (!data.meta.dns_challenge) { data.domain_names.map(function (name) { diff --git a/frontend/js/app/nginx/proxy/list/item.ejs b/frontend/js/app/nginx/proxy/list/item.ejs index d90ace4c0..88aa265e3 100644 --- a/frontend/js/app/nginx/proxy/list/item.ejs +++ b/frontend/js/app/nginx/proxy/list/item.ejs @@ -23,7 +23,13 @@
-
<%- forward_scheme %>://<%- forward_host %>:<%- forward_port %>
+ + <% if (!static) { %> +
<%- forward_scheme %>://<%- forward_host %>:<%- forward_port %>
+ <% } else { %> +
<%- root_dir %>
+
<%- index_file %>
+ <% } %>
<%- certificate && certificate_id ? i18n('ssl', certificate.provider) : i18n('ssl', 'none') %>
diff --git a/frontend/js/app/nginx/proxy/location-item.ejs b/frontend/js/app/nginx/proxy/location-item.ejs index 39445f7be..4673a0f01 100644 --- a/frontend/js/app/nginx/proxy/location-item.ejs +++ b/frontend/js/app/nginx/proxy/location-item.ejs @@ -16,7 +16,7 @@
- + + + autocomplete="off" maxlength="200"> <%- i18n('proxy-hosts', 'custom-forward-host-help') %>
- - + + >
+
+
+ + autocomplete="off" maxlength="200"> +
+
+
+
+ + autocomplete="off" maxlength="200"> +
+
+
+
+ +
+
diff --git a/frontend/js/app/nginx/proxy/location.js b/frontend/js/app/nginx/proxy/location.js index e9513a480..b12b621a0 100644 --- a/frontend/js/app/nginx/proxy/location.js +++ b/frontend/js/app/nginx/proxy/location.js @@ -7,13 +7,15 @@ const LocationView = Mn.View.extend({ className: 'location_block', ui: { - toggle: 'input[type="checkbox"]', + settings: 'input[type="checkbox"].settings-checkbox', + static: 'input[type="checkbox"].location-static-checkbox', config: '.config', delete: '.location-delete' }, events: { - 'change @ui.toggle': function(el) { + + 'change @ui.settings': function(el) { if (el.target.checked) { this.ui.config.show(); } else { @@ -22,11 +24,20 @@ const LocationView = Mn.View.extend({ }, 'change .model': function (e) { + const map = {}; - map[e.target.name] = e.target.value; + + let value = e.target.value + if(e.target.type == 'checkbox') value = e.target.checked ? 1 : 0 + map[e.target.name] = value this.model.set(map); + + setTimeout(this.render.bind(this), 300) + }, + // 'click @ui.static': 'render', + 'click @ui.delete': function () { this.model.destroy(); } diff --git a/frontend/js/i18n/messages.json b/frontend/js/i18n/messages.json index 3437b1098..a0d928f4a 100644 --- a/frontend/js/i18n/messages.json +++ b/frontend/js/i18n/messages.json @@ -123,6 +123,9 @@ "forward-scheme": "Scheme", "forward-host": "Forward Hostname / IP", "forward-port": "Forward Port", + "root-dir": "Root Directory", + "static": "Static File Proxy", + "index-file": "Index File", "delete": "Delete Proxy Host", "delete-confirm": "Are you sure you want to delete the Proxy host for: {domains}?", "help-title": "What is a Proxy Host?", diff --git a/frontend/js/models/proxy-host-location.js b/frontend/js/models/proxy-host-location.js index 2a35059f8..9ce641d2f 100644 --- a/frontend/js/models/proxy-host-location.js +++ b/frontend/js/models/proxy-host-location.js @@ -9,8 +9,11 @@ const model = Backbone.Model.extend({ path: '', advanced_config: '', forward_scheme: 'http', - forward_host: '', - forward_port: '80' + forward_host: null, + forward_port: '80', + root_dir: null, + static: false, + index_file: 'index.html', } }, diff --git a/frontend/js/models/proxy-host.js b/frontend/js/models/proxy-host.js index b82d09fef..fca51b2c0 100644 --- a/frontend/js/models/proxy-host.js +++ b/frontend/js/models/proxy-host.js @@ -10,8 +10,11 @@ const model = Backbone.Model.extend({ modified_on: null, domain_names: [], forward_scheme: 'http', - forward_host: '', + forward_host: null, forward_port: null, + root_dir: null, + static: false, + index_file: 'index.html', access_list_id: 0, certificate_id: 0, ssl_forced: false, diff --git a/scripts/restart-dev b/scripts/restart-dev new file mode 100644 index 000000000..b8e5ec842 --- /dev/null +++ b/scripts/restart-dev @@ -0,0 +1,7 @@ +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. "$DIR/.common.sh" + +cd "${DIR}/.." + +. scripts/destroy-dev +. scripts/start-dev \ No newline at end of file