Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7ACAD177EE for ; Mon, 2 Feb 2015 07:32:24 +0000 (UTC) Received: (qmail 58494 invoked by uid 500); 2 Feb 2015 07:32:12 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 58448 invoked by uid 500); 2 Feb 2015 07:32:12 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 58439 invoked by uid 99); 2 Feb 2015 07:32:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Feb 2015 07:32:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 8734AE035D; Mon, 2 Feb 2015 07:32:12 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: garren@apache.org To: commits@couchdb.apache.org Date: Mon, 02 Feb 2015 07:32:12 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/2] fauxton commit: updated refs/heads/master to ddef3d5 Repository: couchdb-fauxton Updated Branches: refs/heads/master 9f26ac1e2 -> ddef3d54c Initial add CORS to Fauxton Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/a9636bdc Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/a9636bdc Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/a9636bdc Branch: refs/heads/master Commit: a9636bdcdd7ccabb868c678d9be0ac339df282e0 Parents: 9f26ac1 Author: Christian Hogan Authored: Fri Nov 28 13:19:13 2014 -0500 Committer: Garren Smith Committed: Mon Feb 2 09:30:46 2015 +0200 ---------------------------------------------------------------------- app/addons/config/assets/less/config.less | 4 + app/addons/config/routes.js | 33 +- app/addons/config/templates/dashboard.html | 2 +- app/addons/config/templates/sidebartabs.html | 10 + app/addons/config/views.js | 24 ++ app/addons/cors/assets/less/cors.less | 126 +++++++ app/addons/cors/base.js | 24 ++ app/addons/cors/resources.js | 64 ++++ app/addons/cors/routes.js | 21 ++ app/addons/cors/templates/cors.html | 50 +++ .../cors/templates/origin_domain_row.html | 33 ++ .../cors/templates/origin_domain_table.html | 17 + app/addons/cors/views.js | 337 +++++++++++++++++++ settings.json.default | 1 + 14 files changed, 741 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/config/assets/less/config.less ---------------------------------------------------------------------- diff --git a/app/addons/config/assets/less/config.less b/app/addons/config/assets/less/config.less index 6cd0ed2..fd496c6 100644 --- a/app/addons/config/assets/less/config.less +++ b/app/addons/config/assets/less/config.less @@ -41,6 +41,10 @@ } table.config { + thead th { + border-left: none; + border-bottom: 2px solid #999; + } tr { th, td { vertical-align: middle; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/config/routes.js ---------------------------------------------------------------------- diff --git a/app/addons/config/routes.js b/app/addons/config/routes.js index 62fd9b1..32dc4cc 100644 --- a/app/addons/config/routes.js +++ b/app/addons/config/routes.js @@ -14,16 +14,33 @@ define([ 'app', 'api', 'addons/config/resources', - 'addons/config/views' + 'addons/config/views', + 'addons/cors/views' ], -function(app, FauxtonAPI, Config, Views) { +function(app, FauxtonAPI, Config, Views, CORS) { var ConfigRouteObject = FauxtonAPI.RouteObject.extend({ - layout: 'one_pane', + layout: 'with_tabs_sidebar', initialize: function () { this.configs = new Config.Collection(); + this.cors = new CORS.config(); + + this.sidebar = this.setView("#sidebar-content", new Views.Tabs({ + sidebarItems: [ + { + title: 'Main config', + typeSelect: 'main', + link: '_config' + }, + { + title: 'CORS', + typeSelect: 'cors', + link: '_config/cors' + } + ] + })); }, roles: ['_admin'], @@ -38,12 +55,20 @@ function(app, FauxtonAPI, Config, Views) { }, routes: { - '_config': 'config' + '_config': 'config', + '_config/cors':'configCORS' }, config: function () { this.newSection = this.setView('#right-header', new Views.ConfigHeader({ collection: this.configs })); this.setView('#dashboard-content', new Views.Table({ collection: this.configs })); + this.sidebar.setSelectedTab("main"); + }, + + configCORS: function() { + this.removeView('#right-header'); + this.newSection = this.setView('#dashboard-content', new CORS.Views.CORSMain({ model: this.cors })); + this.sidebar.setSelectedTab("cors"); }, establish: function () { http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/config/templates/dashboard.html ---------------------------------------------------------------------- diff --git a/app/addons/config/templates/dashboard.html b/app/addons/config/templates/dashboard.html index f7fae00..0af857d 100644 --- a/app/addons/config/templates/dashboard.html +++ b/app/addons/config/templates/dashboard.html @@ -14,7 +14,7 @@ the License. - + http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/config/templates/sidebartabs.html ---------------------------------------------------------------------- diff --git a/app/addons/config/templates/sidebartabs.html b/app/addons/config/templates/sidebartabs.html new file mode 100644 index 0000000..b48b0ae --- /dev/null +++ b/app/addons/config/templates/sidebartabs.html @@ -0,0 +1,10 @@ + http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/config/views.js ---------------------------------------------------------------------- diff --git a/app/addons/config/views.js b/app/addons/config/views.js index 034205a..1ccdc3e 100644 --- a/app/addons/config/views.js +++ b/app/addons/config/views.js @@ -243,6 +243,30 @@ function(app, FauxtonAPI, Config, Components) { }); } }); + + Views.Tabs = FauxtonAPI.View.extend({ + className: "sidenav", + tagName: "nav", + template: 'addons/config/templates/sidebartabs', + initialize: function (options) { + this.sidebarItems = options.sidebarItems; + }, + + setSelectedTab: function (selectedTab) { + this.selectedTab = selectedTab; + this.$('li').removeClass('active'); + this.$('a[data-type-select="'+this.selectedTab+'"]').parent("li").addClass('active'); + }, + afterRender: function(){ + this.setSelectedTab(this.selectedTab); + }, + + serialize: function () { + return { + sidebarItems: this.sidebarItems + }; + } + }); return Views; }); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/assets/less/cors.less ---------------------------------------------------------------------- diff --git a/app/addons/cors/assets/less/cors.less b/app/addons/cors/assets/less/cors.less new file mode 100644 index 0000000..4e06032 --- /dev/null +++ b/app/addons/cors/assets/less/cors.less @@ -0,0 +1,126 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +/* =cors + ---------------------------------------------------------------------- */ +@import "../../../../../assets/less/bootstrap/variables.less"; +@import "../../../../../assets/less/variables.less"; +@import "../../../../../assets/less/bootstrap/mixins.less"; + +#sidebar-content .nav-list li a span { + display: none; +} + +#cors-header { + margin: 18px 30px 0 30px; +} + +#corsForm { + margin: 0; + + .checkbox { + font-size: 16px; + + input[type='checkbox'] { + margin-top: 4px; + } + } + .radio { + font-size: 16px; + + input[type='radio'] { + margin-top: 4px; + } + } + + .cors-enable { + padding: 10px 30px 18px 30px; + border-bottom: 1px solid #ccc; + } + #origin-domains-container { + display: none; + + .new-origin-domain { + width: 100%; + border-radius: 6px; + } + } + #collapsing-container { + border-top: 1px solid #fff; + border-bottom: 1px solid #ccc; + padding: 18px 30px; + display: none; + } + .origin-domains { + margin: 0; + padding: 18px 0px; + + p { + line-height: 36px; + } + .controls { + margin-top: 18px; + } + } + .localhost-tip { + padding: 18px 30px; + border-top: 1px solid #fff; + border-bottom: 1px solid #ccc; + } + .form-actions { + padding: 18px 30px; + margin-top: 0; + border-top: 1px solid #fff; + } +} + +#origin-domain-table { + td { + padding: 8px 2px; + } + span { + cursor: pointer; + color: #E33F3B; + display: inline-block; + padding-top: 9px; + } + + .edit-domain-section { + position: relative; + margin-right: 20px; + + .field-wrapper { + margin-right: 78px; + } + input { + width: 100%; + padding: 9px; + margin: 0 0 0 4px; + } + } + .url-display { + padding: 10px; + } + + .hide { + display: none; + } + + .update-domain-btn { + position: absolute; + right: -2px; + top: 0; + padding: 9px; + border-radius: 0 6px 6px 0; + } +} http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/base.js ---------------------------------------------------------------------- diff --git a/app/addons/cors/base.js b/app/addons/cors/base.js new file mode 100644 index 0000000..b5824e3 --- /dev/null +++ b/app/addons/cors/base.js @@ -0,0 +1,24 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +define([ + "app", + "api", + "addons/cors/routes" +], + +function (app, FauxtonAPI, CORS) { + + CORS.initialize = function() {}; + + return CORS; +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/resources.js ---------------------------------------------------------------------- diff --git a/app/addons/cors/resources.js b/app/addons/cors/resources.js new file mode 100644 index 0000000..bd3809e --- /dev/null +++ b/app/addons/cors/resources.js @@ -0,0 +1,64 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +define([ + "app", + "api" +], + +function (app, FauxtonAPI) { + var CORS = FauxtonAPI.addon(); + + + CORS.config = FauxtonAPI.Model.extend({ + url: function() { + return app.host+"/_config/cors"; + } + }); + + CORS.ConfigModel = Backbone.Model.extend({ + documentation: "cors", + + url: function () { + return app.host + '/_config/' + encodeURIComponent(this.get("section")) + '/' + encodeURIComponent(this.get("attribute")); + }, + + isNew: function () { return false; }, + + sync: function (method, model, options) { + + var params = { + url: model.url(), + contentType: 'application/json', + dataType: 'json', + data: JSON.stringify(model.get('value')) + }; + + if (method === 'delete') { + params.type = 'DELETE'; + } else { + params.type = 'PUT'; + } + + return $.ajax(params); + } + + }); + + // simple helper function to validate the user entered a valid domain starting with http(s) and + // not including any subfolder + CORS.validateCORSDomain = function (str) { + return (/^https?:\/\/[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$/).test(str); + }; + + return CORS; +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/routes.js ---------------------------------------------------------------------- diff --git a/app/addons/cors/routes.js b/app/addons/cors/routes.js new file mode 100644 index 0000000..017211b --- /dev/null +++ b/app/addons/cors/routes.js @@ -0,0 +1,21 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +define([ + 'app', + 'api', + 'addons/cors/views' +], + +function (app, FauxtonAPI, CORS) { + return CORS; +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/templates/cors.html ---------------------------------------------------------------------- diff --git a/app/addons/cors/templates/cors.html b/app/addons/cors/templates/cors.html new file mode 100644 index 0000000..8db6a60 --- /dev/null +++ b/app/addons/cors/templates/cors.html @@ -0,0 +1,50 @@ + + +
+

Cross-Origin Resource Sharing (CORS) lets you connect to remote servers directly from the browser, so you can host browser-based apps on static pages and talk directly with CouchDB to load your data.

+
+ + + +
+ +
+ +
+

Origin Domains

+ +

Databases will accept requests from these domains:

+ + + + + +
+
+ +
+ +
+ + + +
+ +
+ + + http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/templates/origin_domain_row.html ---------------------------------------------------------------------- diff --git a/app/addons/cors/templates/origin_domain_row.html b/app/addons/cors/templates/origin_domain_row.html new file mode 100644 index 0000000..19f6954 --- /dev/null +++ b/app/addons/cors/templates/origin_domain_row.html @@ -0,0 +1,33 @@ + + + + + http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/templates/origin_domain_table.html ---------------------------------------------------------------------- diff --git a/app/addons/cors/templates/origin_domain_table.html b/app/addons/cors/templates/origin_domain_table.html new file mode 100644 index 0000000..7192bea --- /dev/null +++ b/app/addons/cors/templates/origin_domain_table.html @@ -0,0 +1,17 @@ + + +
SectionSection Option Value
+
<%-url%>
+ +
+
+ +
+ + + Update + +
+
+ + + +
+ +
http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/app/addons/cors/views.js ---------------------------------------------------------------------- diff --git a/app/addons/cors/views.js b/app/addons/cors/views.js new file mode 100644 index 0000000..c390d5a --- /dev/null +++ b/app/addons/cors/views.js @@ -0,0 +1,337 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +define([ + "app", + "api", + "addons/cors/resources" +], + + +function (app, FauxtonAPI, CORS) { + var Views= {}; + + Views.CORSMain = FauxtonAPI.View.extend({ + className: 'cors-page', + template: 'addons/cors/templates/cors', + events: { + 'submit form#corsForm': 'submit', + 'click .js-enable-cors': 'corsClick', + 'click .js-restrict-origin-domains': 'restrictOrigins', + 'click .js-all-origin-domains': 'allOrigins' + }, + + initialize: function () { + this.originDomainTable = this.setView('.origin-domains', new Views.OriginDomainTable({ + model: this.model + })); + }, + + serialize: function () { + return { + enableCors: this.model.get('credentials') + }; + }, + + establish: function(){ + return [this.model.fetch()]; + }, + + afterRender: function () { + var corsEnabled = this.$('.js-enable-cors').is(':checked'); + this.$('#collapsing-container').toggle(corsEnabled); + this.setupOrigins(); + }, + + corsClick: function (e) { + var isChecked = this.$(e.target).prop('checked'); + this.$('#collapsing-container').toggle(isChecked); + this.setupOrigins(); + }, + + + setupOrigins: function() { + var storedOrigins = this.model.get('origins'); + if (storedOrigins && storedOrigins != '*') { + this.restrictOrigins(); + } else { + this.allOrigins(); + } + }, + + allOrigins: function() { + this.$('.js-all-origin-domains').prop('checked', true); + this.$('.js-restrict-origin-domains').prop('checked', false); + this.$('#origin-domains-container').hide(); + }, + + restrictOrigins: function() { + this.$('.js-restrict-origin-domains').prop('checked', true); + this.$('.js-all-origin-domains').prop('checked', false); + this.$('#origin-domains-container').show(); + }, + + formToJSON: function(formSelector){ + var formObject = $(formSelector).serializeArray(), + formJSON={}; + _.map(formObject, function(field){ + formJSON[field.name]=field.value; + }); + return formJSON; + }, + + submit: function(e){ + e.preventDefault(); + var data = this.formToJSON(e.currentTarget); + + if (data.enable_cors === 'on') { + + // CORS checked, save data + if (data.restrict_origin_domains === 'on') { + var storedOrigins = this.model.get('origins').split(','); + var newDomain = $.trim(data.new_origin_domain); + + // if a new domain has been entered, check it's valid + if (!_.isEmpty(newDomain) && !CORS.validateCORSDomain(newDomain)) { + FauxtonAPI.addNotification({ + msg: 'Please enter a valid domain, starting with http/https and only containing the domain (not a subfolder).', + type: 'error', + clear: true + }); + return; + } + + // check that the user has entered at least one new origin domain + if (storedOrigins && storedOrigins.length > 0 && storedOrigins !== '*') { + this.originData = storedOrigins.concat(newDomain).toString(); + } else { + if (_.isEmpty(newDomain)) { + FauxtonAPI.addNotification({ + msg: 'Please enter a new origin domain.', + type: 'error', + clear: true + }); + this.$('.new-origin-domain').focus(); + return; + } + this.originData = data.new_origin_domain; + } + + } else { + this.originData = "*"; + } + + + var enableOption = new CORS.ConfigModel({ + section: 'httpd', + attribute: 'enable_cors', + value: 'true' + }); + + var enableCreds = new CORS.ConfigModel({ + section: 'cors', + attribute: 'credentials', + value: 'true' + }); + + var allowOrigins = new CORS.ConfigModel({ + section: 'cors', + attribute: 'origins', + value: this.originData + }); + + enableOption.save().then(function (response) { + var notification = FauxtonAPI.addNotification({ + msg: 'Your settings have been saved.', + type: 'success', + clear: true + }); + }, + function (response, errorCode, errorMsg) { + var notification = FauxtonAPI.addNotification({ + msg: 'Sorry! There was an error. Code ' + errorCode + '.', + type: 'error', + clear: true + }); + }); + + enableCreds.save(); + allowOrigins.save(); + this.$('.new-origin-domain').val(''); + + } else { + + // Disable CORS + var disableOption = new CORS.ConfigModel({ + section: 'httpd', + attribute: 'enable_cors', + value: 'false' + }); + + var disableCreds = new CORS.ConfigModel({ + section: 'cors', + attribute: 'credentials', + value: 'false' + }); + + var disableOrigins = new CORS.ConfigModel({ + section: 'cors', + attribute: 'origins', + value: '' + }); + + disableOption.save().then(function (response) { + var notification = FauxtonAPI.addNotification({ + msg: 'Your settings have been saved.', + type: 'success', + clear: true + }); + }, + function (response, errorCode, errorMsg) { + var notification = FauxtonAPI.addNotification({ + msg: 'Sorry! There was an error. Code ' + errorCode + '.', + type: 'error', + clear: true + }); + }); + + disableCreds.save(); + disableOrigins.save(); + } + } + }); + + Views.OriginDomainTable = FauxtonAPI.View.extend({ + template: 'addons/cors/templates/origin_domain_table', + + initialize: function () { + // listen for any server-side changes to the object (i.e. saves/deletes). Only then, re-render the table + this.listenTo(this.model, 'sync', this.render); + }, + + beforeRender: function () { + var origins = this.model.get('origins'); + + // if the stored origins are set to '*' or nothing's defined, show nothing + if (_.isEmpty(origins) || origins === '*') { + return; + } + this.showRows(); + }, + + showRows: function () { + var originsArray = this.model.get('origins').split(','); + _.each(originsArray, function (url, index) { + this.insertView('#origin-domain-table tbody', new Views.OriginDomainRow({ + model: this.model, + index: index + })); + }, this); + } + }); + + + // this gets passed the entire model so it can manipulate it directly (add/update the row) + Views.OriginDomainRow = FauxtonAPI.View.extend({ + template: 'addons/cors/templates/origin_domain_row', + tagName: 'tr', + + events: { + 'click .js-edit': 'onEditDomain', + 'click .js-cancel-edit': 'onCancelEditDomain', + 'click .js-delete': 'onDeleteDomain', + 'click .js-save-domain': 'onSaveDomain' + }, + + serialize: function () { + return { + url: this.model.get('origins').split(',')[this.index] + }; + }, + + onEditDomain: function () { + + // show the editable field & save button + this.$('.js-url').addClass('hide'); + this.$('.js-edit-domain').removeClass('hide'); + + // change the edit icon to a cancel icon + this.$('.js-edit').removeClass('js-edit fonticon-pencil') + .addClass('js-cancel-edit fonticon-cancel').attr("title", "Click to cancel"); + this.$('.js-edit-domain input').select(); + }, + + onCancelEditDomain: function () { + this.$('.js-url').removeClass('hide'); + this.$('.js-edit-domain').addClass('hide'); + this.$('.js-cancel-edit').removeClass('js-cancel-edit fonticon-cancel') + .addClass('js-edit fonticon-pencil').attr("title", "Click to edit"); + }, + + onSaveDomain: function () { + var newDomain = this.$('.js-edit-domain input').val(); + + if (!CORS.validateCORSDomain(newDomain)) { + FauxtonAPI.addNotification({ + msg: "Please enter a valid domain, starting with http/https and only containing the domain (not a subfolder).", + type: "error", + clear: true + }); + return; + } + + var domains = this.model.get('origins').split(','); + domains[this.index] = newDomain; + this.saveOrigins(domains); + }, + + // remove the domain from the list + onDeleteDomain: function () { + + // remove the domain from the list. Anyone monitoring the object will hear that it's changed (e.g. + // the main table, which will know to re-render) + var domains = this.model.get('origins').split(','); + domains.splice(this.index, 1); + + this.saveOrigins(domains); + }, + + saveOrigins: function (origins) { + var originDomains = origins.toString(); + + var allowOrigins = new CORS.ConfigModel({ + section: 'cors', + attribute: 'origins', + value: originDomains + }); + + allowOrigins.save().then(function (response) { + var notification = FauxtonAPI.addNotification({ + msg: 'Your origin domains have been updated.', + type: 'success', + clear: true + }); + }, + function (response, errorCode, errorMsg) { + var notification = FauxtonAPI.addNotification({ + msg: 'Something went wrong.', + type: 'error', + clear: true + }); + }); + } + }); + + CORS.Views = Views; + + return CORS; +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/a9636bdc/settings.json.default ---------------------------------------------------------------------- diff --git a/settings.json.default b/settings.json.default index 8e88c0e..1e6aa50 100644 --- a/settings.json.default +++ b/settings.json.default @@ -6,6 +6,7 @@ { "name": "activetasks" }, { "name": "config" }, { "name": "replication" }, + { "name": "cors" }, { "name": "plugins" }, { "name": "permissions" }, { "name": "compaction" },