Skip to content

Commit

Permalink
chore: add better age_over_NN attributes
Browse files Browse the repository at this point in the history
Signed-off-by: Berend Sliedrecht <[email protected]>
  • Loading branch information
berendsliedrecht committed Jan 29, 2025
1 parent b3cea90 commit 0d3d6d2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
8 changes: 5 additions & 3 deletions src/__tests__/issuing/issuing-mdoc.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,17 @@ describe('issuing an MDOC', () => {

it('should include the namespace and attributes', () => {
const attrValues = parsedDocument.getIssuerNameSpace('org.iso.18013.5.1')
// @ts-expect error this will work
const currentAge = new Date(Date.now() - new Date('2007-03-25').getTime()).getFullYear() - 1970
expect(attrValues).toMatchInlineSnapshot(`
Map {
"family_name" => "Jones",
"given_name" => "Ava",
"birth_date" => "2007-03-25",
"age_over_12" => true,
"age_over_14" => true,
"age_over_16" => true,
"age_over_18" => false,
"age_over_21" => false,
"age_over_17" => true,
"age_over_65" => false,
"issue_date" => "2023-09-01",
"expiry_date" => "2028-09-30",
"issuing_country" => "US",
Expand Down
26 changes: 24 additions & 2 deletions src/mdoc/model/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ export default function isObject(input: unknown): input is Record<string, unknow

const DEFAULT_NS = 'org.iso.18013.5.1'

// TODO:
//
// This should be calculated from the `validFrom` field in device retrieval
// and the `iat` from server retrieval. Not `Date.now()`
//
// In case of device retrieval, the value of an age_over_NN data element
// shall be calculated by the issuing authority infrastructure to be valid
// at the value of the timestamp in the validFrom element in the MSO
// from 9.1.2.4. In case of server retrieval, the value of an age_over_NN
// data element shall be valid at the value of the iat timestamp as
// defined in 8.3.2.2.2.2 and 8.3.3.2.2.
const getAgeInYears = (birth: string): number => {
const birthDate = new Date(birth)
birthDate.setHours(0, 0, 0, 0)
Expand Down Expand Up @@ -131,9 +142,20 @@ export class Document {
if (typeof value !== 'string') {
throw new Error(`Invalid type for 'birth_date'. Expected 'string', received '${typeof value}'`)
}

const ageInYears = getAgeInYears(value)
addAttribute('age_over_21', ageInYears >= 21)
addAttribute(`age_over_${Math.floor(ageInYears)}`, true)
const addAgePredicate = (predicate: number) => addAttribute(`age_over_${predicate}`, ageInYears >= predicate)

// Age predicates.
// Values defined in: https://bmi.usercontent.opencode.de/eudi-wallet/eidas-2.0-architekturkonzept/functions/00-pid-issuance-and-presentation/#pid-contents
// ISO/IEC 18013-5: 7.2.5 does not define which ages should be included.

addAgePredicate(12)
addAgePredicate(14)
addAgePredicate(16)
addAgePredicate(18)
addAgePredicate(21)
addAgePredicate(65)
}
}

Expand Down

0 comments on commit 0d3d6d2

Please sign in to comment.