@opengovsg/mockpass 4.8.1 → 4.9.1
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.
- package/README.md +10 -6
- package/lib/assertions.js +18 -106
- package/package.json +1 -1
- package/static/corppass/users.json +58 -0
- package/static/singpass/users.json +52 -0
package/README.md
CHANGED
|
@@ -125,6 +125,7 @@ MockPass accepts any value for `client_id` and `redirect_uri`.
|
|
|
125
125
|
| Client signing and encryption keys | **Overview:** When client makes any request, what signing key is used to verify the client's signature on the client assertion, and what encryption key is used to encrypt the data payload. <br> **Default:** static keyset `static/certs/oidc-v2-rp-public.json` is used. <br> **How to configure:** Set the env var `SP_RP_JWKS_ENDPOINT` to a JWKS URL that MockPass can connect to. This can be a HTTP or HTTPS URL. |
|
|
126
126
|
| Login page | **Overview:** When client makes an authorize request, whether MockPass sends the client to a login page, instead of completing the login silently. <br> **Default:** Disabled for all requests. <br> **How to configure:** Enable for all requests by default by setting the env var `SHOW_LOGIN_PAGE` to `true`. Regardless of the default, you can override on a per-request basis by sending the HTTP request header `X-Show-Login-Page` with the value `true`. <br> **Detailed effect:** When login page is disabled, MockPass will immediately complete login and redirect to the `redirect_uri`. The profile used will be (in order of decreasing precedence) the profile specified in HTTP request headers (`X-Custom-NRIC` and `X-Custom-UUID` must both be specified), the profile with the NRIC specified in the env var `MOCKPASS_NRIC`, or the first profile in MockPass' static data. <br> When login page is enabled, MockPass returns a HTML page with a form that is used to complete the login. The client may select an existing profile, or provide a custom NRIC and UUID on the form. |
|
|
127
127
|
| ID token exchange | **Overview:** Singpass uses the client's [profile](https://docs.developer.singpass.gov.sg/docs/technical-specifications/singpass-authentication-api/2.-token-endpoint/authorization-code-grant#id-token-structure) to decide the format of the id token to send across. <br> **Default:** `direct` <br> **How to configure:** To set this, set the env var (`SINGPASS_CLIENT_PROFILE`) to the desired value |
|
|
128
|
+
| Test users/profiles | **Overview:** The list of NRIC/UUID (and, for foreign IDs, `sfa`) profiles MockPass can log in as. <br> **Default:** static data `static/singpass/users.json` is used. <br> **How to configure:** Set the env var `SINGPASS_USERS_PATH` to the path to a JSON file with the same shape (an array of `{ nric, uuid }`, optionally `sfa: { fid, coi, RP }` for NRICs starting with `Y`). An absolute path is recommended. |
|
|
128
129
|
|
|
129
130
|
### Corppass v2 (Corppass OIDC)
|
|
130
131
|
|
|
@@ -148,6 +149,7 @@ MockPass accepts any value for `client_id` and `redirect_uri`.
|
|
|
148
149
|
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
149
150
|
| Client signing and encryption keys | **Overview:** When client makes any request, what signing key is used to verify the client's signature on the client assertion, and what encryption key is used to encrypt the data payload. <br> **Default:** static keyset `static/certs/oidc-v2-rp-public.json` is used. <br> **How to configure:** Set the env var `CP_RP_JWKS_ENDPOINT` to a JWKS URL that MockPass can connect to. This can be a HTTP or HTTPS URL. |
|
|
150
151
|
| Login page | **Overview:** When client makes an authorize request, whether MockPass sends the client to a login page, instead of completing the login silently. <br> **Default:** Disabled for all requests. <br> **How to configure:** Enable for all requests by default by setting the env var `SHOW_LOGIN_PAGE` to `true`. Regardless of the default, you can override on a per-request basis by sending the HTTP request header `X-Show-Login-Page` with the value `true`. <br> **Detailed effect:** When login page is disabled, MockPass will immediately complete login and redirect to the `redirect_uri`. The profile used will be (in order of decreasing precedence) the profile specified in HTTP request headers (`X-Custom-NRIC`, `X-Custom-UUID`, `X-Custom-UEN` must all be specified), the profile with the NRIC specified in the env var `MOCKPASS_NRIC`, or the first profile in MockPass' static data. <br> When login page is enabled, MockPass returns a HTML page with a form that is used to complete the login. The client may select an existing profile, or provide a custom NRIC, UUID and UEN on the form. |
|
|
152
|
+
| Test users/profiles | **Overview:** The list of NRIC/UUID/UEN profiles MockPass can log in as. <br> **Default:** static data `static/corppass/users.json` is used. <br> **How to configure:** Set the env var `CORPPASS_USERS_PATH` to the path to a JSON file with the same shape (an array of `{ nric, uuid, name, isSingPassHolder, uen }`). An absolute path is recommended. |
|
|
151
153
|
|
|
152
154
|
### Myinfo v3
|
|
153
155
|
|
|
@@ -176,11 +178,12 @@ Only the profiles (NRICs) that have entries in Mockpass' personas dataset will
|
|
|
176
178
|
succeed, using other NRICs will result in an error. See the list of personas in
|
|
177
179
|
[static/myinfo/v3.json](static/myinfo/v3.json).
|
|
178
180
|
|
|
179
|
-
| Configuration item
|
|
180
|
-
|
|
|
181
|
-
| Client certificate
|
|
182
|
-
| Client secret
|
|
183
|
-
| Payload encryption
|
|
181
|
+
| Configuration item | Explanation |
|
|
182
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
183
|
+
| Client certificate | **Overview:** When client makes any request, what certificate is used to verify the request signature, and what certificate is used to encrypt the data payload. <br> **Default:** static certificate/key `static/certs/(server.crt\|key.pub)` are used. <br> **How to configure:** Set the env var `SERVICE_PROVIDER_PUB_KEY` to the path to a public key PEM file, and `SERVICE_PROVIDER_CERT_PATH` to the path to a certificate PEM file. (A certificate PEM file can also be provided to `SERVICE_PROVIDER_PUB_KEY`, despite the env var name.) |
|
|
184
|
+
| Client secret | **Overview:** When client makes a Token request, whether MockPass verifies the request signature. <br> **Default:** Disabled. <br> **How to configure:** Enable for all requests by setting the env var `SERVICE_PROVIDER_MYINFO_SECRET` to some non-blank string. Provide this value to your application as well. |
|
|
185
|
+
| Payload encryption | **Overview:** When client makes a Person or Person-Basic request, whether MockPass encrypts the data payload. When client makes a Person request, whether MockPass verifies the request signature. <br> **Default:** Disabled. <br> **How to configure:** Enable for all requests by setting the env var `ENCRYPT_MYINFO` to `true`. |
|
|
186
|
+
| Personas/test users | **Overview:** The dataset of NRIC-keyed personas (Myinfo attribute values, and the UUID/profile used for login) that MockPass serves. <br> **Default:** static data `static/myinfo/v3.json` is used. <br> **How to configure:** Set the env var `MYINFO_V3_USERS_PATH` to the path to a JSON file with the same shape (`{ attributes, personas }`, where `personas` is keyed by NRIC). An absolute path is recommended. |
|
|
184
187
|
|
|
185
188
|
To emulate the equivalent of the Test environment on Myinfo v3, you must both
|
|
186
189
|
set a client secret and enable payload encryption on MockPass.
|
|
@@ -209,7 +212,8 @@ MockPass accepts any value for `client_id`, `client_secret` and `redirect_uri`.
|
|
|
209
212
|
|
|
210
213
|
Only the profiles (NRICs) that have entries in Mockpass' personas dataset will
|
|
211
214
|
succeed, using other NRICs will result in an error. See the list of personas in
|
|
212
|
-
[static/myinfo/v3.json](static/myinfo/v3.json)
|
|
215
|
+
[static/myinfo/v3.json](static/myinfo/v3.json), or the env var
|
|
216
|
+
`MYINFO_V3_USERS_PATH` to override it (see the Myinfo v3 section above).
|
|
213
217
|
|
|
214
218
|
If the Public Officer Employment Details data item is requested, the
|
|
215
219
|
`pocdex.public_officer_details` scope data is sourced from the
|
package/lib/assertions.js
CHANGED
|
@@ -24,131 +24,43 @@ const hashToken = (token) => {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
const myinfo = {
|
|
27
|
-
v3: JSON.parse(
|
|
27
|
+
v3: JSON.parse(
|
|
28
|
+
readFrom(process.env.MYINFO_V3_USERS_PATH || '../static/myinfo/v3.json'),
|
|
29
|
+
),
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
const singPassUsers = JSON.parse(
|
|
33
|
+
readFrom(process.env.SINGPASS_USERS_PATH || '../static/singpass/users.json'),
|
|
34
|
+
)
|
|
35
|
+
const corpPassUsers = JSON.parse(
|
|
36
|
+
readFrom(process.env.CORPPASS_USERS_PATH || '../static/corppass/users.json'),
|
|
37
|
+
)
|
|
38
|
+
|
|
30
39
|
const oidc = {
|
|
31
40
|
singPass: [
|
|
32
|
-
|
|
33
|
-
{ nric: 'S8116474F', uuid: 'f4b70aea-d639-4b79-b8d9-8ace5875f6b1' },
|
|
34
|
-
{ nric: 'S8723211E', uuid: '178478de-fed7-4c03-a75e-e68c44d0d5f0' },
|
|
35
|
-
{ nric: 'S5062854Z', uuid: '1bd2e743-8681-4079-a557-6a66a8d16386' },
|
|
36
|
-
{ nric: 'T0066846F', uuid: '14f7ee8f-9e64-4170-a529-e55ca7578e2b' },
|
|
37
|
-
{ nric: 'F9477325W', uuid: '2135fe5c-d07b-49d3-b960-aabb0ff2e05a' },
|
|
38
|
-
{ nric: 'S3000024B', uuid: 'b5630beb-e3ee-4a31-aec5-534cdc087fd8' },
|
|
39
|
-
{ nric: 'S6005040F', uuid: '6c6745d9-e6c5-40ee-8c96-5d737ddbc5e4' },
|
|
40
|
-
{ nric: 'S6005041D', uuid: 'bd3fd1e0-c807-4b07-bbe4-b567cab54b8c' },
|
|
41
|
-
{ nric: 'S6005042B', uuid: '2dd788c0-d11f-4d5b-99af-b89d2389b474' },
|
|
42
|
-
{ nric: 'S6005043J', uuid: 'eb196477-36b3-4c0f-ae5e-2172e2f6a6d8' },
|
|
43
|
-
{ nric: 'S6005044I', uuid: '843ebc6b-1de1-4d46-b1dd-9ad4aeac3a27' },
|
|
44
|
-
{ nric: 'S6005045G', uuid: 'caafaedc-f369-498a-9e35-27e9cb7f0de2' },
|
|
45
|
-
{ nric: 'S6005046E', uuid: 'f9b37d06-de3f-4c4f-8331-37a3b2ee6cb4' },
|
|
46
|
-
{ nric: 'S6005047C', uuid: '57620e0f-fdf9-4f3e-a8f6-f6088e151395' },
|
|
47
|
-
{ nric: 'S6005064C', uuid: '80952b2f-3455-4b59-b50f-39afbc418271' },
|
|
48
|
-
{ nric: 'S6005065A', uuid: '3af48e26-69a1-43e3-b5f2-303098ef3210' },
|
|
49
|
-
{ nric: 'S6005066Z', uuid: '8b2f8213-2fe9-493a-ac95-0b55e319e689' },
|
|
50
|
-
{ nric: 'S6005037F', uuid: 'ae3d1d8c-6d14-449e-8ed1-9ce3d5e67607' },
|
|
51
|
-
{ nric: 'S6005038D', uuid: '23d3bb45-a324-46d6-b0d9-2e94194ed9ae' },
|
|
52
|
-
{ nric: 'S6005039B', uuid: '9ac807a2-5217-417a-a8d1-d7018b002b3f' },
|
|
53
|
-
{ nric: 'G1612357P', uuid: 'eb125a02-3137-486f-9262-eab3e0c57a5f' },
|
|
54
|
-
{ nric: 'G1612358M', uuid: 'd821900c-663d-4552-a753-a2e1cf8d124f' },
|
|
55
|
-
{ nric: 'F1612359P', uuid: '08df8d35-600c-45fd-a812-b37a27b7856a' },
|
|
56
|
-
{ nric: 'F1612360U', uuid: '1e90b698-23af-4acb-9fb4-eb5a80f444b6' },
|
|
57
|
-
{ nric: 'F1612361R', uuid: 'bc134ee1-f104-4b26-9839-32047fecb963' },
|
|
58
|
-
{ nric: 'F1612362P', uuid: '285e8366-f3bd-48b4-8153-b47260fc9f56' },
|
|
59
|
-
{ nric: 'F1612363M', uuid: '379bc106-d3db-492c-a38e-fd27642ef47f' },
|
|
60
|
-
{ nric: 'F1612364K', uuid: '108fa3ff-c85c-461e-ba1f-8edef62b68e2' },
|
|
61
|
-
{ nric: 'F1612365W', uuid: '1275ae4e-02d2-4b09-9573-36ac610ede89' },
|
|
62
|
-
{ nric: 'F1612366T', uuid: '23c6a3a4-d9d8-445f-a588-9d91831980a6' },
|
|
63
|
-
{ nric: 'F1612367Q', uuid: '0c400961-eb00-425a-8df4-6656b0b9245a' },
|
|
64
|
-
{ nric: 'F1612358R', uuid: '45669f5c-e9ac-43c6-bcd2-9c3757f1fa1c' },
|
|
65
|
-
{ nric: 'F1612354N', uuid: 'c38ddb2d-9e5d-45c2-bb70-8ccb54fc8320' },
|
|
66
|
-
{ nric: 'F1612357U', uuid: 'f904a2b1-4b61-47e2-bdad-e2d606325e20' },
|
|
67
|
-
{ nric: 'Y4581892I', uuid: 'acf8edda-bfdf-45fc-b140-a6ec6955d857' },
|
|
68
|
-
{ nric: 'Y7654321K', uuid: '9916f054-488e-4894-8299-412e46d89e67' },
|
|
69
|
-
{ nric: 'Y1234567P', uuid: '0fdcc18f-840b-4b35-80ee-44094a6cc66f' },
|
|
41
|
+
...singPassUsers,
|
|
70
42
|
...Object.keys(myinfo.v3.personas).map((nric) => ({
|
|
71
43
|
nric,
|
|
72
44
|
uuid: myinfo.v3.personas[nric].uuid.value,
|
|
73
45
|
claims: myinfo.v3.personas[nric],
|
|
74
46
|
})),
|
|
75
47
|
],
|
|
76
|
-
corpPass:
|
|
77
|
-
{
|
|
78
|
-
nric: 'S8979373D',
|
|
79
|
-
uuid: 'a9865837-7bd7-46ac-bef4-42a76a946424',
|
|
80
|
-
name: 'Name of S8979373D',
|
|
81
|
-
isSingPassHolder: true,
|
|
82
|
-
uen: '123456789A',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
nric: 'S8116474F',
|
|
86
|
-
uuid: 'f4b70aea-d639-4b79-b8d9-8ace5875f6b1',
|
|
87
|
-
name: 'Name of S8116474F',
|
|
88
|
-
isSingPassHolder: true,
|
|
89
|
-
uen: '123456789A',
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
nric: 'S8723211E',
|
|
93
|
-
uuid: '178478de-fed7-4c03-a75e-e68c44d0d5f0',
|
|
94
|
-
name: 'Name of S8723211E',
|
|
95
|
-
isSingPassHolder: true,
|
|
96
|
-
uen: '123456789A',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
nric: 'S5062854Z',
|
|
100
|
-
uuid: '1bd2e743-8681-4079-a557-6a66a8d16386',
|
|
101
|
-
name: 'Name of S5062854Z',
|
|
102
|
-
isSingPassHolder: true,
|
|
103
|
-
uen: '123456789B',
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
nric: 'T0066846F',
|
|
107
|
-
uuid: '14f7ee8f-9e64-4170-a529-e55ca7578e2b',
|
|
108
|
-
name: 'Name of T0066846F',
|
|
109
|
-
isSingPassHolder: true,
|
|
110
|
-
uen: '123456789B',
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
nric: 'F9477325W',
|
|
114
|
-
uuid: '2135fe5c-d07b-49d3-b960-aabb0ff2e05a',
|
|
115
|
-
name: 'Name of F9477325W',
|
|
116
|
-
isSingPassHolder: false,
|
|
117
|
-
uen: '123456789B',
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
nric: 'S3000024B',
|
|
121
|
-
uuid: 'b5630beb-e3ee-4a31-aec5-534cdc087fd8',
|
|
122
|
-
name: 'Name of S3000024B',
|
|
123
|
-
isSingPassHolder: true,
|
|
124
|
-
uen: '123456789C',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
nric: 'S6005040F',
|
|
128
|
-
uuid: '6c6745d9-e6c5-40ee-8c96-5d737ddbc5e4',
|
|
129
|
-
name: 'Name of S6005040F',
|
|
130
|
-
isSingPassHolder: true,
|
|
131
|
-
uen: '123456789C',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
48
|
+
corpPass: corpPassUsers,
|
|
134
49
|
create: {
|
|
135
50
|
singPass: (
|
|
136
|
-
{ nric, uuid },
|
|
51
|
+
{ nric, uuid, sfa },
|
|
137
52
|
iss,
|
|
138
53
|
aud,
|
|
139
54
|
nonce,
|
|
140
55
|
accessToken = crypto.randomBytes(15).toString('hex'),
|
|
141
56
|
) => {
|
|
142
57
|
let sub
|
|
143
|
-
const sfa = {
|
|
144
|
-
Y4581892I: { fid: 'G730Z-H5P96', coi: 'DE', RP: 'CORPPASS' },
|
|
145
|
-
Y7654321K: { fid: '123456789', coi: 'CN', RP: 'IRAS' },
|
|
146
|
-
Y1234567P: { fid: 'G730Z-H5P96', coi: 'MY', RP: 'CORPPASS' },
|
|
147
|
-
}
|
|
148
58
|
if (nric.startsWith('Y')) {
|
|
149
|
-
const sfaAccount = sfa
|
|
150
|
-
|
|
151
|
-
|
|
59
|
+
const sfaAccount = sfa || {
|
|
60
|
+
fid: 'G730Z-H5P96',
|
|
61
|
+
coi: 'DE',
|
|
62
|
+
RP: 'CORPPASS',
|
|
63
|
+
}
|
|
152
64
|
sub = `s=${nric},fid=${sfaAccount.fid},coi=${sfaAccount.coi},u=${uuid}`
|
|
153
65
|
} else {
|
|
154
66
|
sub = `s=${nric},u=${uuid}`
|
package/package.json
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"nric": "S8979373D",
|
|
4
|
+
"uuid": "a9865837-7bd7-46ac-bef4-42a76a946424",
|
|
5
|
+
"name": "Name of S8979373D",
|
|
6
|
+
"isSingPassHolder": true,
|
|
7
|
+
"uen": "123456789A"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"nric": "S8116474F",
|
|
11
|
+
"uuid": "f4b70aea-d639-4b79-b8d9-8ace5875f6b1",
|
|
12
|
+
"name": "Name of S8116474F",
|
|
13
|
+
"isSingPassHolder": true,
|
|
14
|
+
"uen": "123456789A"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"nric": "S8723211E",
|
|
18
|
+
"uuid": "178478de-fed7-4c03-a75e-e68c44d0d5f0",
|
|
19
|
+
"name": "Name of S8723211E",
|
|
20
|
+
"isSingPassHolder": true,
|
|
21
|
+
"uen": "123456789A"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"nric": "S5062854Z",
|
|
25
|
+
"uuid": "1bd2e743-8681-4079-a557-6a66a8d16386",
|
|
26
|
+
"name": "Name of S5062854Z",
|
|
27
|
+
"isSingPassHolder": true,
|
|
28
|
+
"uen": "123456789B"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"nric": "T0066846F",
|
|
32
|
+
"uuid": "14f7ee8f-9e64-4170-a529-e55ca7578e2b",
|
|
33
|
+
"name": "Name of T0066846F",
|
|
34
|
+
"isSingPassHolder": true,
|
|
35
|
+
"uen": "123456789B"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"nric": "F9477325W",
|
|
39
|
+
"uuid": "2135fe5c-d07b-49d3-b960-aabb0ff2e05a",
|
|
40
|
+
"name": "Name of F9477325W",
|
|
41
|
+
"isSingPassHolder": false,
|
|
42
|
+
"uen": "123456789B"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"nric": "S3000024B",
|
|
46
|
+
"uuid": "b5630beb-e3ee-4a31-aec5-534cdc087fd8",
|
|
47
|
+
"name": "Name of S3000024B",
|
|
48
|
+
"isSingPassHolder": true,
|
|
49
|
+
"uen": "123456789C"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"nric": "S6005040F",
|
|
53
|
+
"uuid": "6c6745d9-e6c5-40ee-8c96-5d737ddbc5e4",
|
|
54
|
+
"name": "Name of S6005040F",
|
|
55
|
+
"isSingPassHolder": true,
|
|
56
|
+
"uen": "123456789C"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "nric": "S8979373D", "uuid": "a9865837-7bd7-46ac-bef4-42a76a946424" },
|
|
3
|
+
{ "nric": "S8116474F", "uuid": "f4b70aea-d639-4b79-b8d9-8ace5875f6b1" },
|
|
4
|
+
{ "nric": "S8723211E", "uuid": "178478de-fed7-4c03-a75e-e68c44d0d5f0" },
|
|
5
|
+
{ "nric": "S5062854Z", "uuid": "1bd2e743-8681-4079-a557-6a66a8d16386" },
|
|
6
|
+
{ "nric": "T0066846F", "uuid": "14f7ee8f-9e64-4170-a529-e55ca7578e2b" },
|
|
7
|
+
{ "nric": "F9477325W", "uuid": "2135fe5c-d07b-49d3-b960-aabb0ff2e05a" },
|
|
8
|
+
{ "nric": "S3000024B", "uuid": "b5630beb-e3ee-4a31-aec5-534cdc087fd8" },
|
|
9
|
+
{ "nric": "S6005040F", "uuid": "6c6745d9-e6c5-40ee-8c96-5d737ddbc5e4" },
|
|
10
|
+
{ "nric": "S6005041D", "uuid": "bd3fd1e0-c807-4b07-bbe4-b567cab54b8c" },
|
|
11
|
+
{ "nric": "S6005042B", "uuid": "2dd788c0-d11f-4d5b-99af-b89d2389b474" },
|
|
12
|
+
{ "nric": "S6005043J", "uuid": "eb196477-36b3-4c0f-ae5e-2172e2f6a6d8" },
|
|
13
|
+
{ "nric": "S6005044I", "uuid": "843ebc6b-1de1-4d46-b1dd-9ad4aeac3a27" },
|
|
14
|
+
{ "nric": "S6005045G", "uuid": "caafaedc-f369-498a-9e35-27e9cb7f0de2" },
|
|
15
|
+
{ "nric": "S6005046E", "uuid": "f9b37d06-de3f-4c4f-8331-37a3b2ee6cb4" },
|
|
16
|
+
{ "nric": "S6005047C", "uuid": "57620e0f-fdf9-4f3e-a8f6-f6088e151395" },
|
|
17
|
+
{ "nric": "S6005064C", "uuid": "80952b2f-3455-4b59-b50f-39afbc418271" },
|
|
18
|
+
{ "nric": "S6005065A", "uuid": "3af48e26-69a1-43e3-b5f2-303098ef3210" },
|
|
19
|
+
{ "nric": "S6005066Z", "uuid": "8b2f8213-2fe9-493a-ac95-0b55e319e689" },
|
|
20
|
+
{ "nric": "S6005037F", "uuid": "ae3d1d8c-6d14-449e-8ed1-9ce3d5e67607" },
|
|
21
|
+
{ "nric": "S6005038D", "uuid": "23d3bb45-a324-46d6-b0d9-2e94194ed9ae" },
|
|
22
|
+
{ "nric": "S6005039B", "uuid": "9ac807a2-5217-417a-a8d1-d7018b002b3f" },
|
|
23
|
+
{ "nric": "G1612357P", "uuid": "eb125a02-3137-486f-9262-eab3e0c57a5f" },
|
|
24
|
+
{ "nric": "G1612358M", "uuid": "d821900c-663d-4552-a753-a2e1cf8d124f" },
|
|
25
|
+
{ "nric": "F1612359P", "uuid": "08df8d35-600c-45fd-a812-b37a27b7856a" },
|
|
26
|
+
{ "nric": "F1612360U", "uuid": "1e90b698-23af-4acb-9fb4-eb5a80f444b6" },
|
|
27
|
+
{ "nric": "F1612361R", "uuid": "bc134ee1-f104-4b26-9839-32047fecb963" },
|
|
28
|
+
{ "nric": "F1612362P", "uuid": "285e8366-f3bd-48b4-8153-b47260fc9f56" },
|
|
29
|
+
{ "nric": "F1612363M", "uuid": "379bc106-d3db-492c-a38e-fd27642ef47f" },
|
|
30
|
+
{ "nric": "F1612364K", "uuid": "108fa3ff-c85c-461e-ba1f-8edef62b68e2" },
|
|
31
|
+
{ "nric": "F1612365W", "uuid": "1275ae4e-02d2-4b09-9573-36ac610ede89" },
|
|
32
|
+
{ "nric": "F1612366T", "uuid": "23c6a3a4-d9d8-445f-a588-9d91831980a6" },
|
|
33
|
+
{ "nric": "F1612367Q", "uuid": "0c400961-eb00-425a-8df4-6656b0b9245a" },
|
|
34
|
+
{ "nric": "F1612358R", "uuid": "45669f5c-e9ac-43c6-bcd2-9c3757f1fa1c" },
|
|
35
|
+
{ "nric": "F1612354N", "uuid": "c38ddb2d-9e5d-45c2-bb70-8ccb54fc8320" },
|
|
36
|
+
{ "nric": "F1612357U", "uuid": "f904a2b1-4b61-47e2-bdad-e2d606325e20" },
|
|
37
|
+
{
|
|
38
|
+
"nric": "Y4581892I",
|
|
39
|
+
"uuid": "acf8edda-bfdf-45fc-b140-a6ec6955d857",
|
|
40
|
+
"sfa": { "fid": "G730Z-H5P96", "coi": "DE", "RP": "CORPPASS" }
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"nric": "Y7654321K",
|
|
44
|
+
"uuid": "9916f054-488e-4894-8299-412e46d89e67",
|
|
45
|
+
"sfa": { "fid": "123456789", "coi": "CN", "RP": "IRAS" }
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"nric": "Y1234567P",
|
|
49
|
+
"uuid": "0fdcc18f-840b-4b35-80ee-44094a6cc66f",
|
|
50
|
+
"sfa": { "fid": "G730Z-H5P96", "coi": "MY", "RP": "CORPPASS" }
|
|
51
|
+
}
|
|
52
|
+
]
|