node-my-info-sg
Advanced tools
Comparing version 1.1.0 to 1.1.1
@@ -19,3 +19,3 @@ const _ = require('lodash'); | ||
getAuthoriseUrl(purpose, attributes) { | ||
getAuthoriseUrl(purpose, attributes, redirectUrl) { | ||
const state = crypto.randomBytes(16).toString('hex'); | ||
@@ -27,7 +27,7 @@ const authoriseUrl = `${this._authApiUrl}\ | ||
&state=${state}\ | ||
&redirect_uri=${this._redirectUrl}`; | ||
&redirect_uri=${redirectUrl || this._redirectUrl}`; | ||
return { authoriseUrl, state }; | ||
} | ||
async getToken(code) { | ||
async getToken(code, redirectUrl) { | ||
const { | ||
@@ -41,3 +41,3 @@ _authLevel, _clientId, _clientSecret, _privateKeyPath, _redirectUrl, _tokenApiUrl, | ||
grant_type: 'authorization_code', | ||
redirect_uri: _redirectUrl, | ||
redirect_uri: redirectUrl || _redirectUrl, | ||
client_id: _clientId, | ||
@@ -44,0 +44,0 @@ client_secret: _clientSecret, |
{ | ||
"name": "node-my-info-sg", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "lib/client.js", |
@@ -5,3 +5,3 @@ # node-my-info-sg 🇸🇬 | ||
Small wrapper around Singapore [MyInfo V3 API](https://www.ndi-api.gov.sg/library/trusted-data/myinfo/introduction) for node JS. Wraps the scary-scary 😱 security logic into easy to use APIs | ||
Small wrapper around Singapore [MyInfo V3 API](https://www.ndi-api.gov.sg/library/trusted-data/myinfo/introduction) for node JS. Wraps the scary-scary 😱 security logic into easy to use APIs. | ||
@@ -44,6 +44,7 @@ Lightly refactored from the [excellent official example](https://github.com/ndi-trusted-data/myinfo-demo-app) 🎉 | ||
1. **Generate the OAuth2 url** | ||
```js | ||
var { authoriseUrl, state } = myInfoClient.getAuthoriseUrl(purpose, attributes); | ||
// Then you can pass authoriseUrl to your frontend app and redirect the user | ||
const attributes = ['uinfin', 'name', 'mobileno']; | ||
const { authoriseUrl, state } = myInfoClient.getAuthoriseUrl(purpose, attributes); | ||
// Then you can pass authoriseUrl to your frontend app | ||
// (or open authoriseUrl on a WebView on your mobile apps) | ||
@@ -59,15 +60,11 @@ // | ||
// Exchange authorisation code with usable access token | ||
myInfoClient.getToken(code) | ||
// Get the person object | ||
.then(({ accessToken }) => myInfoClient.getPerson(accessToken, _attributes)) | ||
// Now you can use the person object to pre-fill your form! | ||
.then(({ person }) => console.log(JSON.stringify(person))); | ||
const { accessToken } = await myInfoClient.getToken(code); | ||
// Get the person object | ||
// Make sure attributes is the same as the one requested in previous step! | ||
const { person } = await myInfoClient.getPerson(accessToken, attributes) | ||
// Now you can return the person object to your frontend and pre-fill your form! | ||
console.log(JSON.stringify(person)); | ||
``` | ||
## Test | ||
```js | ||
yarn test | ||
``` | ||
@@ -82,6 +79,9 @@ ## Example | ||
``` | ||
## Future Improvement | ||
1. Add sensible linting rules | ||
1. Pass this repository to the cool government guy, so they can maintain it | ||
## Unit test | ||
```js | ||
yarn lint | ||
yarn test | ||
``` |
@@ -17,4 +17,6 @@ import _ from 'lodash'; | ||
async function runSingpassMockOAuthFlow(page, url, callbackUrl) { | ||
await page.goto(url); | ||
async function runMockpassOAuthFlow(page, authoriseUrl, callbackUrl) { | ||
// Visit authoriseUrl login with the second user on the dropdown | ||
await page.goto(authoriseUrl); | ||
await page.waitFor('#salutationCode'); | ||
@@ -24,3 +26,6 @@ await page.evaluate(() => { document.getElementById('salutationCode').selectedIndex = 2; }); | ||
// Wait until allow permission button is visible | ||
await page.waitFor('button#allow'); | ||
// Click on allow permission and wait for redirection to callbackUrl | ||
const [request] = await Promise.all([ | ||
@@ -48,2 +53,3 @@ page.waitForRequest((_request) => _.startsWith(_request.url(), callbackUrl)), | ||
redirectUrl, | ||
overrideRedirectUrl, | ||
}) { | ||
@@ -60,5 +66,7 @@ const client = new MyInfoClient({ | ||
const actualRedirectUrl = overrideRedirectUrl || redirectUrl; | ||
const { authoriseUrl, state } = client.getAuthoriseUrl(purpose, attributes); | ||
const { authoriseUrl, state } = client.getAuthoriseUrl(purpose, attributes, overrideRedirectUrl); | ||
// client.getAuthoriseUrl should construct a authoriseUrl | ||
expect(authoriseUrl).toEqual(`\ | ||
@@ -69,10 +77,10 @@ ${baseUrl}/com/v3/authorise?client_id=${clientId}\ | ||
&state=${state}\ | ||
&redirect_uri=${redirectUrl}`); | ||
&redirect_uri=${actualRedirectUrl}`); | ||
const { code } = await runSingpassMockOAuthFlow(page, authoriseUrl, redirectUrl); | ||
// Oauth flow should returns an authorization_code | ||
const { code } = await runMockpassOAuthFlow(page, authoriseUrl, actualRedirectUrl); | ||
// OAuth flow should returns an authorization_code | ||
expect(typeof code).toEqual('string'); | ||
const { accessToken } = await client.getToken(code); | ||
const { accessToken } = await client.getToken(code, overrideRedirectUrl); | ||
// client.getToken should returns an accessToken | ||
@@ -102,14 +110,23 @@ expect(typeof accessToken).toEqual('string'); | ||
describe('on sandbox environment (no PKI digital signature)', () => { | ||
const baseParams = { | ||
purpose: ' signing up with MyInfo', | ||
attributes: ['uinfin', 'name', 'mobileno'], | ||
baseUrl: 'https://sandbox.api.myinfo.gov.sg', | ||
authLevel: 'L0', | ||
publicCertPath: './example/ssl/stg-auth-signing-public.pem', | ||
privateKeyPath: './example/ssl/stg-demoapp-client-privatekey-2018.pem', | ||
clientId: 'STG2-MYINFO-SELF-TEST', | ||
clientSecret: '44d953c796cccebcec9bdc826852857ab412fbe2', | ||
redirectUrl: 'http://localhost:3001/callback', | ||
}; | ||
it('handles the full MyInfo flow', () => { | ||
return testFullMyInfoFlow({ ...baseParams, page }); | ||
}); | ||
it('handles the full MyInfo flow with when overriding the redirectUrl', () => { | ||
return testFullMyInfoFlow({ | ||
...baseParams, | ||
page, | ||
purpose: ' signing up with MyInfo', | ||
attributes: ['uinfin', 'name', 'mobileno'], | ||
baseUrl: 'https://sandbox.api.myinfo.gov.sg', | ||
authLevel: 'L0', | ||
publicCertPath: './example/ssl/stg-auth-signing-public.pem', | ||
privateKeyPath: './example/ssl/stg-demoapp-client-privatekey-2018.pem', | ||
clientId: 'STG2-MYINFO-SELF-TEST', | ||
clientSecret: '44d953c796cccebcec9bdc826852857ab412fbe2', | ||
redirectUrl: 'http://localhost:3001/callback', | ||
overrideRedirectUrl: 'http://localhost:3001/callback', | ||
}); | ||
@@ -116,0 +133,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
86844
399
0