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'); + } + }, + ); +};