@opengovsg/mockpass 4.9.2 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -299,10 +299,15 @@ function lookUpPersonAttribute(profile, attribute) {
299
299
  function buildPersonInfo(profile, scope) {
300
300
  const requestedAttributes = scope
301
301
  .split(' ')
302
- .filter((requested) => FapiUtils.MyInfoPersonScopes.includes(requested))
302
+ .map((requested) =>
303
+ FapiUtils.MyInfoPersonScopes.includes(requested)
304
+ ? requested
305
+ : resolveGranularScope(requested),
306
+ )
307
+ .filter(Boolean)
303
308
 
304
309
  const personInfo = {}
305
- for (const attribute of requestedAttributes) {
310
+ for (const attribute of new Set(requestedAttributes)) {
306
311
  personInfo[attribute] = lookUpPersonAttribute(profile, attribute)
307
312
  }
308
313
  return personInfo
@@ -505,10 +510,19 @@ function verifyAllowedScopes(scope) {
505
510
  assert(scope, 'Scope is required')
506
511
  const scopes = scope.split(' ')
507
512
  for (const s of scopes) {
508
- if (!FapiUtils.SupportedScopes.includes(s))
513
+ if (!FapiUtils.SupportedScopes.includes(s) && !resolveGranularScope(s))
509
514
  throw new Error(`Scope ${s} is not supported`)
510
515
  }
511
516
  }
517
+
518
+ // Myinfo v4/v5 lets clients consent to a single field of a complex attribute
519
+ // with a dotted scope, e.g. vehicles.vehicleno or childrenbirthrecords.dob.
520
+ // Mockpass serves the whole parent attribute for any of its sub-scopes.
521
+ function resolveGranularScope(scope) {
522
+ const [parent, subAttribute] = scope.split('.')
523
+ if (!subAttribute) return null
524
+ return FapiUtils.MyInfoPersonScopes.includes(parent) ? parent : null
525
+ }
512
526
  function verifyStateAndNonce(state, nonce) {
513
527
  assert(state, 'State is required')
514
528
  if (/^[A-Za-z0-9/+_\-=.]{30,255}$/.test(state) === false)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengovsg/mockpass",
3
- "version": "4.9.2",
3
+ "version": "4.10.0",
4
4
  "description": "A mock SingPass/CorpPass server for dev purposes",
5
5
  "main": "app.js",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "base-64": "^1.0.0",
40
40
  "cookie-parser": "^1.4.3",
41
- "dotenv": "^17.2.0",
41
+ "dotenv": "^18.0.5",
42
42
  "expiry-map": "^2.0.0",
43
43
  "express": "^5.1.0",
44
44
  "express-session": "^1.19.0",
@@ -5408,7 +5408,18 @@
5408
5408
  "secondaryrace": {
5409
5409
  "code": "",
5410
5410
  "desc": ""
5411
- }
5411
+ },
5412
+ "vaccinationrequirements": [
5413
+ {
5414
+ "requirement": {
5415
+ "code": "1M3D",
5416
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
5417
+ },
5418
+ "fulfilled": {
5419
+ "value": true
5420
+ }
5421
+ }
5422
+ ]
5412
5423
  },
5413
5424
  {
5414
5425
  "dialect": {
@@ -5457,7 +5468,18 @@
5457
5468
  "secondaryrace": {
5458
5469
  "code": "",
5459
5470
  "desc": ""
5460
- }
5471
+ },
5472
+ "vaccinationrequirements": [
5473
+ {
5474
+ "requirement": {
5475
+ "code": "1M3D",
5476
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
5477
+ },
5478
+ "fulfilled": {
5479
+ "value": false
5480
+ }
5481
+ }
5482
+ ]
5461
5483
  }
5462
5484
  ],
5463
5485
  "drivinglicence": {
@@ -6537,7 +6559,18 @@
6537
6559
  "secondaryrace": {
6538
6560
  "code": "",
6539
6561
  "desc": ""
6540
- }
6562
+ },
6563
+ "vaccinationrequirements": [
6564
+ {
6565
+ "requirement": {
6566
+ "code": "1M3D",
6567
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
6568
+ },
6569
+ "fulfilled": {
6570
+ "value": true
6571
+ }
6572
+ }
6573
+ ]
6541
6574
  },
6542
6575
  {
6543
6576
  "dialect": {
@@ -6586,7 +6619,18 @@
6586
6619
  "secondaryrace": {
6587
6620
  "code": "",
6588
6621
  "desc": ""
6589
- }
6622
+ },
6623
+ "vaccinationrequirements": [
6624
+ {
6625
+ "requirement": {
6626
+ "code": "1M3D",
6627
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
6628
+ },
6629
+ "fulfilled": {
6630
+ "value": false
6631
+ }
6632
+ }
6633
+ ]
6590
6634
  }
6591
6635
  ],
6592
6636
  "drivinglicence": {
@@ -10988,7 +11032,18 @@
10988
11032
  "secondaryrace": {
10989
11033
  "code": "",
10990
11034
  "desc": ""
10991
- }
11035
+ },
11036
+ "vaccinationrequirements": [
11037
+ {
11038
+ "requirement": {
11039
+ "code": "1M3D",
11040
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
11041
+ },
11042
+ "fulfilled": {
11043
+ "value": true
11044
+ }
11045
+ }
11046
+ ]
10992
11047
  }
10993
11048
  ],
