From 40e81801135eb7009ba0304f3ba82cd58ce0fe6e Mon Sep 17 00:00:00 2001
From: Vidya Haikal <vidya.haikal@hukumonline.com>
Date: Wed, 23 Oct 2024 22:04:45 +0700
Subject: [PATCH] feat: Initialize user when spin api-service

---
 .env                                     |  2 +
 docker-compose.dev.yml                   |  2 +
 docker-compose.yml                       |  2 +
 packages/api/src/config.ts               |  2 +
 packages/api/src/server.ts               |  2 +
 packages/api/src/utils/userInitialize.ts | 56 ++++++++++++++++++++++++
 6 files changed, 66 insertions(+)
 create mode 100644 packages/api/src/utils/userInitialize.ts

diff --git a/.env b/.env
index 865453cb1..afed2d562 100644
--- a/.env
+++ b/.env
@@ -12,3 +12,5 @@ HYPERDX_APP_URL=http://localhost
 HYPERDX_LOG_LEVEL=debug
 OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 # port is fixed
 
+EMAIL=
+PASSWORD=
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index 0261db5fa..fde6d1231 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -225,6 +225,8 @@ services:
       REDIS_URL: redis://redis:6379
       SERVER_URL: 'http://localhost:8000'
       USAGE_STATS_ENABLED: ${USAGE_STATS_ENABLED:-false}
+      EMAIL: ${EMAIL}
+      PASSWORD: ${PASSWORD}
     volumes:
       - ./packages/api/src:/app/src
     networks:
diff --git a/docker-compose.yml b/docker-compose.yml
index a49eb0e71..44620c687 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -178,6 +178,8 @@ services:
       REDIS_URL: redis://redis:6379
       SERVER_URL: ${HYPERDX_API_URL}:${HYPERDX_API_PORT}
       USAGE_STATS_ENABLED: ${USAGE_STATS_ENABLED:-true}
+      EMAIL: ${EMAIL}
+      PASSWORD: ${PASSWORD}
     networks:
       - internal
     depends_on:
diff --git a/packages/api/src/config.ts b/packages/api/src/config.ts
index 7cb304e75..23ebf57e0 100644
--- a/packages/api/src/config.ts
+++ b/packages/api/src/config.ts
@@ -28,6 +28,8 @@ export const PORT = Number.parseInt(env.PORT as string);
 export const REDIS_URL = env.REDIS_URL as string;
 export const SERVER_URL = env.SERVER_URL as string;
 export const USAGE_STATS_ENABLED = env.USAGE_STATS_ENABLED !== 'false';
+export const EMAIL = env.EMAIL as string;
+export const PASSWORD = env.PASSWORD as string;
 
 // Only for single container local deployments, disable authentication
 export const IS_LOCAL_APP_MODE =
diff --git a/packages/api/src/server.ts b/packages/api/src/server.ts
index 5ef9535a7..d6640cc55 100644
--- a/packages/api/src/server.ts
+++ b/packages/api/src/server.ts
@@ -7,6 +7,7 @@ import * as config from './config';
 import { connectDB, mongooseConnection } from './models';
 import logger from './utils/logger';
 import redisClient from './utils/redis';
+import { userInitialize } from './utils/userInitialize';
 
 export default class Server {
   protected readonly appType = config.APP_TYPE;
@@ -99,6 +100,7 @@ export default class Server {
       connectDB(),
       redisClient.connect(),
       clickhouse.connect(),
+      userInitialize(),
     ]);
   }
 }
diff --git a/packages/api/src/utils/userInitialize.ts b/packages/api/src/utils/userInitialize.ts
new file mode 100644
index 000000000..6002d0ec3
--- /dev/null
+++ b/packages/api/src/utils/userInitialize.ts
@@ -0,0 +1,56 @@
+import * as config from '@/config';
+import { createTeam, isTeamExisting } from '@/controllers/team';
+import { findUserByEmail } from '@/controllers/user';
+import User from '@/models/user';
+
+import logger from './logger';
+
+export const userInitialize = async () => {
+  logger.info('Initializing user...');
+  const email = config.EMAIL;
+  const password = config.PASSWORD;
+
+  if (!email && !password) {
+    return;
+  }
+
+  if (email === '' && password === '') {
+    logger.error('Email and password must not be empty');
+    logger.info('Continuing without initializing user');
+    return;
+  }
+
+  const user = await findUserByEmail(email);
+
+  if (user) {
+    logger.info('User already exists');
+    return;
+  }
+
+  if (await isTeamExisting()) {
+    logger.info('Team already exists');
+    return;
+  }
+
+  (User as any).register(
+    new User({ email }),
+    password,
+    async (err: Error, user: any) => {
+      if (err) {
+        throw new Error(err.message);
+      }
+
+      const team = await createTeam({
+        name: `${email}'s Team`,
+      });
+      user.team = team._id;
+      user.name = email;
+      try {
+        await user.save();
+        logger.info('User initialized successfully, with email: ', email);
+      } catch (e) {
+        logger.error('Failed to initializing user');
+      }
+    },
+  );
+};