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

Ocrvs 5793 Cameroon improvements #6054

Merged
merged 13 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/auth/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function getPlugins() {
plugin: Sentry,
options: {
client: {
environment: process.env.HOSTNAME,
environment: process.env.DOMAIN,
dsn: SENTRY_DSN
},
catchLogErrors: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const ErrorMessage = styled.div`
type IFullProps = {
name: string
label: string
placeholder?: string
extraValue: IFormFieldValue
options: ISelectOption[]
splitView?: boolean
Expand Down Expand Up @@ -280,12 +281,13 @@ class DocumentUploaderWithOptionComp extends React.Component<
}

renderDocumentUploaderWithDocumentTypeBlock = () => {
const { name, intl } = this.props
const { name, intl, placeholder } = this.props
return this.props.splitView ? (
this.state.dropDownOptions.map((opt, idx) => (
<Flex splitView key={idx}>
<Select
id={`${name}${idx}`}
placeholder={placeholder}
options={[opt]}
value={opt.value}
onChange={this.onChange}
Expand All @@ -307,6 +309,7 @@ class DocumentUploaderWithOptionComp extends React.Component<
<Flex>
<Select
id={name}
placeholder={placeholder}
options={this.state.dropDownOptions}
value={this.state.fields.documentType}
onChange={this.onChange}
Expand Down
25 changes: 19 additions & 6 deletions packages/client/src/utils/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
*/
import { MessageDescriptor } from 'react-intl'
import { validationMessages as messages } from '@client/i18n/messages'
import {
IFormFieldValue,
IFormData,
IFormField
} from '@opencrvs/client/src/forms'
import { IFormFieldValue, IFormData } from '@opencrvs/client/src/forms'
import {
REGEXP_BLOCK_ALPHA_NUMERIC_DOT,
REGEXP_DECIMAL_POINT_NUMBER,
Expand Down Expand Up @@ -224,6 +220,10 @@ export const isDateNotInFuture = (date: string) => {
return new Date(date) <= new Date(Date.now())
}

export const isDateNotPastLimit = (date: string, limit: Date) => {
return new Date(date) >= limit
}

export const isDateNotBeforeBirth = (date: string, drafts: IFormData) => {
const birthDate = drafts.deceased && drafts.deceased.birthDate
return birthDate
Expand Down Expand Up @@ -285,11 +285,13 @@ export const isValidBirthDate: Validation = (

export const isValidChildBirthDate: Validation = (value: IFormFieldValue) => {
const childBirthDate = value as string
const pastDateLimit = new Date(1900, 0, 1)
return !childBirthDate
? { message: messages.required }
: childBirthDate &&
isAValidDateFormat(childBirthDate) &&
isDateNotInFuture(childBirthDate)
isDateNotInFuture(childBirthDate) &&
isDateNotPastLimit(childBirthDate, pastDateLimit)
? undefined
: { message: messages.isValidBirthDate }
}
Expand Down Expand Up @@ -480,6 +482,17 @@ export const dateNotInFuture = (): Validation => (value: IFormFieldValue) => {
}
}

export const dateNotPastLimit =
(limit: string): Validation =>
(value: IFormFieldValue) => {
const cast = value as string
if (isDateNotPastLimit(cast, new Date(limit))) {
return undefined
} else {
return { message: messages.dateFormat }
}
}

export const dateNotToday = (date: string): boolean => {
const today = new Date().setHours(0, 0, 0, 0)
const day = new Date(date).setHours(0, 0, 0, 0)
Expand Down
3 changes: 2 additions & 1 deletion packages/client/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ export default defineConfig(({ mode }) => {
},
commonjsOptions: {
transformMixedEsModules: true
}
},
sourcemap: true
},
resolve: {
alias: {
Expand Down
2 changes: 1 addition & 1 deletion packages/config/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function getPlugins() {
plugin: Sentry,
options: {
client: {
environment: process.env.HOSTNAME,
environment: process.env.DOMAIN,
dsn: SENTRY_DSN
},
catchLogErrors: true
Expand Down
2 changes: 1 addition & 1 deletion packages/documents/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function getPlugins() {
plugin: Sentry,
options: {
client: {
environment: process.env.HOSTNAME,
environment: process.env.DOMAIN,
dsn: SENTRY_DSN
},
catchLogErrors: true
Expand Down
2 changes: 1 addition & 1 deletion packages/gateway/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const getPlugins = () => {
const plugins: any[] = []

if (SENTRY_DSN) {
Sentry.init({ dsn: SENTRY_DSN, environment: process.env.HOSTNAME })
Sentry.init({ dsn: SENTRY_DSN, environment: process.env.DOMAIN })
}

const swaggerOptions: HapiSwagger.RegisterOptions = {
Expand Down
13 changes: 2 additions & 11 deletions packages/gateway/src/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
*/
import * as glob from 'glob'
import { join, resolve } from 'path'
import healthCheckHandler, {
querySchema as healthCheckQuerySchema,
responseSchema as healthCheckResponseSchema
} from '@gateway/features/healthCheck/handler'
import healthCheckHandler from '@gateway/features/healthCheck/handler'
import {
createLocationHandler,
requestSchema,
Expand Down Expand Up @@ -46,13 +43,7 @@ export const getRoutes = () => {
config: {
auth: false,
description: 'Checks the health of all services.',
notes: 'Pass the service as a query param: service',
validate: {
query: healthCheckQuerySchema
},
response: {
schema: healthCheckResponseSchema
}
notes: 'Pass the service as a query param: service'
}
},
// get all locations
Expand Down
64 changes: 18 additions & 46 deletions packages/gateway/src/features/healthCheck/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*/
import * as Hapi from '@hapi/hapi'
import * as Joi from 'joi'
import { badRequest, internal } from '@hapi/boom'
import {
AUTH_URL,
SEARCH_URL,
Expand Down Expand Up @@ -47,55 +46,31 @@ enum Services {
GATEWAY = 'gateway'
}

const SERVICES = {
[Services.AUTH]: `${AUTH_URL}/ping`,
[Services.SEARCH]: `${SEARCH_URL}ping`,
[Services.USER_MGNT]: `${USER_MANAGEMENT_URL}ping`,
[Services.METRICS]: `${METRICS_URL}/ping`,
[Services.NOTIFICATION]: `${NOTIFICATION_URL}ping`,
[Services.COUNTRY_CONFIG]: `${COUNTRY_CONFIG_URL}/ping`,
[Services.WORKFLOW]: `${WORKFLOW_URL}ping`
}

export default async function healthCheckHandler(
request: Hapi.Request,
h: Hapi.ResponseToolkit
) {
let service
if (request.query['service'] && request.query['service'][0]) {
service = request.query['service'][0]
} else {
throw badRequest('Received no service to check')
}

let response
const responses = {}

switch (service) {
case Services.GATEWAY:
response = true
break
case Services.AUTH:
response = await checkServiceHealth(`${AUTH_URL}/ping`)
break
case Services.SEARCH:
response = await checkServiceHealth(`${SEARCH_URL}ping`)
break
case Services.USER_MGNT:
response = await checkServiceHealth(`${USER_MANAGEMENT_URL}ping`)
break
case Services.METRICS:
response = await checkServiceHealth(`${METRICS_URL}/ping`)
break
case Services.NOTIFICATION:
response = await checkServiceHealth(`${NOTIFICATION_URL}ping`)
break
case Services.COUNTRY_CONFIG:
response = await checkServiceHealth(`${COUNTRY_CONFIG_URL}/ping`)
break
case Services.WORKFLOW:
response = await checkServiceHealth(`${WORKFLOW_URL}ping`)
break
default:
response = false
}

if (!response) {
throw internal('Service health check failed for: ', service)
} else {
return {
success: response
for (const [key, value] of Object.entries(SERVICES)) {
try {
const res = await checkServiceHealth(value)
responses[key] = res
} catch (err) {
responses[key] = false
}
}
return responses
}

export const querySchema = Joi.object({
Expand All @@ -114,6 +89,3 @@ export const querySchema = Joi.object({
)
.single()
})
export const responseSchema = Joi.object({
success: Joi.boolean()
})
63 changes: 9 additions & 54 deletions packages/gateway/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,64 +144,19 @@ describe('Route authorization', () => {

expect(res.statusCode).toBe(401)
})
it('Tests the health check with a valid parameter', async () => {
fetch.mockResponse(
JSON.stringify({
success: true
})
)
const res = await server.app.inject({
method: 'GET',
url: '/ping?service=search'
})
expect(res.result).toEqual({
success: true
})
})
it('Fails the health check with a missing parameter', async () => {
fetch.mockResponse(
JSON.stringify({
success: true
})
)
it('Tests the health check for all the service', async () => {
const res = await server.app.inject({
method: 'GET',
url: '/ping'
})
expect(res.statusCode).toBe(400)
})
it('Rejects the health check with an invalid parameter', async () => {
fetch.mockResponse(
JSON.stringify({
success: true
})
)
const res = await server.app.inject({
method: 'GET',
url: '/ping?service=nonsense'
})
expect(res.result.message).toEqual(
`"service" must be one of [auth, user-mgnt, metrics, notification, countryconfig, search, workflow, gateway]`
)
})
it('Fails the health check for a failed health check on a running service', async () => {
fetch.mockResponse(
JSON.stringify({
success: false
})
)
const res = await server.app.inject({
method: 'GET',
url: '/ping?service=auth'
})
expect(res.result.message).toEqual('An internal server error occurred')
})
it('Fails the health check for a failed and not running service', async () => {
fetch.mockReject(new Error('An internal server error occurred'))
const res = await server.app.inject({
method: 'GET',
url: '/ping?service=auth'
expect(res.result).toEqual({
auth: false,
search: false,
'user-mgnt': false,
metrics: false,
notification: false,
countryconfig: false,
workflow: false
})
expect(res.result.message).toEqual('An internal server error occurred')
})
})
8 changes: 4 additions & 4 deletions packages/login/src/utils/authUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,23 @@ export function maskEmail(email: string) {
const username = parts[0]
const domain = parts[1]

const maskedUsername = maskString(username)
const maskedUsername = maskString(username, 6)
const maskedDomain =
maskString(domain.split('.')[0]) + '.' + maskString(domain.split('.')[1])

return maskedUsername + '@' + maskedDomain
}

export function maskString(s: string) {
const maskPercentage = 0.6
export function maskString(s: string, limit = 5) {
const maskPercentage = s.length > 30 ? 0.7 : 0.6
const emailLength = s.length || 0
const unmaskedEmailLength =
emailLength - Math.ceil(maskPercentage * emailLength)
const startFrom = Math.ceil(unmaskedEmailLength / 2)
const endBefore = unmaskedEmailLength - startFrom
const maskedEmail = s.replace(
s.slice(startFrom, emailLength - endBefore),
'*'.repeat(emailLength - startFrom - endBefore)
'*'.repeat(Math.min(emailLength - startFrom - endBefore, limit))
)
return maskedEmail
}
1 change: 1 addition & 0 deletions packages/login/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export default defineConfig(({ mode }) => {
// This changes the out put dir from dist to build
build: {
outDir: 'build',
sourcemap: true,
commonjsOptions: {
transformMixedEsModules: true
}
Expand Down
2 changes: 1 addition & 1 deletion packages/metrics/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function getPlugins() {
plugin: Sentry,
options: {
client: {
environment: process.env.HOSTNAME,
environment: process.env.DOMAIN,
dsn: SENTRY_DSN
},
catchLogErrors: true
Expand Down
2 changes: 1 addition & 1 deletion packages/notification/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function getPlugins() {
plugin: Sentry,
options: {
client: {
environment: process.env.HOSTNAME,
environment: process.env.DOMAIN,
dsn: SENTRY_DSN
},
catchLogErrors: true
Expand Down
2 changes: 1 addition & 1 deletion packages/search/src/config/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function getPlugins() {
plugin: Sentry,
options: {
client: {
environment: process.env.HOSTNAME,
environment: process.env.DOMAIN,
dsn: SENTRY_DSN
},
catchLogErrors: true
Expand Down
Loading
Loading