host.js 6.1 KB

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