diff --git a/packages/commons/src/token-verifier.test.ts b/packages/commons/src/token-verifier.test.ts index 3d087e26a0..5a8f98ebf5 100644 --- a/packages/commons/src/token-verifier.test.ts +++ b/packages/commons/src/token-verifier.test.ts @@ -50,7 +50,7 @@ describe('Token verifier module', () => { '111', // @ts-ignore { headers: { authorization: 'Bearer: 111' } }, - 'true', + true, 'http://auth.opencrvs.org' ) expect(result.isValid).toBe(true) @@ -86,7 +86,7 @@ describe('Token verifier module', () => { '111', // @ts-ignore { headers: { authorization: 'Bearer: 111' } }, - 'false', + false, 'http://auth.opencrvs.org' ) expect(result.isValid).toBe(true) diff --git a/packages/commons/src/token-verifier.ts b/packages/commons/src/token-verifier.ts index 9717e95633..cdfd3dec68 100644 --- a/packages/commons/src/token-verifier.ts +++ b/packages/commons/src/token-verifier.ts @@ -33,18 +33,18 @@ export const verifyToken = async (token: string, authUrl: string) => { export const validateFunc = async ( payload: any, request: Hapi.Request, - checkInvalidToken: string, + checkInvalidToken: boolean, authUrl: string ) => { - let valid - if (checkInvalidToken === 'true') { + let valid = false + if (checkInvalidToken) { valid = await verifyToken( request.headers.authorization.replace('Bearer ', ''), authUrl ) } - if (valid === true || checkInvalidToken !== 'true') { + if (valid || !checkInvalidToken) { return { isValid: true, credentials: payload diff --git a/packages/config/package.json b/packages/config/package.json index 9e58d864a6..843ad54b0f 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -20,8 +20,9 @@ "@hapi/boom": "^9.1.1", "@hapi/hapi": "^20.2.1", "@opencrvs/commons": "^1.3.0", - "fast-csv": "^4.3.6", "cross-env": "^7.0.0", + "envalid": "^8.0.0", + "fast-csv": "^4.3.6", "fp-ts": "^2.12.3", "hapi-auth-jwt2": "10.6.0", "hapi-pino": "^9.0.0", @@ -40,8 +41,8 @@ "devDependencies": { "@types/boom": "^7.3.1", "@types/fhir": "^0.0.30", - "@types/jwt-decode": "^2.2.1", "@types/jsonwebtoken": "^9.0.0", + "@types/jwt-decode": "^2.2.1", "@types/lodash": "^4.14.126", "@typescript-eslint/eslint-plugin": "^4.5.0", "@typescript-eslint/parser": "^4.5.0", @@ -53,8 +54,8 @@ "mockingoose": "^2.15.2", "nodemon": "^3.0.0", "prettier": "^2.5.0", - "ts-node": "^6.1.1", "ts-jest": "27.1.4", + "ts-node": "^6.1.1", "typescript": "4.9.5" }, "lint-staged": { diff --git a/packages/config/src/config/constants.ts b/packages/config/src/config/constants.ts index 2e578dcdcc..b0d4ce7328 100644 --- a/packages/config/src/config/constants.ts +++ b/packages/config/src/config/constants.ts @@ -9,34 +9,4 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ export const OPENCRVS_SPECIFICATION_URL = 'http://opencrvs.org/specs/' -export const HOST = process.env.HOST || 'localhost' -export const HOSTNAME = process.env.DOMAIN || '*' -export const LOGIN_URL = process.env.LOGIN_URL || 'http://localhost:3020/' -export const CLIENT_APP_URL = - process.env.CLIENT_APP_URL || 'http://localhost:3000/' -export const PORT = process.env.PORT || 2021 -// Services -export const GATEWAY_URL = process.env.GATEWAY_URL || 'http://localhost:7070/' -export const SEARCH_URL = process.env.SEARCH_URL || 'http://localhost:9090/' -export const METRICS_URL = process.env.METRICS_URL || 'http://localhost:1050' -export const AUTH_URL = process.env.AUTH_URL || 'http://localhost:4040' -export const COUNTRY_CONFIG_URL = - process.env.COUNTRY_CONFIG_URL || 'http://localhost:3040' -export const MONGO_URL = - process.env.MONGO_URL || 'mongodb://localhost/application-config' -export const USER_MANAGEMENT_URL = - process.env.USER_MANAGEMENT_URL || 'http://localhost:3030' -export const DOCUMENTS_URL = - process.env.DOCUMENTS_URL || 'http://localhost:9050' -export const SENTRY_DSN = process.env.SENTRY_DSN -export const CERT_PUBLIC_KEY_PATH = - (process.env.CERT_PUBLIC_KEY_PATH as string) || - '../../.secrets/public-key.pem' -export const PRODUCTION = process.env.NODE_ENV === 'production' -export const QA_ENV = process.env.QA_ENV || false -export const FHIR_URL = process.env.FHIR_URL || 'http://localhost:3447/fhir' - -// Check if the token has been invalided in the auth service before it has expired -// This needs to be a string to make it easy to pass as an ENV var. -export const CHECK_INVALID_TOKEN = process.env.CHECK_INVALID_TOKEN || 'false' export const DEFAULT_TIMEOUT = 600000 diff --git a/packages/config/src/config/database.ts b/packages/config/src/config/database.ts index f356240fda..5e9574bc54 100644 --- a/packages/config/src/config/database.ts +++ b/packages/config/src/config/database.ts @@ -9,7 +9,7 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ import * as mongoose from 'mongoose' -import { MONGO_URL } from '@config/config/constants' +import { env } from '@config/environment' import { logger } from '@opencrvs/commons' const db = mongoose.connection @@ -31,7 +31,7 @@ const wait = (time: number) => const connect = async (): Promise => { try { - await mongoose.connect(MONGO_URL) + await mongoose.connect(env.MONGO_URL) } catch (err) { logger.error(err) await wait(1000) diff --git a/packages/config/src/config/plugins.ts b/packages/config/src/config/plugins.ts index 1112d36fd0..eda61ca6ce 100644 --- a/packages/config/src/config/plugins.ts +++ b/packages/config/src/config/plugins.ts @@ -9,7 +9,7 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ import { logger } from '@opencrvs/commons' -import { SENTRY_DSN } from '@config/config/constants' +import { env } from '@config/environment' import { ServerRegisterPluginObject } from '@hapi/hapi' import * as JWT from 'hapi-auth-jwt2' import * as Pino from 'hapi-pino' @@ -31,13 +31,13 @@ export default function getPlugins() { }) } - if (SENTRY_DSN) { + if (env.SENTRY_DSN) { plugins.push({ plugin: Sentry, options: { client: { - environment: process.env.DOMAIN, - dsn: SENTRY_DSN + environment: env.DOMAIN, + dsn: env.SENTRY_DSN }, catchLogErrors: true } diff --git a/packages/config/src/environment.ts b/packages/config/src/environment.ts new file mode 100644 index 0000000000..f03aa488c5 --- /dev/null +++ b/packages/config/src/environment.ts @@ -0,0 +1,31 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * OpenCRVS is also distributed under the terms of the Civil Registration + * & Healthcare Disclaimer located at http://opencrvs.org/license. + * + * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. + */ +import { cleanEnv, str, port, url, bool } from 'envalid' + +export const env = cleanEnv(process.env, { + HOST: str({ devDefault: 'localhost' }), + DOMAIN: str({ devDefault: '*' }), + LOGIN_URL: url({ devDefault: 'http://localhost:3020/' }), + CLIENT_APP_URL: url({ devDefault: 'http://localhost:3000/' }), + PORT: port({ default: 2021 }), + QA_ENV: bool({ default: false }), + CHECK_INVALID_TOKEN: bool({ + devDefault: false, + desc: `Check if the token has been invalided in the auth service before it has expired` + }), + CERT_PUBLIC_KEY_PATH: str({ devDefault: '../../.secrets/public-key.pem' }), + SENTRY_DSN: str({ default: undefined }), + AUTH_URL: url({ devDefault: 'http://localhost:4040/' }), + COUNTRY_CONFIG_URL: url({ devDefault: 'http://localhost:3040/' }), + MONGO_URL: url({ devDefault: 'mongodb://localhost/application-config' }), + USER_MANAGEMENT_URL: url({ devDefault: 'http://localhost:3030/' }), + FHIR_URL: url({ devDefault: 'http://localhost:3447/fhir' }) +}) diff --git a/packages/config/src/handlers/application/applicationConfigHandler.ts b/packages/config/src/handlers/application/applicationConfigHandler.ts index 69c99900b8..15a461d1b1 100644 --- a/packages/config/src/handlers/application/applicationConfigHandler.ts +++ b/packages/config/src/handlers/application/applicationConfigHandler.ts @@ -14,7 +14,7 @@ import { badData } from '@hapi/boom' import * as Joi from 'joi' import { pick } from 'lodash' import getSystems from '@config/handlers/system/systemHandler' -import { COUNTRY_CONFIG_URL } from '@config/config/constants' +import { env } from '@config/environment' import fetch from 'node-fetch' import { getToken } from '@config/utils/auth' import { pipe } from 'fp-ts/lib/function' @@ -77,7 +77,7 @@ async function getCertificates(request: Hapi.Request, h: Hapi.ResponseToolkit) { return [] } async function getConfigFromCountry(authToken?: string) { - const url = new URL('application-config', COUNTRY_CONFIG_URL).toString() + const url = new URL('application-config', env.COUNTRY_CONFIG_URL).toString() const res = await fetch(url) if (!res.ok) { @@ -92,7 +92,7 @@ async function getEventCertificate( ) { const url = new URL( `/certificates/${event}.svg`, - COUNTRY_CONFIG_URL + env.COUNTRY_CONFIG_URL ).toString() const res = await fetch(url, { diff --git a/packages/config/src/handlers/dashboardQueries/dashboardQueries.ts b/packages/config/src/handlers/dashboardQueries/dashboardQueries.ts index 1a10c880f4..168e8e6f6f 100644 --- a/packages/config/src/handlers/dashboardQueries/dashboardQueries.ts +++ b/packages/config/src/handlers/dashboardQueries/dashboardQueries.ts @@ -9,7 +9,7 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ import * as Hapi from '@hapi/hapi' -import { COUNTRY_CONFIG_URL } from '@config/config/constants' +import { env } from '@config/environment' import { defaultQueries } from './defaultQueries' import fetch from 'node-fetch' @@ -17,7 +17,9 @@ export default async function getDashboardQueries( request: Hapi.Request, h: Hapi.ResponseToolkit ) { - const response = await fetch(`${COUNTRY_CONFIG_URL}/dashboards/queries.json`) + const response = await fetch( + `${env.COUNTRY_CONFIG_URL}/dashboards/queries.json` + ) if (response.status === 404) { return defaultQueries() diff --git a/packages/config/src/handlers/dashboardQueries/defaultQueries.ts b/packages/config/src/handlers/dashboardQueries/defaultQueries.ts index 0ed313f08c..d59b01c885 100644 --- a/packages/config/src/handlers/dashboardQueries/defaultQueries.ts +++ b/packages/config/src/handlers/dashboardQueries/defaultQueries.ts @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { PRODUCTION, QA_ENV } from '@config/config/constants' +import { env } from '@config/environment' import { subMinutes } from 'date-fns' const registrations = ({ lastUpdatedAt }: { lastUpdatedAt: string }) => ({ @@ -772,7 +772,7 @@ const populationEstimatesPerDay = () => ({ ] }) -const REFRESH_AFTER_IN_MINUTE = PRODUCTION && !QA_ENV ? 1440 : 5 +const REFRESH_AFTER_IN_MINUTE = env.isProd && !env.QA_ENV ? 1440 : 5 export function defaultQueries() { const lastUpdatedAt = subMinutes( diff --git a/packages/config/src/handlers/forms/formsHandler.ts b/packages/config/src/handlers/forms/formsHandler.ts index b5284cf45d..e086fa7ca2 100644 --- a/packages/config/src/handlers/forms/formsHandler.ts +++ b/packages/config/src/handlers/forms/formsHandler.ts @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { COUNTRY_CONFIG_URL } from '@config/config/constants' +import { env } from '@config/environment' import FormVersions, { IFormVersionModel, Status @@ -32,7 +32,7 @@ export default async function getForm( h: Hapi.ResponseToolkit ) { const token = request.headers.authorization - const response = await fetch(`${COUNTRY_CONFIG_URL}/forms`, { + const response = await fetch(`${env.COUNTRY_CONFIG_URL}/forms`, { headers: { Authorization: token } @@ -40,7 +40,7 @@ export default async function getForm( if (response.status !== 200) { logger.error( - `Core failed to fetch form definition from ${COUNTRY_CONFIG_URL}/forms. Check country config logs for more details` + `Core failed to fetch form definition from ${env.COUNTRY_CONFIG_URL}/forms. Check country config logs for more details` ) return h.response().code(500) diff --git a/packages/config/src/server.ts b/packages/config/src/server.ts index 0c53f3969c..f83d33144f 100644 --- a/packages/config/src/server.ts +++ b/packages/config/src/server.ts @@ -10,35 +10,26 @@ */ import * as Hapi from '@hapi/hapi' -import { - PORT, - HOST, - CHECK_INVALID_TOKEN, - CERT_PUBLIC_KEY_PATH, - AUTH_URL, - DEFAULT_TIMEOUT, - HOSTNAME, - LOGIN_URL, - CLIENT_APP_URL -} from '@config/config/constants' +import { DEFAULT_TIMEOUT } from '@config/config/constants' import getRoutes from '@config/config/routes' import getPlugins from '@config/config/plugins' import * as database from '@config/config/database' import { validateFunc, logger } from '@opencrvs/commons' import { readFileSync } from 'fs' import { badRequest } from '@hapi/boom' +import { env } from './environment' -export const publicCert = readFileSync(CERT_PUBLIC_KEY_PATH) +export const publicCert = readFileSync(env.CERT_PUBLIC_KEY_PATH) export async function createServer() { - let whitelist: string[] = [HOSTNAME] - if (HOSTNAME[0] !== '*') { - whitelist = [LOGIN_URL, CLIENT_APP_URL] + let whitelist: string[] = [env.DOMAIN] + if (env.DOMAIN[0] !== '*') { + whitelist = [env.LOGIN_URL, env.CLIENT_APP_URL] } logger.info(`Whitelist: ${JSON.stringify(whitelist)}`) const server = new Hapi.Server({ - host: HOST, - port: PORT, + host: env.HOST, + port: env.PORT, routes: { cors: { origin: whitelist }, validate: { @@ -68,7 +59,7 @@ export async function createServer() { audience: 'opencrvs:config-user' }, validate: (payload: any, request: Hapi.Request) => - validateFunc(payload, request, CHECK_INVALID_TOKEN, AUTH_URL) + validateFunc(payload, request, env.CHECK_INVALID_TOKEN, env.AUTH_URL) }) server.auth.default('jwt') @@ -93,7 +84,7 @@ export async function createServer() { async function start() { await server.start() await database.start() - server.log('info', `Config server started on ${HOST}:${PORT}`) + server.log('info', `Config server started on ${env.HOST}:${env.PORT}`) } return { server, start, stop } diff --git a/packages/config/src/services/documents.ts b/packages/config/src/services/documents.ts deleted file mode 100644 index 7158c86c94..0000000000 --- a/packages/config/src/services/documents.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * OpenCRVS is also distributed under the terms of the Civil Registration - * & Healthcare Disclaimer located at http://opencrvs.org/license. - * - * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. - */ -import fetch from 'node-fetch' -import { DOCUMENTS_URL } from '@config/config/constants' -import { internal } from '@hapi/boom' -import { logger } from '@opencrvs/commons' - -interface IAuthHeader { - Authorization: string -} - -export async function getDocumentUrl(fileUri: string, authHeader: IAuthHeader) { - const url = new URL('/presigned-url', DOCUMENTS_URL).toString() - const res = await fetch(url, { - method: 'POST', - headers: { - ...authHeader, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ fileUri }) - }) - if (!res.ok) { - logger.error(await res.json()) - throw internal() - } - return (await res.json()).presignedURL -} diff --git a/packages/config/src/services/hearth.ts b/packages/config/src/services/hearth.ts index ab639d62a7..eb96f7e98a 100644 --- a/packages/config/src/services/hearth.ts +++ b/packages/config/src/services/hearth.ts @@ -9,11 +9,14 @@ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ import { Location, SavedBundle } from '@opencrvs/commons/types' -import { FHIR_URL } from '@config/config/constants' +import { env } from '@config/environment' import { joinURL } from '@opencrvs/commons' export const fetchLocations = async () => { - const allLocationsUrl = joinURL(FHIR_URL, `Location?_count=0&status=active`) + const allLocationsUrl = joinURL( + env.FHIR_URL, + `Location?_count=0&status=active` + ) const response = await fetch(allLocationsUrl) if (!response.ok) { @@ -29,7 +32,7 @@ export const fetchFromHearth = async ( method = 'GET', body: string | undefined = undefined ): Promise => { - const response = await fetch(joinURL(FHIR_URL, suffix), { + const response = await fetch(joinURL(env.FHIR_URL, suffix), { method, headers: { 'Content-Type': 'application/fhir+json' @@ -50,7 +53,7 @@ export const sendToFhir = async ( method: string, token: string ) => { - return fetch(`${FHIR_URL}${suffix}`, { + return fetch(`${env.FHIR_URL}${suffix}`, { method, body, headers: { diff --git a/packages/config/src/services/userManagement.ts b/packages/config/src/services/userManagement.ts index 90344d1bca..bfc7ac9f86 100644 --- a/packages/config/src/services/userManagement.ts +++ b/packages/config/src/services/userManagement.ts @@ -8,7 +8,7 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -import { USER_MANAGEMENT_URL } from '@config/config/constants' +import { env } from '@config/environment' import fetch from 'node-fetch' interface AuthHeader { @@ -20,7 +20,7 @@ export const fetchUserManagement = async ( authHeader: AuthHeader, method = 'GET' ): Promise => { - const systemURL = new URL(suffix, USER_MANAGEMENT_URL).toString() + const systemURL = new URL(suffix, env.USER_MANAGEMENT_URL).toString() const response = await fetch(systemURL, { method, headers: { diff --git a/packages/gateway/package.json b/packages/gateway/package.json index 081030abfe..1d0d1b3925 100644 --- a/packages/gateway/package.json +++ b/packages/gateway/package.json @@ -40,6 +40,7 @@ "country-code-lookup": "^0.1.0", "csv-stringify": "^5.3.4", "dotenv": "^6.1.0", + "envalid": "^8.0.0", "file-type": "^16.5.3", "flat": "^5.0.0", "fp-ts": "^2.12.3", @@ -81,8 +82,8 @@ "@types/jsonwebtoken": "^9.0.0", "@types/jwt-decode": "^2.2.1", "@types/lodash": "^4.14.108", - "@types/node-fetch": "^2.5.12", "@types/node": "18.11.18", + "@types/node-fetch": "^2.5.12", "@types/redis": "^2.8.6", "@types/uuid": "^3.4.3", "@typescript-eslint/eslint-plugin": "^4.5.0", diff --git a/packages/gateway/src/constants.ts b/packages/gateway/src/constants.ts index ffda6697ff..740cc44ad6 100644 --- a/packages/gateway/src/constants.ts +++ b/packages/gateway/src/constants.ts @@ -8,79 +8,50 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -export const REDIS_HOST = process.env.REDIS_HOST || 'localhost' -export const HOST = process.env.HOST || '0.0.0.0' -export const PORT = process.env.PORT || 7070 -export const HOSTNAME = process.env.DOMAIN || '*' -export const LOGIN_URL = process.env.LOGIN_URL || 'http://localhost:3020/' -export const CLIENT_APP_URL = - process.env.CLIENT_APP_URL || 'http://localhost:3000/' -export const FHIR_URL = process.env.FHIR_URL || 'http://localhost:3447/fhir' -export const CERT_PUBLIC_KEY_PATH = - (process.env.CERT_PUBLIC_KEY_PATH as string) || - '../../.secrets/public-key.pem' -// Services -export const SEARCH_URL = process.env.SEARCH_URL || 'http://localhost:9090/' -export const METRICS_URL = process.env.METRICS_URL || 'http://localhost:1050' -export const AUTH_URL = process.env.AUTH_URL || 'http://localhost:4040' -export const USER_MANAGEMENT_URL = - process.env.USER_MANAGEMENT_URL || 'http://localhost:3030/' -export const WEBHOOKS_URL = process.env.WEBHOOKS_URL || 'http://localhost:2525/' -export const APPLICATION_CONFIG_URL = - process.env.APPLICATION_CONFIG_URL || 'http://localhost:2021/' -export const NOTIFICATION_URL = - process.env.NOTIFICATION_URL || 'http://localhost:2020/' -export const WORKFLOW_URL = process.env.WORKFLOW_URL || 'http://localhost:5050/' -export const COUNTRY_CONFIG_URL = - process.env.COUNTRY_CONFIG_URL || 'http://localhost:3040' -export const DOCUMENTS_URL = - process.env.DOCUMENTS_URL || 'http://localhost:9050' -/** Disables the Redis-based rate limiting globally */ -export const DISABLE_RATE_LIMIT = Boolean(process.env.DISABLE_RATE_LIMIT) -export const SENTRY_DSN = process.env.SENTRY_DSN - -export const PRODUCTION = process.env.NODE_ENV === 'production' -export const QA_ENV = process.env.QA_ENV || false +import { env } from '@gateway/environment' export const AVATAR_API = 'https://eu.ui-avatars.com/api/?background=DEE5F2&color=222&name=' -// Check if the token has been invalided in the auth service before it has expired -// This needs to be a string to make it easy to pass as an ENV var. -export const CHECK_INVALID_TOKEN = process.env.CHECK_INVALID_TOKEN || 'false' -export function getLanguages() { - const LANGUAGES = process.env.LANGUAGES || 'bn,en' - return LANGUAGES.split(',') -} -export const DEFAULT_COUNTRY = process.env.COUNTRY || 'FAR' export const NATIVE_LANGUAGE = (() => { - const languages = getLanguages() + const languages = env.LANGUAGES.split(',') return languages.find((language) => language !== 'en') })() -export const CONFIG_TOKEN_EXPIRY_SECONDS = process.env - .CONFIG_TOKEN_EXPIRY_SECONDS - ? parseInt(process.env.CONFIG_TOKEN_EXPIRY_SECONDS, 10) - : 604800 // 1 week - -export const CONFIG_SMS_CODE_EXPIRY_SECONDS = process.env - .CONFIG_SMS_CODE_EXPIRY_SECONDS - ? parseInt(process.env.CONFIG_SMS_CODE_EXPIRY_SECONDS, 10) - : 600 - -export const CONFIG_SYSTEM_TOKEN_EXPIRY_SECONDS = process.env - .CONFIG_SYSTEM_TOKEN_EXPIRY_SECONDS - ? parseInt(process.env.CONFIG_SYSTEM_TOKEN_EXPIRY_SECONDS, 10) - : 600 export const DEFAULT_TIMEOUT = 600000 -export const MINIO_BUCKET = process.env.MINIO_BUCKET || 'ocrvs' -export const OIDP_BASE_URL = process.env.NATIONAL_ID_OIDP_BASE_URL -export const OIDP_TOKEN_URL = process.env.NATIONAL_ID_OIDP_TOKEN_URL -export const OIDP_USERINFO_URL = process.env.NATIONAL_ID_OIDP_USERINFO_URL -/** Base64 encoded RS256 JSON Web Key */ -export const OIDP_CLIENT_PRIVATE_KEY = - process.env.NATIONAL_ID_OIDP_CLIENT_PRIVATE_KEY -/** Value for "aud" claim when getting access token for fetching Open ID provider user info */ -export const OIDP_JWT_AUD_CLAIM = process.env.NATIONAL_ID_OIDP_JWT_AUD_CLAIM +export const REDIS_HOST = env.REDIS_HOST +export const HOST = env.HOST +export const PORT = env.PORT +export const HOSTNAME = env.DOMAIN +export const LOGIN_URL = env.LOGIN_URL +export const CLIENT_APP_URL = env.CLIENT_APP_URL +export const FHIR_URL = env.FHIR_URL +export const CERT_PUBLIC_KEY_PATH = env.CERT_PUBLIC_KEY_PATH +export const SEARCH_URL = env.SEARCH_URL +export const METRICS_URL = env.METRICS_URL +export const AUTH_URL = env.AUTH_URL +export const USER_MANAGEMENT_URL = env.USER_MANAGEMENT_URL +export const WEBHOOKS_URL = env.WEBHOOKS_URL +export const APPLICATION_CONFIG_URL = env.APPLICATION_CONFIG_URL +export const NOTIFICATION_URL = env.NOTIFICATION_URL +export const WORKFLOW_URL = env.WORKFLOW_URL +export const COUNTRY_CONFIG_URL = env.COUNTRY_CONFIG_URL +export const DOCUMENTS_URL = env.DOCUMENTS_URL +export const DISABLE_RATE_LIMIT = env.DISABLE_RATE_LIMIT +export const SENTRY_DSN = env.SENTRY_DSN +export const PRODUCTION = env.isProd +export const QA_ENV = env.QA_ENV +export const CHECK_INVALID_TOKEN = env.CHECK_INVALID_TOKEN +export const DEFAULT_COUNTRY = env.COUNTRY +export const CONFIG_TOKEN_EXPIRY_SECONDS = env.CONFIG_TOKEN_EXPIRY_SECONDS +export const CONFIG_SMS_CODE_EXPIRY_SECONDS = env.CONFIG_SMS_CODE_EXPIRY_SECONDS +export const CONFIG_SYSTEM_TOKEN_EXPIRY_SECONDS = + env.CONFIG_SYSTEM_TOKEN_EXPIRY_SECONDS +export const MINIO_BUCKET = env.MINIO_BUCKET +export const OIDP_BASE_URL = env.NATIONAL_ID_OIDP_BASE_URL +export const OIDP_TOKEN_URL = env.NATIONAL_ID_OIDP_TOKEN_URL +export const OIDP_USERINFO_URL = env.NATIONAL_ID_OIDP_USERINFO_URL +export const OIDP_CLIENT_PRIVATE_KEY = env.NATIONAL_ID_OIDP_CLIENT_PRIVATE_KEY +export const OIDP_JWT_AUD_CLAIM = env.NATIONAL_ID_OIDP_JWT_AUD_CLAIM diff --git a/packages/gateway/src/environment.ts b/packages/gateway/src/environment.ts new file mode 100644 index 0000000000..04f8d7cc5a --- /dev/null +++ b/packages/gateway/src/environment.ts @@ -0,0 +1,62 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * OpenCRVS is also distributed under the terms of the Civil Registration + * & Healthcare Disclaimer located at http://opencrvs.org/license. + * + * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. + */ +import { cleanEnv, str, port, url, bool, num } from 'envalid' + +export const env = cleanEnv(process.env, { + REDIS_HOST: str({ devDefault: 'localhost' }), + HOST: str({ devDefault: '0.0.0.0' }), + PORT: port({ default: 7070 }), + DOMAIN: str({ devDefault: '*' }), + LOGIN_URL: url({ devDefault: 'http://localhost:3020/' }), + CLIENT_APP_URL: url({ devDefault: 'http://localhost:3000/' }), + FHIR_URL: url({ devDefault: 'http://localhost:3447/fhir' }), + CERT_PUBLIC_KEY_PATH: str({ + devDefault: '../../.secrets/public-key.pem' + }), + SEARCH_URL: url({ devDefault: 'http://localhost:9090/' }), + METRICS_URL: url({ devDefault: 'http://localhost:1050' }), + AUTH_URL: url({ devDefault: 'http://localhost:4040' }), + USER_MANAGEMENT_URL: url({ devDefault: 'http://localhost:3030/' }), + WEBHOOKS_URL: url({ devDefault: 'http://localhost:2525/' }), + APPLICATION_CONFIG_URL: url({ devDefault: 'http://localhost:2021/' }), + NOTIFICATION_URL: url({ devDefault: 'http://localhost:2020/' }), + WORKFLOW_URL: url({ devDefault: 'http://localhost:5050/' }), + COUNTRY_CONFIG_URL: url({ devDefault: 'http://localhost:3040' }), + DOCUMENTS_URL: url({ devDefault: 'http://localhost:9050' }), + DISABLE_RATE_LIMIT: bool({ + default: false, + desc: 'Disables the Redis-based rate limiting globally' + }), + SENTRY_DSN: str({ default: undefined }), + QA_ENV: bool({ default: false }), + CHECK_INVALID_TOKEN: bool({ + devDefault: false, + desc: 'Check if the token has been invalidated in the auth service before it has expired' + }), + LANGUAGES: str({ devDefault: 'bn,en' }), + COUNTRY: str({ devDefault: 'FAR' }), + CONFIG_TOKEN_EXPIRY_SECONDS: num({ default: 604800 }), // 1 week + CONFIG_SMS_CODE_EXPIRY_SECONDS: num({ default: 600 }), // 10 minutes + CONFIG_SYSTEM_TOKEN_EXPIRY_SECONDS: num({ default: 600 }), // 10 minutes + MINIO_BUCKET: str({ devDefault: 'ocrvs' }), + + NATIONAL_ID_OIDP_BASE_URL: str({ default: undefined }), + NATIONAL_ID_OIDP_TOKEN_URL: str({ default: undefined }), + NATIONAL_ID_OIDP_USERINFO_URL: str({ default: undefined }), + NATIONAL_ID_OIDP_CLIENT_PRIVATE_KEY: str({ + default: undefined, + desc: 'Base64 encoded RS256 JSON Web Key' + }), + NATIONAL_ID_OIDP_JWT_AUD_CLAIM: str({ + default: undefined, + desc: 'Value for "aud" claim when getting access token for fetching Open ID provider user info' + }) +}) diff --git a/packages/webhooks/package.json b/packages/webhooks/package.json index f779cea523..f9747ee563 100644 --- a/packages/webhooks/package.json +++ b/packages/webhooks/package.json @@ -22,6 +22,7 @@ "@opencrvs/commons": "^1.5.0", "app-module-path": "^2.2.0", "bullmq": "^1.9.0", + "envalid": "^8.0.0", "hapi-auth-jwt2": "10.6.0", "hapi-pino": "^9.0.0", "hapi-sentry": "^3.1.0", diff --git a/packages/webhooks/src/constants.ts b/packages/webhooks/src/constants.ts index e766117025..81ad51c12e 100644 --- a/packages/webhooks/src/constants.ts +++ b/packages/webhooks/src/constants.ts @@ -8,27 +8,25 @@ * * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. */ -export const MONGO_URL = process.env.MONGO_URL || 'mongodb://localhost/webhooks' -export const HOST = process.env.HOST || '0.0.0.0' -export const PORT = process.env.PORT || 2525 -export const USER_MANAGEMENT_URL = - process.env.USER_MANAGEMENT_URL || 'http://localhost:3030/' -export const CERT_PRIVATE_KEY_PATH = - (process.env.CERT_PRIVATE_KEY_PATH as string) || - '../../.secrets/private-key.pem' -export const CERT_PUBLIC_KEY_PATH = - (process.env.CERT_PUBLIC_KEY_PATH as string) || - '../../.secrets/public-key.pem' -export const SENTRY_DSN = process.env.SENTRY_DSN +import { env } from '@webhooks/environment' -export const PRODUCTION = process.env.NODE_ENV === 'production' -export const QA_ENV = process.env.QA_ENV || false -export const AUTH_URL = process.env.AUTH_URL || 'http://localhost:4040' -export const FHIR_URL = process.env.FHIR_URL || 'http://localhost:3447/fhir' -// Check if the token has been invalided in the auth service before it has expired -// This needs to be a string to make it easy to pass as an ENV var. -export const CHECK_INVALID_TOKEN = process.env.CHECK_INVALID_TOKEN || 'false' -export const REDIS_HOST = process.env.REDIS_HOST || 'localhost' export const QUEUE_NAME = 'NOTIFY_URL' export const OPENCRVS_SPECIFICATION_URL = 'http://opencrvs.org/specs/' export const DEFAULT_TIMEOUT = 600000 + +export const MONGO_URL = env.MONGO_URL +export const HOST = env.HOST +export const PORT = env.PORT +export const USER_MANAGEMENT_URL = env.USER_MANAGEMENT_URL +export const CERT_PRIVATE_KEY_PATH = env.CERT_PRIVATE_KEY_PATH +export const CERT_PUBLIC_KEY_PATH = env.CERT_PUBLIC_KEY_PATH + +export const SENTRY_DSN = env.SENTRY_DSN +export const PRODUCTION = env.isProd +export const QA_ENV = env.QA_ENV + +export const AUTH_URL = env.AUTH_URL +export const FHIR_URL = env.FHIR_URL + +export const CHECK_INVALID_TOKEN = env.CHECK_INVALID_TOKEN +export const REDIS_HOST = env.REDIS_HOST diff --git a/packages/webhooks/src/environment.ts b/packages/webhooks/src/environment.ts new file mode 100644 index 0000000000..0abccef569 --- /dev/null +++ b/packages/webhooks/src/environment.ts @@ -0,0 +1,30 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * OpenCRVS is also distributed under the terms of the Civil Registration + * & Healthcare Disclaimer located at http://opencrvs.org/license. + * + * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS. + */ +import { bool, cleanEnv, port, str, url } from 'envalid' + +export const env = cleanEnv(process.env, { + MONGO_URL: str({ devDefault: 'mongodb://localhost/webhooks' }), + HOST: str({ devDefault: '0.0.0.0' }), + PORT: port({ default: 2525 }), + USER_MANAGEMENT_URL: url({ devDefault: 'http://localhost:3030/' }), + CERT_PRIVATE_KEY_PATH: str({ devDefault: '../../.secrets/private-key.pem' }), + CERT_PUBLIC_KEY_PATH: str({ devDefault: '../../.secrets/public-key.pem' }), + SENTRY_DSN: str({ default: undefined }), + NODE_ENV: str({ devDefault: 'development' }), + QA_ENV: bool({ devDefault: false }), + AUTH_URL: url({ devDefault: 'http://localhost:4040' }), + FHIR_URL: url({ devDefault: 'http://localhost:3447/fhir' }), + CHECK_INVALID_TOKEN: bool({ + devDefault: false, + desc: 'Check if the token has been invalidated in the auth service before it has expired' + }), + REDIS_HOST: str({ devDefault: 'localhost' }) +})