10994
11049
  "drivinglicence": {
@@ -13513,7 +13568,18 @@
13513
13568
  "secondaryrace": {
13514
13569
  "code": "",
13515
13570
  "desc": ""
13516
- }
13571
+ },
13572
+ "vaccinationrequirements": [
13573
+ {
13574
+ "requirement": {
13575
+ "code": "1M3D",
13576
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
13577
+ },
13578
+ "fulfilled": {
13579
+ "value": true
13580
+ }
13581
+ }
13582
+ ]
13517
13583
  },
13518
13584
  {
13519
13585
  "dialect": {
@@ -13562,7 +13628,18 @@
13562
13628
  "secondaryrace": {
13563
13629
  "code": "",
13564
13630
  "desc": ""
13565
- }
13631
+ },
13632
+ "vaccinationrequirements": [
13633
+ {
13634
+ "requirement": {
13635
+ "code": "1M3D",
13636
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
13637
+ },
13638
+ "fulfilled": {
13639
+ "value": false
13640
+ }
13641
+ }
13642
+ ]
13566
13643
  },
13567
13644
  {
13568
13645
  "dialect": {
@@ -18078,7 +18155,18 @@
18078
18155
  "secondaryrace": {
18079
18156
  "code": "",
18080
18157
  "desc": ""
18081
- }
18158
+ },
18159
+ "vaccinationrequirements": [
18160
+ {
18161
+ "requirement": {
18162
+ "code": "1M3D",
18163
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
18164
+ },
18165
+ "fulfilled": {
18166
+ "value": true
18167
+ }
18168
+ }
18169
+ ]
18082
18170
  },
18083
18171
  {
18084
18172
  "dialect": {
@@ -18127,7 +18215,18 @@
18127
18215
  "secondaryrace": {
18128
18216
  "code": "",
18129
18217
  "desc": ""
18130
- }
18218
+ },
18219
+ "vaccinationrequirements": [
18220
+ {
18221
+ "requirement": {
18222
+ "code": "1M3D",
18223
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
18224
+ },
18225
+ "fulfilled": {
18226
+ "value": false
18227
+ }
18228
+ }
18229
+ ]
18131
18230
  }
18132
18231
  ],
18133
18232
  "drivinglicence": {
@@ -20444,7 +20543,18 @@
20444
20543
  "secondaryrace": {
20445
20544
  "code": "",
20446
20545
  "desc": ""
20447
- }
20546
+ },
20547
+ "vaccinationrequirements": [
20548
+ {
20549
+ "requirement": {
20550
+ "code": "1M3D",
20551
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
20552
+ },
20553
+ "fulfilled": {
20554
+ "value": true
20555
+ }
20556
+ }
20557
+ ]
20448
20558
  },
20449
20559
  {
20450
20560
  "dialect": {
@@ -20493,7 +20603,18 @@
20493
20603
  "secondaryrace": {
20494
20604
  "code": "",
20495
20605
  "desc": ""
20496
- }
20606
+ },
20607
+ "vaccinationrequirements": [
20608
+ {
20609
+ "requirement": {
20610
+ "code": "1M3D",
20611
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
20612
+ },
20613
+ "fulfilled": {
20614
+ "value": false
20615
+ }
20616
+ }
20617
+ ]
20497
20618
  },
20498
20619
  {
20499
20620
  "dialect": {
@@ -22742,7 +22863,18 @@
22742
22863
  "secondaryrace": {
22743
22864
  "code": "",
22744
22865
  "desc": ""
22745
- }
22866
+ },
22867
+ "vaccinationrequirements": [
22868
+ {
22869
+ "requirement": {
22870
+ "code": "1M3D",
22871
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
22872
+ },
22873
+ "fulfilled": {
22874
+ "value": true
22875
+ }
22876
+ }
22877
+ ]
22746
22878
  },
22747
22879
  {
22748
22880
  "dialect": {
@@ -22791,7 +22923,18 @@
22791
22923
  "secondaryrace": {
22792
22924
  "code": "",
22793
22925
  "desc": ""
22794
- }
22926
+ },
22927
+ "vaccinationrequirements": [
22928
+ {
22929
+ "requirement": {
22930
+ "code": "1M3D",
22931
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
22932
+ },
22933
+ "fulfilled": {
22934
+ "value": false
22935
+ }
22936
+ }
22937
+ ]
22795
22938
  }
22796
22939
  ],
22797
22940
  "drivinglicence": {
@@ -23871,7 +24014,18 @@
23871
24014
  "secondaryrace": {
23872
24015
  "code": "",
23873
24016
  "desc": ""
23874
- }
24017
+ },
24018
+ "vaccinationrequirements": [
24019
+ {
24020
+ "requirement": {
24021
+ "code": "1M3D",
24022
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
24023
+ },
24024
+ "fulfilled": {
24025
+ "value": true
24026
+ }
24027
+ }
24028
+ ]
23875
24029
  },
23876
24030
  {
23877
24031
  "dialect": {
@@ -23920,7 +24074,18 @@
23920
24074
  "secondaryrace": {
23921
24075
  "code": "",
23922
24076
  "desc": ""
23923
- }
24077
+ },
24078
+ "vaccinationrequirements": [
24079
+ {
24080
+ "requirement": {
24081
+ "code": "1M3D",
24082
+ "desc": "Minimum 1 dose of MMR and 3 doses of DTaP"
24083
+ },
24084
+ "fulfilled": {
24085
+ "value": false
24086
+ }
24087
+ }
24088
+ ]
23924
24089
  },
23925
24090
  {
23926
24091
  "dialect": {
@@ -29398,4 +29563,4 @@
29398
29563
  }
29399
29564
  }
29400
29565
  }
29401
- }
29566
+ }