20180927102719-init-serverurl.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import mongoose from 'mongoose';
  2. // eslint-disable-next-line import/no-named-as-default
  3. import Config from '~/server/models/config';
  4. import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
  5. import loggerFactory from '~/utils/logger';
  6. const logger = loggerFactory('growi:migrate:init-serverurl');
  7. /**
  8. * check all values of the array are equal
  9. * @see https://stackoverflow.com/a/35568895
  10. */
  11. function isAllValuesSame(array) {
  12. return !!array.reduce((a, b) => {
  13. return (a === b) ? a : NaN;
  14. });
  15. }
  16. module.exports = {
  17. async up(db) {
  18. logger.info('Apply migration');
  19. mongoose.connect(getMongoUri(), mongoOptions);
  20. // find 'app:siteUrl'
  21. const siteUrlConfig = await Config.findOne({
  22. ns: 'crowi',
  23. key: 'app:siteUrl',
  24. });
  25. // exit if exists
  26. if (siteUrlConfig != null) {
  27. logger.info('\'app:siteUrl\' is already exists. This migration terminates without any changes.');
  28. return;
  29. }
  30. // find all callbackUrls
  31. const configs = await Config.find({
  32. ns: 'crowi',
  33. $or: [
  34. { key: 'security:passport-github:callbackUrl' },
  35. { key: 'security:passport-google:callbackUrl' },
  36. { key: 'security:passport-twitter:callbackUrl' },
  37. { key: 'security:passport-saml:callbackUrl' },
  38. ],
  39. });
  40. // determine serverUrl
  41. let siteUrl;
  42. if (configs.length > 0) {
  43. logger.info(`${configs.length} configs which has callbackUrl found: `);
  44. logger.info(configs);
  45. // extract domain
  46. const siteUrls = configs.map((config) => {
  47. // see https://regex101.com/r/Q0Isjo/2
  48. const match = config.value.match(/^"(https?:\/\/[^/]+).*"$/);
  49. return (match != null) ? match[1] : null;
  50. }).filter((value) => { return value != null });
  51. // determine serverUrl if all values are same
  52. if (siteUrls.length > 0 && isAllValuesSame(siteUrls)) {
  53. siteUrl = siteUrls[0];
  54. }
  55. }
  56. if (siteUrl != null) {
  57. const ns = 'crowi';
  58. const key = 'app:siteUrl';
  59. await Config.findOneAndUpdate(
  60. { ns, key },
  61. { ns, key, value: JSON.stringify(siteUrl) },
  62. { upsert: true },
  63. );
  64. logger.info('Migration has successfully applied');
  65. }
  66. },
  67. async down(db) {
  68. logger.info('Rollback migration');
  69. mongoose.connect(getMongoUri(), mongoOptions);
  70. // remote 'app:siteUrl'
  71. await Config.findOneAndDelete({
  72. ns: 'crowi',
  73. key: 'app:siteUrl',
  74. });
  75. logger.info('Migration has been successfully rollbacked');
  76. },
  77. };