Files
cloudron-box/src/js/setupdns.js

233 lines
9.2 KiB
JavaScript
Raw Normal View History

2018-01-22 13:01:38 -08:00
'use strict';
/* global tld */
// create main application module
2018-05-15 15:46:24 -07:00
var app = angular.module('Application', ['angular-md5', 'ui-notification', 'ui.bootstrap']);
2018-01-22 13:01:38 -08:00
app.filter('zoneName', function () {
return function (domain) {
return tld.getDomain(domain);
};
});
app.controller('SetupDNSController', ['$scope', '$http', '$timeout', 'Client', function ($scope, $http, $timeout, Client) {
var search = decodeURIComponent(window.location.search).slice(1).split('&').map(function (item) { return item.split('='); }).reduce(function (o, k) { o[k[0]] = k[1]; return o; }, {});
$scope.state = null; // 'initialized', 'waitingForDnsSetup', 'waitingForBox'
$scope.error = null;
$scope.provider = '';
$scope.showDNSSetup = false;
$scope.instanceId = '';
$scope.isDomain = false;
$scope.isSubdomain = false;
$scope.hyphenatedSubdomains = false;
2018-05-15 15:46:24 -07:00
$scope.tlsProvider = [
{ name: 'Let\'s Encrypt Prod', value: 'letsencrypt-prod' },
{ name: 'Let\'s Encrypt Prod - Wildcard', value: 'letsencrypt-prod-wildcard' },
2018-05-15 15:46:24 -07:00
{ name: 'Let\'s Encrypt Staging', value: 'letsencrypt-staging' },
{ name: 'Let\'s Encrypt Staging - Wildcard', value: 'letsencrypt-staging-wildcard' },
{ name: 'Self-Signed', value: 'fallback' }, // this is not 'Custom' because we don't allow user to upload certs during setup phase
2018-05-15 15:46:24 -07:00
];
2018-01-22 13:01:38 -08:00
2018-09-12 14:40:12 -07:00
$scope.needsPort80 = function (dnsProvider, tlsProvider) {
return ((dnsProvider === 'manual' || dnsProvider === 'noop' || dnsProvider === 'wildcard') &&
(tlsProvider === 'letsencrypt-prod' || tlsProvider === 'letsencrypt-staging'));
};
$scope.setDefaultTlsProvider = function () {
var dnsProvider = $scope.domainConfigure.provider;
// wildcard LE won't work without automated DNS
if ((dnsProvider === 'manual' || dnsProvider === 'noop' || dnsProvider === 'wildcard')) {
$scope.domainConfigure.tlsProvider.provider = 'letsencrypt-prod';
} else {
$scope.domainConfigure.tlsProvider.provider = 'letsencrypt-prod-wildcard';
}
};
2018-01-22 13:01:38 -08:00
// If we migrate the api origin we have to poll the new location
if (search.admin_fqdn) Client.apiOrigin = 'https://' + search.admin_fqdn;
$scope.$watch('dnsCredentials.domain', function (newVal) {
if (!newVal) {
$scope.isDomain = false;
$scope.isSubdomain = false;
} else if (!tld.getDomain(newVal) || newVal[newVal.length-1] === '.') {
$scope.isDomain = false;
$scope.isSubdomain = false;
} else {
$scope.isDomain = true;
$scope.isSubdomain = tld.getDomain(newVal) !== newVal;
}
});
// keep in sync with domains.js
$scope.dnsProvider = [
{ name: 'AWS Route53', value: 'route53' },
{ name: 'Cloudflare (DNS only)', value: 'cloudflare' },
{ name: 'Digital Ocean', value: 'digitalocean' },
{ name: 'Gandi LiveDNS', value: 'gandi' },
2018-05-06 21:52:25 -07:00
{ name: 'GoDaddy', value: 'godaddy' },
2018-01-22 13:01:38 -08:00
{ name: 'Google Cloud DNS', value: 'gcdns' },
2018-05-09 18:44:03 +02:00
{ name: 'Name.com', value: 'namecom' },
2018-01-22 13:01:38 -08:00
{ name: 'Wildcard', value: 'wildcard' },
{ name: 'Manual (not recommended)', value: 'manual' },
{ name: 'No-op (only for development)', value: 'noop' }
];
$scope.dnsCredentials = {
error: null,
busy: false,
2018-05-15 15:46:24 -07:00
advancedVisible: false,
2018-01-22 13:01:38 -08:00
domain: '',
accessKeyId: '',
secretAccessKey: '',
gcdnsKey: { keyFileName: '', content: '' },
digitalOceanToken: '',
gandiApiKey: '',
2018-05-06 21:52:25 -07:00
cloudflareEmail: '',
cloudflareToken: '',
godaddyApiKey: '',
godaddyApiSecret: '',
2018-05-09 18:44:03 +02:00
nameComUsername: '',
nameComToken: '',
2018-05-15 15:46:24 -07:00
provider: 'route53',
zoneName: '',
tlsConfig: {
provider: 'letsencrypt-prod-wildcard'
},
hyphenatedSubdomains: false
2018-01-22 13:01:38 -08:00
};
function readFileLocally(obj, file, fileName) {
return function (event) {
$scope.$apply(function () {
obj[file] = null;
obj[fileName] = event.target.files[0].name;
var reader = new FileReader();
reader.onload = function (result) {
if (!result.target || !result.target.result) return console.error('Unable to read local file');
obj[file] = result.target.result;
};
reader.readAsText(event.target.files[0]);
});
};
}
document.getElementById('gcdnsKeyFileInput').onchange = readFileLocally($scope.dnsCredentials.gcdnsKey, 'content', 'keyFileName');
$scope.setDnsCredentials = function () {
$scope.dnsCredentials.busy = true;
$scope.dnsCredentials.error = null;
$scope.error = null;
var provider = $scope.dnsCredentials.provider;
var data = {
providerToken: $scope.instanceId,
2018-09-05 21:27:19 -07:00
hyphenatedSubdomains: $scope.dnsCredentials.hyphenatedSubdomains
2018-01-22 13:01:38 -08:00
};
if (provider === 'route53') {
data.accessKeyId = $scope.dnsCredentials.accessKeyId;
data.secretAccessKey = $scope.dnsCredentials.secretAccessKey;
2018-05-07 13:18:51 -07:00
} else if (provider === 'gcdns') {
2018-01-22 13:01:38 -08:00
try {
var serviceAccountKey = JSON.parse($scope.dnsCredentials.gcdnsKey.content);
data.projectId = serviceAccountKey.project_id;
data.credentials = {
client_email: serviceAccountKey.client_email,
private_key: serviceAccountKey.private_key
};
if (!data.projectId || !data.credentials || !data.credentials.client_email || !data.credentials.private_key) {
throw 'fields_missing';
}
} catch(e) {
$scope.dnsCredentials.error = 'Cannot parse Google Service Account Key';
$scope.dnsCredentials.busy = false;
return;
}
} else if (provider === 'digitalocean') {
data.token = $scope.dnsCredentials.digitalOceanToken;
} else if (provider === 'gandi') {
data.token = $scope.dnsCredentials.gandiApiKey;
2018-05-06 21:52:25 -07:00
} else if (provider === 'godaddy') {
data.apiKey = $scope.dnsCredentials.godaddyApiKey;
data.apiSecret = $scope.dnsCredentials.godaddyApiSecret;
2018-01-22 13:01:38 -08:00
} else if (provider === 'cloudflare') {
data.email = $scope.dnsCredentials.cloudflareEmail;
data.token = $scope.dnsCredentials.cloudflareToken;
2018-05-09 18:44:03 +02:00
} else if (provider === 'namecom') {
data.username = $scope.dnsCredentials.nameComUsername;
data.token = $scope.dnsCredentials.nameComToken;
2018-01-22 13:01:38 -08:00
}
2018-09-12 11:45:07 -07:00
var tlsConfig = {
provider: $scope.dnsCredentials.tlsConfig.provider,
wildcard: false
};
if ($scope.dnsCredentials.tlsConfig.provider.indexOf('-wildcard') !== -1) {
tlsConfig.provider = tlsConfig.provider.replace('-wildcard', '');
tlsConfig.wildcard = true;
}
Client.setupDnsConfig($scope.dnsCredentials.domain, $scope.dnsCredentials.zoneName, provider, data, tlsConfig, function (error) {
2018-06-15 20:54:15 -07:00
if (error && error.statusCode === 401) {
2018-01-22 13:01:38 -08:00
$scope.dnsCredentials.busy = false;
$scope.error = 'Wrong instance id provided.';
return;
} else if (error) {
$scope.dnsCredentials.busy = false;
$scope.dnsCredentials.error = error.message;
return;
}
waitForDnsSetup();
});
};
function waitForDnsSetup() {
$scope.state = 'waitingForDnsSetup';
Client.getStatus(function (error, status) {
// webadminStatus.dns is intentionally not tested. it can be false if dns creds are invalid
// runConfigurationChecks() in main.js will pick the .dns and show a notification
if (!error && status.adminFqdn && status.webadminStatus.tls) {
window.location.href = 'https://' + status.adminFqdn + '/setup.html';
}
setTimeout(waitForDnsSetup, 5000);
});
}
function initialize() {
Client.getStatus(function (error, status) {
if (error) {
// During domain migration, the box code restarts and can result in getStatus() failing temporarily
console.error(error);
$scope.state = 'waitingForBox';
return $timeout(initialize, 3000);
}
// domain is currently like a lock flag
if (status.adminFqdn) return waitForDnsSetup();
if (status.provider === 'digitalocean') $scope.dnsCredentials.provider = 'digitalocean';
2018-05-06 21:51:58 -07:00
if (status.provider === 'gce') $scope.dnsCredentials.provider = 'gcdns';
2018-01-22 13:01:38 -08:00
if (status.provider === 'ami') {
// remove route53 on ami
$scope.dnsProvider.shift();
$scope.dnsCredentials.provider = 'wildcard';
}
$scope.instanceId = search.instanceId;
$scope.provider = status.provider;
$scope.hyphenatedSubdomains = status.edition === 'hostingprovider';
2018-01-22 13:01:38 -08:00
$scope.state = 'initialized';
});
}
initialize();
}]);