@opengovsg/mockpass 4.3.3 → 4.3.5
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/.github/workflows/publish.yml +5 -0
- package/README.md +32 -29
- package/lib/assertions.js +17 -2
- package/lib/express/myinfo/controllers.js +1 -1
- package/lib/express/oidc/v2-ndi.js +13 -8
- package/package.json +3 -3
|
@@ -29,6 +29,8 @@ jobs:
|
|
|
29
29
|
cache: 'npm'
|
|
30
30
|
cache-dependency-path: '**/package-lock.json'
|
|
31
31
|
registry-url: https://registry.npmjs.org/
|
|
32
|
+
- name: Set up QEMU
|
|
33
|
+
uses: docker/setup-qemu-action@v3
|
|
32
34
|
- name: Set up Docker Buildx
|
|
33
35
|
uses: docker/setup-buildx-action@v3
|
|
34
36
|
- name: Login to Docker Hub
|
|
@@ -41,6 +43,9 @@ jobs:
|
|
|
41
43
|
uses: docker/build-push-action@v6
|
|
42
44
|
with:
|
|
43
45
|
push: true
|
|
46
|
+
platforms: |
|
|
47
|
+
linux/arm64/v8
|
|
48
|
+
linux/amd64
|
|
44
49
|
tags: |
|
|
45
50
|
opengovsg/mockpass:latest
|
|
46
51
|
opengovsg/mockpass:${{ env.TAGNAME }}
|
package/README.md
CHANGED
|
@@ -27,16 +27,17 @@ Configure your application to point to the following endpoints:
|
|
|
27
27
|
Configure your application (or MockPass) with keys:
|
|
28
28
|
|
|
29
29
|
- EITHER configure MockPass with your application's JWKS endpoint URL using the env
|
|
30
|
-
|
|
30
|
+
var `SP_RP_JWKS_ENDPOINT`.
|
|
31
31
|
- OR configure your application to use the private keys from
|
|
32
32
|
`static/certs/oidc-v2-rp-secret.json`.
|
|
33
33
|
|
|
34
34
|
MockPass accepts any value for `client_id` and `redirect_uri`.
|
|
35
35
|
|
|
36
|
-
| Configuration item
|
|
37
|
-
|
|
38
|
-
| 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.
|
|
39
|
-
| Login page
|
|
36
|
+
| Configuration item | Explanation |
|
|
37
|
+
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
38
|
+
| 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. |
|
|
39
|
+
| 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. |
|
|
40
|
+
| 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 |
|
|
40
41
|
|
|
41
42
|
### Corppass v2 (Corppass OIDC)
|
|
42
43
|
|
|
@@ -50,16 +51,16 @@ Configure your application to point to the following endpoints:
|
|
|
50
51
|
Configure your application (or MockPass) with keys:
|
|
51
52
|
|
|
52
53
|
- EITHER configure MockPass with your application's JWKS endpoint URL using the env
|
|
53
|
-
|
|
54
|
+
var `CP_RP_JWKS_ENDPOINT`. HTTP/HTTPS endpoints are supported.
|
|
54
55
|
- OR configure your application to use the private keys from
|
|
55
56
|
`static/certs/oidc-v2-rp-secret.json`.
|
|
56
57
|
|
|
57
58
|
MockPass accepts any value for `client_id` and `redirect_uri`.
|
|
58
59
|
|
|
59
|
-
| Configuration item
|
|
60
|
-
|
|
61
|
-
| 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.
|
|
62
|
-
| Login page
|
|
60
|
+
| Configuration item | Explanation |
|
|
61
|
+
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
62
|
+
| 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. |
|
|
63
|
+
| 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. |
|
|
63
64
|
|
|
64
65
|
### Myinfo v3
|
|
65
66
|
|
|
@@ -75,7 +76,7 @@ Configure your application (or MockPass) with certificates/keys:
|
|
|
75
76
|
- Provide your application with
|
|
76
77
|
the certificate `static/certs/spcp.crt` as the Myinfo public certificate.
|
|
77
78
|
- EITHER configure MockPass with your application's X.509 certificate by setting
|
|
78
|
-
the env vars `SERVICE_PROVIDER_PUB_KEY` and `SERVICE_PROVIDER_CERT_PATH` to
|
|
79
|
+
the env vars `SERVICE_PROVIDER_PUB_KEY` and `SERVICE_PROVIDER_CERT_PATH` to
|
|
79
80
|
the path to the certificate in PEM format. Self-signed or untrusted
|
|
80
81
|
certificates are supported.
|
|
81
82
|
- OR configure your application to use the certificate and private key
|
|
@@ -88,11 +89,11 @@ Only the profiles (NRICs) that have entries in Mockpass' personas dataset will
|
|
|
88
89
|
succeed, using other NRICs will result in an error. See the list of personas in
|
|
89
90
|
[static/myinfo/v3.json](static/myinfo/v3.json).
|
|
90
91
|
|
|
91
|
-
| Configuration item | Explanation
|
|
92
|
-
|
|
92
|
+
| Configuration item | Explanation |
|
|
93
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
93
94
|
| 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.) |
|
|
94
|
-
| Client secret
|
|
95
|
-
| 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`.
|
|
95
|
+
| 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. |
|
|
96
|
+
| 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`. |
|
|
96
97
|
|
|
97
98
|
To emulate the equivalent of the Test environment on Myinfo v3, you must both
|
|
98
99
|
set a client secret and enable payload encryption on MockPass.
|
|
@@ -120,10 +121,10 @@ Configure your application (or MockPass) with certificates/keys:
|
|
|
120
121
|
MockPass accepts any value for `client_id`, `client_secret` and `redirect_uri`.
|
|
121
122
|
|
|
122
123
|
Only the profiles (NRICs) that have entries in Mockpass' personas dataset will
|
|
123
|
-
succeed, using other NRICs will result in an error. See the list of personas in
|
|
124
|
+
succeed, using other NRICs will result in an error. See the list of personas in
|
|
124
125
|
[static/myinfo/v3.json](static/myinfo/v3.json).
|
|
125
126
|
|
|
126
|
-
If the Public Officer Employment Details data item is requested, the
|
|
127
|
+
If the Public Officer Employment Details data item is requested, the
|
|
127
128
|
`pocdex.public_officer_details` scope data is sourced from the
|
|
128
129
|
`publicofficerdetails` data key (where present) on personas.
|
|
129
130
|
Most personas do not have this data key configured, and will result in a `"NA"`
|
|
@@ -132,10 +133,10 @@ in the login page dropdown, please check the personas dataset linked above to
|
|
|
132
133
|
identify them.
|
|
133
134
|
The `pocdex.number_of_employments` scope is not supported.
|
|
134
135
|
|
|
135
|
-
| Configuration item | Explanation
|
|
136
|
-
|
|
137
|
-
| 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 key `static/certs/key.pub` is used. <br> **How to configure:** Set the env var `SERVICE_PROVIDER_PUB_KEY` to the path to a public key PEM file. (A certificate PEM file can also be provided, despite the env var name.)
|
|
138
|
-
| Login page
|
|
136
|
+
| Configuration item | Explanation |
|
|
137
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
138
|
+
| 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 key `static/certs/key.pub` is used. <br> **How to configure:** Set the env var `SERVICE_PROVIDER_PUB_KEY` to the path to a public key PEM file. (A certificate PEM file can also be provided, despite the env var name.) |
|
|
139
|
+
| 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 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. |
|
|
139
140
|
|
|
140
141
|
### Singpass/Corppass v1 (legacy)
|
|
141
142
|
|
|
@@ -144,12 +145,14 @@ The `pocdex.number_of_employments` scope is not supported.
|
|
|
144
145
|
Configure your application to point to the following endpoints:
|
|
145
146
|
|
|
146
147
|
Singpass (v1 - Singpass OIDC):
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
|
|
149
|
+
- http://localhost:5156/singpass/authorize - OIDC login redirect with optional page
|
|
150
|
+
- http://localhost:5156/singpass/token - receives OIDC authorization code and returns id_token
|
|
149
151
|
|
|
150
152
|
Corppass (v1 - Corppass OIDC):
|
|
151
|
-
|
|
152
|
-
|
|
153
|
+
|
|
154
|
+
- http://localhost:5156/corppass/authorize - OIDC login redirect with optional page
|
|
155
|
+
- http://localhost:5156/corppass/token - receives OIDC authorization code and returns id_token
|
|
153
156
|
|
|
154
157
|
Configure your application with keys and/or certificates:
|
|
155
158
|
|
|
@@ -165,10 +168,10 @@ from `static/certs/(server.crt|key.pem)`.
|
|
|
165
168
|
|
|
166
169
|
Common configuration:
|
|
167
170
|
|
|
168
|
-
| Configuration item | Explanation
|
|
169
|
-
|
|
170
|
-
| Port number
|
|
171
|
-
| Stateless Mode
|
|
171
|
+
| Configuration item | Explanation |
|
|
172
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
173
|
+
| Port number | **Overview:** What port number MockPass will listen for HTTP requests on. <br> **Default:** 5156. <br> **How to configure:** Set the env var `MOCKPASS_PORT` or `PORT` to some port number. |
|
|
174
|
+
| Stateless Mode | **Overview:** Enable for environments where the state of the process is not guaranteed, such as in serverless contexts. <br> **Default:** not set. <br> **How to configure:** Set the env var `MOCKPASS_STATELESS` to `true` or `false`. |
|
|
172
175
|
|
|
173
176
|
Run MockPass:
|
|
174
177
|
|
package/lib/assertions.js
CHANGED
|
@@ -64,6 +64,9 @@ const oidc = {
|
|
|
64
64
|
{ nric: 'F1612358R', uuid: '45669f5c-e9ac-43c6-bcd2-9c3757f1fa1c' },
|
|
65
65
|
{ nric: 'F1612354N', uuid: 'c38ddb2d-9e5d-45c2-bb70-8ccb54fc8320' },
|
|
66
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' },
|
|
67
70
|
...Object.keys(myinfo.v3.personas).map((nric) => ({
|
|
68
71
|
nric,
|
|
69
72
|
uuid: myinfo.v3.personas[nric].uuid.value,
|
|
@@ -135,8 +138,20 @@ const oidc = {
|
|
|
135
138
|
nonce,
|
|
136
139
|
accessToken = crypto.randomBytes(15).toString('hex'),
|
|
137
140
|
) => {
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
let sub
|
|
142
|
+
const sfa = {
|
|
143
|
+
Y4581892I: { fid: 'G730Z-H5P96', coi: 'DE', RP: 'CORPPASS' },
|
|
144
|
+
Y7654321K: { fid: '123456789', coi: 'CN', RP: 'IRAS' },
|
|
145
|
+
Y1234567P: { fid: 'G730Z-H5P96', coi: 'MY', RP: 'CORPPASS' },
|
|
146
|
+
}
|
|
147
|
+
if (nric.startsWith('Y')) {
|
|
148
|
+
const sfaAccount = sfa[nric]
|
|
149
|
+
? sfa[nric]
|
|
150
|
+
: { fid: 'G730Z-H5P96', coi: 'DE', RP: 'CORPPASS' }
|
|
151
|
+
sub = `s=${nric},fid=${sfaAccount.fid},coi=${sfaAccount.coi},u=${uuid}`
|
|
152
|
+
} else {
|
|
153
|
+
sub = `s=${nric},u=${uuid}`
|
|
154
|
+
}
|
|
140
155
|
const accessTokenHash = hashToken(accessToken)
|
|
141
156
|
|
|
142
157
|
const refreshToken = crypto.randomBytes(20).toString('hex')
|
|
@@ -50,7 +50,7 @@ module.exports =
|
|
|
50
50
|
const encryptedAndSignedPersona = await new jose.CompactEncrypt(
|
|
51
51
|
Buffer.from(sign),
|
|
52
52
|
)
|
|
53
|
-
.setProtectedHeader({ alg: 'RSA-OAEP', enc: '
|
|
53
|
+
.setProtectedHeader({ alg: 'RSA-OAEP', enc: 'A256GCM' })
|
|
54
54
|
.encrypt(publicKey)
|
|
55
55
|
return encryptedAndSignedPersona
|
|
56
56
|
}
|
|
@@ -382,14 +382,6 @@ function config(app, { showLoginPage, isStateless }) {
|
|
|
382
382
|
)
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
if (!protectedHeader.typ) {
|
|
386
|
-
console.error('The client_assertion typ should be set')
|
|
387
|
-
return res.status(401).send({
|
|
388
|
-
error: 'invalid_client',
|
|
389
|
-
error_description: 'The client_assertion typ should be set',
|
|
390
|
-
})
|
|
391
|
-
}
|
|
392
|
-
|
|
393
385
|
if (idp === 'singPass') {
|
|
394
386
|
if (clientAssertionClaims['sub'] !== client_id) {
|
|
395
387
|
console.error(
|
|
@@ -473,6 +465,19 @@ function config(app, { showLoginPage, isStateless }) {
|
|
|
473
465
|
.setProtectedHeader(signedProtectedHeader)
|
|
474
466
|
.sign(signingKey)
|
|
475
467
|
|
|
468
|
+
if (
|
|
469
|
+
process.env.SINGPASS_CLIENT_PROFILE === 'direct' ||
|
|
470
|
+
process.env.SINGPASS_CLIENT_PROFILE === 'bridge'
|
|
471
|
+
)
|
|
472
|
+
return res.status(200).send({
|
|
473
|
+
access_token: accessToken,
|
|
474
|
+
token_type: 'Bearer',
|
|
475
|
+
id_token: signedIdToken,
|
|
476
|
+
...(idp === 'corpPass'
|
|
477
|
+
? { scope: 'openid', expires_in: 10 * 60 }
|
|
478
|
+
: {}),
|
|
479
|
+
})
|
|
480
|
+
|
|
476
481
|
// Step 4: Encrypt ID token with RP encryption key
|
|
477
482
|
const rpEncryptionKey = findEncryptionKey(
|
|
478
483
|
rpKeysetJson,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengovsg/mockpass",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.5",
|
|
4
4
|
"description": "A mock SingPass/CorpPass server for dev purposes",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"bin": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"cookie-parser": "^1.4.3",
|
|
41
41
|
"dotenv": "^16.0.0",
|
|
42
42
|
"expiry-map": "^2.0.0",
|
|
43
|
-
"express": "^
|
|
43
|
+
"express": "^5.1.0",
|
|
44
44
|
"jose": "^5.2.3",
|
|
45
45
|
"jsonwebtoken": "^9.0.0",
|
|
46
46
|
"lodash": "^4.17.11",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"eslint": "^9.8.0",
|
|
61
61
|
"eslint-config-prettier": "^9.1.0",
|
|
62
62
|
"eslint-plugin-prettier": "^4.0.0",
|
|
63
|
-
"globals": "^
|
|
63
|
+
"globals": "^16.0.0",
|
|
64
64
|
"husky": "^9.0.11",
|
|
65
65
|
"lint-staged": "^15.2.2",
|
|
66
66
|
"nodemon": "^3.0.1",
|