From efa1424cad5ac64133b5783456ae806f2e34b649 Mon Sep 17 00:00:00 2001
From: Jamie Curnow <jcurnow@vision6.com.au>
Date: Wed, 12 Sep 2018 11:14:06 +1000
Subject: [PATCH] Fixes #11 - After creating keys the app needs to completely
 restart due to aggressive module caching

---
 rootfs/etc/services.d/manager/run |  7 ++-
 src/backend/importer.js           | 13 +++--
 src/backend/logger.js             |  1 +
 src/backend/setup.js              | 95 ++++++++++++++++++-------------
 4 files changed, 71 insertions(+), 45 deletions(-)

diff --git a/rootfs/etc/services.d/manager/run b/rootfs/etc/services.d/manager/run
index f70905d..c4ade6d 100755
--- a/rootfs/etc/services.d/manager/run
+++ b/rootfs/etc/services.d/manager/run
@@ -3,4 +3,9 @@
 mkdir -p /data/letsencrypt-acme-challenge
 
 cd /app
-node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
+
+while :
+do
+    node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
+    sleep 1
+done
diff --git a/src/backend/importer.js b/src/backend/importer.js
index 25a36b6..b6699e3 100644
--- a/src/backend/importer.js
+++ b/src/backend/importer.js
@@ -1,9 +1,10 @@
 'use strict';
 
-const fs        = require('fs');
-const logger    = require('./logger').import;
-const utils     = require('./lib/utils');
-const batchflow = require('batchflow');
+const fs         = require('fs');
+const logger     = require('./logger').import;
+const utils      = require('./lib/utils');
+const batchflow  = require('batchflow');
+const debug_mode = process.env.NODE_ENV !== 'production';
 
 const internalProxyHost       = require('./internal/proxy-host');
 const internalRedirectionHost = require('./internal/redirection-host');
@@ -534,6 +535,10 @@ module.exports = function () {
             );
 
         } else {
+            if (debug_mode) {
+                logger.debug('Importer skipped');
+            }
+
             resolve();
         }
     });
diff --git a/src/backend/logger.js b/src/backend/logger.js
index 2c618fd..589b327 100644
--- a/src/backend/logger.js
+++ b/src/backend/logger.js
@@ -8,4 +8,5 @@ module.exports = {
     nginx:   new Signale({scope: 'Nginx   '}),
     ssl:     new Signale({scope: 'SSL     '}),
     import:  new Signale({scope: 'Importer'}),
+    setup:   new Signale({scope: 'Setup   '})
 };
diff --git a/src/backend/setup.js b/src/backend/setup.js
index 5015cbc..3a66080 100644
--- a/src/backend/setup.js
+++ b/src/backend/setup.js
@@ -3,10 +3,11 @@
 const fs                  = require('fs');
 const NodeRSA             = require('node-rsa');
 const config              = require('config');
-const logger              = require('./logger').global;
+const logger              = require('./logger').setup;
 const userModel           = require('./models/user');
 const userPermissionModel = require('./models/user_permission');
 const authModel           = require('./models/auth');
+const debug_mode          = process.env.NODE_ENV !== 'production';
 
 module.exports = function () {
     return new Promise((resolve, reject) => {
@@ -22,6 +23,9 @@ module.exports = function () {
                 config_data = require(filename);
             } catch (err) {
                 // do nothing
+                if (debug_mode) {
+                    logger.debug(filename + ' config file could not be required');
+                }
             }
 
             // Now create the keys and save them in the config.
@@ -40,12 +44,18 @@ module.exports = function () {
                     reject(err);
                 } else {
                     logger.info('Wrote JWT key pair to config file: ' + filename);
-                    config.util.loadFileConfigs();
-                    resolve();
+
+                    logger.warn('Restarting interface to apply new configuration');
+                    process.exit(0);
                 }
             });
+
         } else {
             // JWT key pair exists
+            if (debug_mode) {
+                logger.debug('JWT Keypair already exists');
+            }
+
             resolve();
         }
     })
@@ -54,49 +64,54 @@ module.exports = function () {
                 .query()
                 .select(userModel.raw('COUNT(`id`) as `count`'))
                 .where('is_deleted', 0)
-                .first('count')
-                .then(row => {
-                    if (!row.count) {
-                        // Create a new user and set password
-                        logger.info('Creating a new user: admin@example.com with password: changeme');
+                .first();
+        })
+        .then(row => {
+            if (!row.count) {
+                // Create a new user and set password
+                logger.info('Creating a new user: admin@example.com with password: changeme');
 
-                        let data = {
-                            is_deleted: 0,
-                            email:      'admin@example.com',
-                            name:       'Administrator',
-                            nickname:   'Admin',
-                            avatar:     '',
-                            roles:      ['admin']
-                        };
+                let data = {
+                    is_deleted: 0,
+                    email:      'admin@example.com',
+                    name:       'Administrator',
+                    nickname:   'Admin',
+                    avatar:     '',
+                    roles:      ['admin']
+                };
 
-                        return userModel
+                return userModel
+                    .query()
+                    .insertAndFetch(data)
+                    .then(user => {
+                        return authModel
                             .query()
-                            .insertAndFetch(data)
-                            .then(user => {
-                                return authModel
+                            .insert({
+                                user_id: user.id,
+                                type:    'password',
+                                secret:  'changeme',
+                                meta:    {}
+                            })
+                            .then(() => {
+                                return userPermissionModel
                                     .query()
                                     .insert({
-                                        user_id: user.id,
-                                        type:    'password',
-                                        secret:  'changeme',
-                                        meta:    {}
-                                    })
-                                    .then(() => {
-                                        return userPermissionModel
-                                            .query()
-                                            .insert({
-                                                user_id:           user.id,
-                                                visibility:        'all',
-                                                proxy_hosts:       'manage',
-                                                redirection_hosts: 'manage',
-                                                dead_hosts:        'manage',
-                                                streams:           'manage',
-                                                access_lists:      'manage',
-                                                certificates:      'manage'
-                                            });
+                                        user_id:           user.id,
+                                        visibility:        'all',
+                                        proxy_hosts:       'manage',
+                                        redirection_hosts: 'manage',
+                                        dead_hosts:        'manage',
+                                        streams:           'manage',
+                                        access_lists:      'manage',
+                                        certificates:      'manage'
                                     });
                             });
-                    }
-                });
+                    })
+                    .then(() => {
+                        logger.info('Initial setup completed');
+                    });
+            } else if (debug_mode) {
+                logger.debug('Admin user setup not required');
+            }
         });
 };