host.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. const _ = require('lodash');
  2. const proxyHostModel = require('../models/proxy_host');
  3. const redirectionHostModel = require('../models/redirection_host');
  4. const deadHostModel = require('../models/dead_host');
  5. const internalHost = {
  6. /**
  7. * Makes sure that the ssl_* and hsts_* fields play nicely together.
  8. * ie: if there is no cert, then force_ssl is off.
  9. * if force_ssl is off, then hsts_enabled is definitely off.
  10. *
  11. * @param {object} data
  12. * @param {object} [existing_data]
  13. * @returns {object}
  14. */
  15. cleanSslHstsData: function (data, existing_data) {
  16. existing_data = existing_data === undefined ? {} : existing_data;
  17. let combined_data = _.assign({}, existing_data, data);
  18. if (!combined_data.certificate_id) {
  19. combined_data.ssl_forced = false;
  20. combined_data.http2_support = false;
  21. }
  22. if (!combined_data.ssl_forced) {
  23. combined_data.hsts_enabled = false;
  24. }
  25. if (!combined_data.hsts_enabled) {
  26. combined_data.hsts_subdomains = false;
  27. }
  28. return combined_data;
  29. },
  30. /**
  31. * used by the getAll functions of hosts, this removes the certificate meta if present
  32. *
  33. * @param {Array} rows
  34. * @returns {Array}
  35. */
  36. cleanAllRowsCertificateMeta: function (rows) {
  37. rows.map(function (row, idx) {
  38. if (typeof rows[idx].certificate !== 'undefined' && rows[idx].certificate) {
  39. rows[idx].certificate.meta = {};
  40. }
  41. });
  42. return rows;
  43. },
  44. /**
  45. * used by the get/update functions of hosts, this removes the certificate meta if present
  46. *
  47. * @param {Object} row
  48. * @returns {Object}
  49. */
  50. cleanRowCertificateMeta: function (row) {
  51. if (typeof row.certificate !== 'undefined' && row.certificate) {
  52. row.certificate.meta = {};
  53. }
  54. return row;
  55. },
  56. /**
  57. * This returns all the host types with any domain listed in the provided domain_names array.
  58. * This is used by the certificates to temporarily disable any host that is using the domain
  59. *
  60. * @param {Array} domain_names
  61. * @returns {Promise}
  62. */
  63. getHostsWithDomains: function (domain_names) {
  64. let promises = [
  65. proxyHostModel
  66. .query()
  67. .where('is_deleted', 0),
  68. redirectionHostModel
  69. .query()
  70. .where('is_deleted', 0),
  71. deadHostModel
  72. .query()
  73. .where('is_deleted', 0)
  74. ];
  75. return Promise.all(promises)
  76. .then((promises_results) => {
  77. let response_object = {
  78. total_count: 0,
  79. dead_hosts: [],
  80. proxy_hosts: [],
  81. redirection_hosts: []
  82. };
  83. if (promises_results[0]) {
  84. // Proxy Hosts
  85. response_object.proxy_hosts = internalHost._getHostsWithDomains(promises_results[0], domain_names);
  86. response_object.total_count += response_object.proxy_hosts.length;
  87. }
  88. if (promises_results[1]) {
  89. // Redirection Hosts
  90. response_object.redirection_hosts = internalHost._getHostsWithDomains(promises_results[1], domain_names);
  91. response_object.total_count += response_object.redirection_hosts.length;
  92. }
  93. if (promises_results[2]) {
  94. // Dead Hosts
  95. response_object.dead_hosts = internalHost._getHostsWithDomains(promises_results[2], domain_names);
  96. response_object.total_count += response_object.dead_hosts.length;
  97. }
  98. return response_object;
  99. });
  100. },
  101. /**
  102. * Internal use only, checks to see if the domain is already taken by any other record
  103. *
  104. * @param {String} hostname
  105. * @param {String} [ignore_type] 'proxy', 'redirection', 'dead'
  106. * @param {Integer} [ignore_id] Must be supplied if type was also supplied
  107. * @returns {Promise}
  108. */
  109. isHostnameTaken: function (hostname, ignore_type, ignore_id) {
  110. let promises = [
  111. proxyHostModel
  112. .query()
  113. .where('is_deleted', 0)
  114. .andWhere('domain_names', 'like', '%' + hostname + '%'),
  115. redirectionHostModel
  116. .query()
  117. .where('is_deleted', 0)
  118. .andWhere('domain_names', 'like', '%' + hostname + '%'),
  119. deadHostModel
  120. .query()
  121. .where('is_deleted', 0)
  122. .andWhere('domain_names', 'like', '%' + hostname + '%')
  123. ];
  124. return Promise.all(promises)
  125. .then((promises_results) => {
  126. let is_taken = false;
  127. if (promises_results[0]) {
  128. // Proxy Hosts
  129. if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[0], ignore_type === 'proxy' && ignore_id ? ignore_id : 0)) {
  130. is_taken = true;
  131. }
  132. }
  133. if (promises_results[1]) {
  134. // Redirection Hosts
  135. if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[1], ignore_type === 'redirection' && ignore_id ? ignore_id : 0)) {
  136. is_taken = true;
  137. }
  138. }
  139. if (promises_results[2]) {
  140. // Dead Hosts
  141. if (internalHost._checkHostnameRecordsTaken(hostname, promises_results[2], ignore_type === 'dead' && ignore_id ? ignore_id : 0)) {
  142. is_taken = true;
  143. }
  144. }
  145. return {
  146. hostname: hostname,
  147. is_taken: is_taken
  148. };
  149. });
  150. },
  151. /**
  152. * Private call only
  153. *
  154. * @param {String} hostname
  155. * @param {Array} existing_rows
  156. * @param {Integer} [ignore_id]
  157. * @returns {Boolean}
  158. */
  159. _checkHostnameRecordsTaken: function (hostname, existing_rows, ignore_id) {
  160. let is_taken = false;
  161. if (existing_rows && existing_rows.length) {
  162. existing_rows.map(function (existing_row) {
  163. existing_row.domain_names.map(function (existing_hostname) {
  164. // Does this domain match?
  165. if (existing_hostname.toLowerCase() === hostname.toLowerCase()) {
  166. if (!ignore_id || ignore_id !== existing_row.id) {
  167. is_taken = true;
  168. }
  169. }
  170. });
  171. });
  172. }
  173. return is_taken;
  174. },
  175. /**
  176. * Private call only
  177. *
  178. * @param {Array} hosts
  179. * @param {Array} domain_names
  180. * @returns {Array}
  181. */
  182. _getHostsWithDomains: function (hosts, domain_names) {
  183. let response = [];
  184. if (hosts && hosts.length) {
  185. hosts.map(function (host) {
  186. let host_matches = false;
  187. domain_names.map(function (domain_name) {
  188. host.domain_names.map(function (host_domain_name) {
  189. if (domain_name.toLowerCase() === host_domain_name.toLowerCase()) {
  190. host_matches = true;
  191. }
  192. });
  193. });
  194. if (host_matches) {
  195. response.push(host);
  196. }
  197. });
  198. }
  199. return response;
  200. }
  201. };
  202. module.exports = internalHost;