Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(env-vars): config, webhooks and gateway env validation #7625

Merged
merged 14 commits into from
Oct 2, 2024
Merged
4 changes: 2 additions & 2 deletions packages/commons/src/token-verifier.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions packages/commons/src/token-verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions packages/config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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": {
Expand Down
30 changes: 0 additions & 30 deletions packages/config/src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions packages/config/src/config/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,7 +31,7 @@ const wait = (time: number) =>

const connect = async (): Promise<void> => {
try {
await mongoose.connect(MONGO_URL)
await mongoose.connect(env.MONGO_URL)
} catch (err) {
logger.error(err)
await wait(1000)
Expand Down
8 changes: 4 additions & 4 deletions packages/config/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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
}
Expand Down
31 changes: 31 additions & 0 deletions packages/config/src/environment.ts
Original file line number Diff line number Diff line change
@@ -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' })
})
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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) {
Expand All @@ -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, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@
* 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'

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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => ({
Expand Down Expand Up @@ -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(
Expand Down
6 changes: 3 additions & 3 deletions packages/config/src/handlers/forms/formsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -32,15 +32,15 @@ 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
}
})

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)
Expand Down
29 changes: 10 additions & 19 deletions packages/config/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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')
Expand All @@ -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 }
Expand Down
35 changes: 0 additions & 35 deletions packages/config/src/services/documents.ts

This file was deleted.

Loading
Loading