Add pre-flight check for domain collision
This commit is contained in:
@@ -1721,6 +1721,15 @@ angular.module('Application').service('Client', ['$http', '$interval', '$timeout
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.getDNSRecords = function (domain, subdomain, type, callback) {
|
||||
get('/api/v1/domains/' + domain + '/dns?subdomain=' + subdomain + '&type=' + type, null, function (error, data, status) {
|
||||
if (error) return callback(error);
|
||||
if (status !== 200) return callback(new ClientError(status, data));
|
||||
|
||||
callback(null, data.values);
|
||||
});
|
||||
};
|
||||
|
||||
Client.prototype.addMailDomain = function (domain, callback) {
|
||||
post('/api/v1/mail', { domain: domain }, null, function (error, data, status) {
|
||||
if (error) return callback(error);
|
||||
|
||||
@@ -81,6 +81,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal domain collision -->
|
||||
<div class="modal fade" id="domainCollisionsModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Domain Collision</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>By default Cloudron does not overwrite DNS records which exist outside of Cloudron.</p>
|
||||
<p>The following domains already exist outside of Cloudron:</p>
|
||||
<ul>
|
||||
<li ng-repeat="domain in location.domainCollisions">{{ domain.subdomain + '.' + domain.domain }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger" ng-click="location.submit(true)">Overwrite existing DNS Records</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal update app -->
|
||||
<div class="modal fade" id="updateModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/* global angular */
|
||||
/* global $ */
|
||||
/* global asyncSeries */
|
||||
/* global asyncForEach */
|
||||
|
||||
|
||||
// TODO use this once we enable custom SSL certificate ui again
|
||||
@@ -156,7 +157,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
$scope.location = {
|
||||
busy: false,
|
||||
error: {},
|
||||
success: false,
|
||||
domainCollisions: [],
|
||||
|
||||
domain: null,
|
||||
location: '',
|
||||
@@ -182,6 +183,7 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
var app = $scope.app;
|
||||
|
||||
$scope.location.error = {};
|
||||
$scope.location.domainCollisions = [];
|
||||
$scope.location.location = app.location;
|
||||
$scope.location.domain = $scope.domains.filter(function (d) { return d.domain === app.domain; })[0];
|
||||
$scope.location.portBindingsInfo = angular.extend({}, app.manifest.tcpPorts, app.manifest.udpPorts); // Portbinding map only for information
|
||||
@@ -199,9 +201,12 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
}
|
||||
},
|
||||
|
||||
submit: function () {
|
||||
submit: function (overwriteDns) {
|
||||
$('#domainCollisionsModal').modal('hide');
|
||||
|
||||
$scope.location.busy = true;
|
||||
$scope.location.error = {};
|
||||
$scope.location.domainCollisions = [];
|
||||
|
||||
// only use enabled ports from portBindings
|
||||
var portBindings = {};
|
||||
@@ -212,30 +217,62 @@ angular.module('Application').controller('AppController', ['$scope', '$location'
|
||||
}
|
||||
|
||||
var data = {
|
||||
overwriteDns: !!overwriteDns,
|
||||
location: $scope.location.location,
|
||||
domain: $scope.location.domain.domain,
|
||||
portBindings: portBindings,
|
||||
alternateDomains: $scope.location.alternateDomains.map(function (a) { return { subdomain: a.subdomain, domain: a.domain.domain };})
|
||||
};
|
||||
|
||||
Client.configureApp($scope.app.id, 'location', data, function (error) {
|
||||
if (error && (error.statusCode === 409 || error.statusCode === 400)) {
|
||||
if ((error.location && error.domain) || error.field === 'location') {
|
||||
$scope.location.error.location = error.message;
|
||||
$scope.locationForm.$setPristine();
|
||||
} else {
|
||||
$scope.location.error.alternateDomains = error.message;
|
||||
}
|
||||
// pre-flight only for changed domains
|
||||
var domains = [];
|
||||
if ($scope.app.domain !== data.domain || $scope.app.location !== data.location) domains.push({ subdomain: data.location, domain: data.domain });
|
||||
data.alternateDomains.forEach(function (a) {
|
||||
if ($scope.app.alternateDomains.some(function (d) { return d.domain === a.domain && d.subdomain === a.subdomain; })) return;
|
||||
domains.push({ subdomain: a.subdomain, domain: a.domain });
|
||||
});
|
||||
|
||||
asyncForEach(domains, function (domain, callback) {
|
||||
if (overwriteDns) return callback();
|
||||
|
||||
Client.getDNSRecords(domain.domain, domain.subdomain, 'A', function (error, result) {
|
||||
// TODO handle credential errors
|
||||
if (error) return callback(error);
|
||||
|
||||
if (result.length) $scope.location.domainCollisions.push(domain);
|
||||
|
||||
callback();
|
||||
});
|
||||
}, function (error) {
|
||||
if (error) {
|
||||
$scope.location.busy = false;
|
||||
return;
|
||||
return Client.error(error);
|
||||
}
|
||||
if (error) return Client.error(error);
|
||||
|
||||
$scope.location.success = true;
|
||||
$scope.location.busy = false;
|
||||
if ($scope.location.domainCollisions.length) {
|
||||
$scope.location.busy = false;
|
||||
return $('#domainCollisionsModal').modal('show');
|
||||
}
|
||||
|
||||
refreshApp();
|
||||
Client.configureApp($scope.app.id, 'location', data, function (error) {
|
||||
if (error && (error.statusCode === 409 || error.statusCode === 400)) {
|
||||
if ((error.location && error.domain) || error.field === 'location') {
|
||||
$scope.location.error.location = error.message;
|
||||
$scope.locationForm.$setPristine();
|
||||
} else {
|
||||
$scope.location.error.alternateDomains = error.message;
|
||||
}
|
||||
|
||||
$scope.location.busy = false;
|
||||
return;
|
||||
}
|
||||
if (error) return Client.error(error);
|
||||
|
||||
$scope.locationForm.$setPristine();
|
||||
$scope.location.busy = false;
|
||||
|
||||
refreshApp();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user