Skip to content

Commit

Permalink
ref: return Set from checkMyInfoHashes
Browse files Browse the repository at this point in the history
  • Loading branch information
mantariksh committed Nov 11, 2020
1 parent 4f74774 commit 1a6e9c6
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
15 changes: 12 additions & 3 deletions src/app/controllers/myinfo.server.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { StatusCodes } from 'http-status-codes'
import { ProcessedFieldResponse } from 'src/app/modules/submission/submission.types'

import { createLoggerWithLabel } from '../../config/logger'
import { AuthType, IHashes, IPopulatedForm, SpcpSession } from '../../types'
import {
AuthType,
IPopulatedForm,
MyInfoAttribute,
SpcpSession,
} from '../../types'
import { MyInfoFactory } from '../services/myinfo/myinfo.factory'
import {
extractRequestedAttributes,
Expand All @@ -20,14 +25,16 @@ const logger = createLoggerWithLabel(module)

type MyInfoReq<T> = T & {
form: IPopulatedForm
hashedFields?: IHashes
}
type ResWithSpcpSession<T> = T & {
locals: { spcpSession?: SpcpSession }
}
type ResWithUinFin<T> = T & {
uinFin?: string
}
type ResWithHashedFields<T> = T & {
locals: { hashedFields?: Set<MyInfoAttribute> }
}

export const addMyInfo: RequestHandler<ParamsDictionary> = async (
req,
Expand Down Expand Up @@ -104,7 +111,9 @@ export const verifyMyInfoVals: RequestHandler<
)
.map((hashedFields) => {
// eslint-disable-next-line @typescript-eslint/no-extra-semi
;(req as MyInfoReq<typeof req>).hashedFields = hashedFields
;(res as ResWithHashedFields<
typeof res
>).locals.hashedFields = hashedFields
return next()
})
.mapErr((error) => {
Expand Down
9 changes: 7 additions & 2 deletions src/app/services/myinfo/myinfo.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import FeatureManager, {
FeatureNames,
RegisteredFeature,
} from '../../../config/feature-manager'
import { IFieldSchema, IHashes, IMyInfoHashSchema } from '../../../types'
import {
IFieldSchema,
IHashes,
IMyInfoHashSchema,
MyInfoAttribute,
} from '../../../types'
import {
DatabaseError,
MissingFeatureError,
Expand Down Expand Up @@ -54,7 +59,7 @@ interface IMyInfoFactory {
responses: ProcessedFieldResponse[],
hashes: IHashes,
) => ResultAsync<
IHashes,
Set<MyInfoAttribute>,
HashingError | HashDidNotMatchError | MissingFeatureError
>
}
Expand Down
10 changes: 6 additions & 4 deletions src/app/services/myinfo/myinfo.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
IFieldSchema,
IHashes,
IMyInfoHashSchema,
MyInfoAttribute,
} from '../../../types'
import { DatabaseError } from '../../modules/core/core.errors'
import { ProcessedFieldResponse } from '../../modules/submission/submission.types'
Expand Down Expand Up @@ -250,7 +251,7 @@ export class MyInfoService {
checkMyInfoHashes(
responses: ProcessedFieldResponse[],
hashes: IHashes,
): ResultAsync<IHashes, HashingError | HashDidNotMatchError> {
): ResultAsync<Set<MyInfoAttribute>, HashingError | HashDidNotMatchError> {
const comparisonPromises = compareHashedValues(responses, hashes)
return ResultAsync.fromPromise(
Bluebird.props(comparisonPromises),
Expand All @@ -266,9 +267,10 @@ export class MyInfoService {
return new HashingError(message)
},
).andThen((comparisonResults) => {
const comparedAttrs = Array.from(comparisonResults.keys())
// All outcomes should be true
const failedAttrs = Object.keys(comparisonResults).filter(
(attr) => !comparisonResults[attr],
const failedAttrs = comparedAttrs.filter(
(attr) => !comparisonResults.get(attr),
)
if (failedAttrs.length > 0) {
const message = 'MyInfo Hash did not match'
Expand All @@ -281,7 +283,7 @@ export class MyInfoService {
})
return errAsync(new HashDidNotMatchError(message))
}
return okAsync(comparisonResults as IHashes)
return okAsync(new Set(comparedAttrs))
})
}
}
18 changes: 8 additions & 10 deletions src/app/services/myinfo/myinfo.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '@opengovsg/myinfo-gov-client'
import bcrypt from 'bcrypt'
import { StatusCodes } from 'http-status-codes'
import { get, keyBy, mapValues } from 'lodash'
import { get } from 'lodash'
import moment from 'moment'

import { createLoggerWithLabel } from '../../../config/logger'
Expand Down Expand Up @@ -182,19 +182,17 @@ const compareSingleHash = (
export const compareHashedValues = (
responses: ProcessedFieldResponse[],
hashes: IHashes,
): Record<string, Promise<boolean>> => {
): Map<MyInfoAttribute, Promise<boolean>> => {
// Filter responses to only those fields with a corresponding hash
const fieldsWithHashes = filterFieldsWithHashes(responses, hashes)
// Map MyInfoAttribute to response
const myInfoResponsesObj = keyBy(
fieldsWithHashes,
(field) => field.myInfo.attr,
)
// Map MyInfoAttribute to Promise<boolean>
return mapValues(myInfoResponsesObj, (answer) =>
const myInfoResponsesMap = new Map<MyInfoAttribute, Promise<boolean>>()
fieldsWithHashes.forEach((field) => {
const attr = field.myInfo.attr
// Already checked that hashes contains this attr
compareSingleHash(hashes[answer.myInfo.attr]!, answer),
)
myInfoResponsesMap.set(attr, compareSingleHash(hashes[attr]!, field))
})
return myInfoResponsesMap
}

export const mapVerifyMyInfoError: MapRouteError = (error) => {
Expand Down

0 comments on commit 1a6e9c6

Please sign in to comment.