From 15978689c0f2166b28cafdb70a6f6c88e3930020 Mon Sep 17 00:00:00 2001
From: Fabien 'egg' O'Carroll <fabien@allou.is>
Date: Tue, 9 Mar 2021 16:15:10 +0000
Subject: [PATCH] Added default value to accent_color setting (#12743)

refs TryGhost/Team#535

We want to ensure that a site will always have a default value of
`'#15171A'` for the accent_color setting.

Since the boot process changed we have three cases to account for:

1. Setting does not exist
2. Setting exists with no value
3. Setting exists with a value

It is only in the case of 2. that we want the migration to update the
database with a default value.

In the case of 3. the site owner has already set a value, which we do
not want to override.

In the case of 1. the setting will be created (and populated with
default value) from the default-settings.json file, by the
populateDefaults method called from the settings service

We also update the accent_color setting to include a non-empty
validation, to ensure that the setting will always have a value, as
sites before 4.x may have an empty accent_color, we must update the
importer to set the default value if one is not present. Otherwise we
would run into validation errors and even if we didn't would have an
invalid database state.
---
 .../data/importer/importers/data/settings.js  |  5 +++++
 .../4.0/30-set-default-accent-color.js        | 21 +++++++++++++++++++
 core/server/data/schema/default-settings.json |  5 ++++-
 test/unit/data/schema/integrity_spec.js       |  2 +-
 test/utils/fixtures/export/v4_export.json     |  2 +-
 5 files changed, 32 insertions(+), 3 deletions(-)
 create mode 100644 core/server/data/migrations/versions/4.0/30-set-default-accent-color.js

diff --git a/core/server/data/importer/importers/data/settings.js b/core/server/data/importer/importers/data/settings.js
index 0f7ec90a24..db6bc75b8c 100644
--- a/core/server/data/importer/importers/data/settings.js
+++ b/core/server/data/importer/importers/data/settings.js
@@ -159,6 +159,11 @@ class SettingsImporter extends BaseImporter {
                 data.type = keyTypeMapper(data.key);
             }
 
+            // accent_color can be empty pre-4.x
+            if (data.key === 'accent_color' && !data.value) {
+                data.value = '#15171A';
+            }
+
             return data;
         });
 
diff --git a/core/server/data/migrations/versions/4.0/30-set-default-accent-color.js b/core/server/data/migrations/versions/4.0/30-set-default-accent-color.js
new file mode 100644
index 0000000000..3e26ead47d
--- /dev/null
+++ b/core/server/data/migrations/versions/4.0/30-set-default-accent-color.js
@@ -0,0 +1,21 @@
+const logging = require('../../../../../shared/logging');
+const {createTransactionalMigration} = require('../../utils');
+
+module.exports = createTransactionalMigration(async function up(knex) {
+    const existingSetting = await knex.select('*').from('settings').where('key', 'accent_color').first();
+
+    if (!existingSetting) {
+        logging.warn(`Not setting value of accent_color, setting does not exist`);
+        return;
+    }
+
+    if (existingSetting.value) {
+        logging.warn(`Not setting value of accent_color, value of ${existingSetting.value} already present`);
+        return;
+    }
+
+    logging.info('Setting value of accent_color to default #15171A');
+    await knex('settings').update('value', '#15171A').where('key', 'accent_color');
+}, async function down() {
+    // noop
+});
diff --git a/core/server/data/schema/default-settings.json b/core/server/data/schema/default-settings.json
index cbebf602dc..a1b206df02 100644
--- a/core/server/data/schema/default-settings.json
+++ b/core/server/data/schema/default-settings.json
@@ -87,8 +87,11 @@
             "type": "string"
         },
         "accent_color": {
-            "defaultValue": "",
+            "defaultValue": "#15171A",
             "flags": "PUBLIC",
+            "validations": {
+                "isEmpty": false
+            },
             "type": "string"
         },
         "lang": {
diff --git a/test/unit/data/schema/integrity_spec.js b/test/unit/data/schema/integrity_spec.js
index 5e548ccb41..c4b6cb4b88 100644
--- a/test/unit/data/schema/integrity_spec.js
+++ b/test/unit/data/schema/integrity_spec.js
@@ -34,7 +34,7 @@ describe('DB version integrity', function () {
     // Only these variables should need updating
     const currentSchemaHash = '559cdbb49a7eeb5758caf0c6e3bf790d';
     const currentFixturesHash = '5f6f69931811c407dff01da9ef9667f4';
-    const currentSettingsHash = 'e1f85186a7c7ed76064b6026f68c6321';
+    const currentSettingsHash = 'a787bc3c1812b56a498b9ac5f8900f63';
     const currentRoutesHash = '3d180d52c663d173a6be791ef411ed01';
 
     // If this test is failing, then it is likely a change has been made that requires a DB version bump,
diff --git a/test/utils/fixtures/export/v4_export.json b/test/utils/fixtures/export/v4_export.json
index f264994a5c..812bc6101f 100644
--- a/test/utils/fixtures/export/v4_export.json
+++ b/test/utils/fixtures/export/v4_export.json
@@ -2376,7 +2376,7 @@
                         "id": "6029c95ba526f951dabea4d7",
                         "group": "site",
                         "key": "accent_color",
-                        "value": "",
+                        "value": "#15171A",
                         "type": "string",
                         "flags": "PUBLIC",
                         "created_at": "2021-02-15T14:07:39.000Z",