Просмотр исходного кода

GC-1033: impl init-serverUrl migration

Yuki Takei 7 лет назад
Родитель
Сommit
9f20e1ec62
3 измененных файлов с 100 добавлено и 9 удалено
  1. 3 1
      package.json
  2. 94 0
      src/migrations/20180927102719-init-serverurl.js
  3. 3 8
      src/server/models/config.js

+ 3 - 1
package.json

@@ -37,9 +37,11 @@
     "heroku-postbuild": "sh bin/heroku/install-plugins.sh && npm run build:prod",
     "lint:fix": "eslint . --fix",
     "lint": "eslint .",
-    "migrate": "migrate-mongo up -f config/migrate.js",
+    "migrate": "npm run migrate:up",
     "migrate:create": "migrate-mongo create -f config/migrate.js -- ",
     "migrate:status": "migrate-mongo status -f config/migrate.js",
+    "migrate:up": "migrate-mongo up -f config/migrate.js",
+    "migrate:down": "migrate-mongo down -f config/migrate.js",
     "mkdirp": "mkdirp",
     "plugin:def": "node bin/generate-plugin-definitions-source.js",
     "prebuild:dev:app": "env-cmd config/env.dev.js npm run plugin:def",

+ 94 - 0
src/migrations/20180927102719-init-serverurl.js

@@ -0,0 +1,94 @@
+'use strict';
+
+require('module-alias/register');
+const logger = require('@alias/logger')('growi:migrate:init-serverurl');
+
+const mongoose = require('mongoose');
+const config = require('@root/config/migrate');
+
+const queryToFindSiteUrl = {
+  ns: 'crowi',
+  key: 'app:siteUrl',
+};
+
+/**
+ * check all values of the array are equal
+ * @see https://stackoverflow.com/a/35568895
+ */
+function isAllValuesSame(array) {
+  return !!array.reduce((a, b) => {
+    return (a === b) ? a : NaN;
+  });
+}
+
+module.exports = {
+
+  async up(db) {
+    logger.info('Apply migration');
+    mongoose.connect(config.mongoUri, config.mongodb.options);
+
+    const Config = require('@server/models/config')();
+
+    // find 'app:siteUrl'
+    const siteUrlConfig = await Config.findOne({
+      ns: 'crowi',
+      key: 'app:siteUrl',
+    });
+    // exit if exists
+    if (siteUrlConfig != null) {
+      logger.info('\'app:siteUrl\' is already exists. This migration terminates without any changes.');
+      return;
+    }
+
+    // find all callbackUrls
+    const configs = await Config.find({
+      ns: 'crowi',
+      $or: [
+        { key: 'security:passport-github:callbackUrl' },
+        { key: 'security:passport-google:callbackUrl' },
+        { key: 'security:passport-twitter:callbackUrl' },
+        { key: 'security:passport-saml:callbackUrl' },
+      ]
+    });
+
+    // determine serverUrl
+    let siteUrl;
+    if (configs.length > 0) {
+      logger.info(`${configs.length} configs which has callbackUrl found: `);
+      logger.info(configs);
+
+      // extract domain
+      const siteUrls = configs.map(config => {
+        // see https://regex101.com/r/Q0Isjo/2
+        const match = config.value.match(/^"(https?:\/\/[^/]+).*"$/);
+        return (match != null) ? match[1] : null;
+      }).filter(value => value != null);
+
+      // determine serverUrl if all values are same
+      if (siteUrls.length > 0 && isAllValuesSame(siteUrls)) {
+        siteUrl = siteUrls[0];
+      }
+    }
+
+    if (siteUrl != null) {
+      await Config.findOneAndUpdateByNsAndKey('crowi', 'app:siteUrl', siteUrl);
+      logger.info('Migration has successfully applied');
+    }
+  },
+
+  async down(db) {
+    logger.info('Undo migration');
+    mongoose.connect(config.mongoUri, config.mongodb.options);
+
+    const Config = require('@server/models/config')();
+
+    // remote 'app:siteUrl'
+    await Config.findOneAndDelete({
+      ns: 'crowi',
+      key: 'app:siteUrl',
+    });
+
+    logger.info('Migration has successfully undoed');
+  }
+
+};

+ 3 - 8
src/server/models/config.js

@@ -231,16 +231,11 @@ module.exports = function(crowi) {
     return callback(null, configs);
   };
 
-  configSchema.statics.findAndUpdate = function(ns, key, value, callback) {
-    var Config = this;
-    Config.findOneAndUpdate(
+  configSchema.statics.findOneAndUpdateByNsAndKey = async function(ns, key, value) {
+    return this.findOneAndUpdate(
       { ns: ns, key: key },
       { ns: ns, key: key, value: JSON.stringify(value) },
-      { upsert: true, },
-      function(err, config) {
-        debug('Config.findAndUpdate', err, config);
-        callback(err, config);
-      });
+      { upsert: true, });
   };
 
   configSchema.statics.getConfig = function(callback) {