@@ -10,11 +10,8 @@ const mockDecryptKey = "sshh-secret";
1010const mockSignKey = "sshh-secret" ;
1111const mockTokenResponse : TokenResponse = {
1212 access_token : "MOCK_ACCESS_TOKEN" ,
13- refresh_token : "MOCK_REFRESH_TOKEN" ,
1413 id_token : "MOCK_ID_TOKEN" ,
1514 token_type : "bearer" ,
16- expires_in : 599 ,
17- scope : "openid" ,
1815} ;
1916
2017const createMockTokenPayload = ( overrideProps ?: Partial < TokenPayload > ) : TokenPayload => ( {
@@ -49,7 +46,7 @@ describe("NDI Singpass Helper", () => {
4946 } ,
5047 } ) ,
5148 ) ;
52- const authUrl = await helper . constructAuthorizationUrl ( "af0ifjsldkj" , "a2ghskf1234las" ) ;
49+ const authUrl = await helper . constructAuthorizationUrl ( "af0ifjsldkj" , "a2ghskf1234las" , [ ] ) ;
5350 const expected =
5451 "https://mocksingpass.sg/authorize?state=af0ifjsldkj&nonce=a2ghskf1234las&redirect_uri=http%3A%2F%2Fmockme.sg%2Fcallback&scope=openid&client_id=CLIENT-ID&response_type=code" ;
5552 expect ( authUrl ) . toEqual ( expected ) ;
@@ -64,7 +61,7 @@ describe("NDI Singpass Helper", () => {
6461 } ,
6562 } ) ,
6663 ) ;
67- const authUrl = await helper . constructAuthorizationUrl ( "af0ifjsldkj" , "a2ghskf1234las" , "2345667" ) ;
64+ const authUrl = await helper . constructAuthorizationUrl ( "af0ifjsldkj" , "a2ghskf1234las" , [ ] , "2345667" ) ;
6865 const expected =
6966 "https://mocksingpass.sg/authorize?state=af0ifjsldkj&nonce=a2ghskf1234las&redirect_uri=http%3A%2F%2Fmockme.sg%2Fcallback&scope=openid&client_id=CLIENT-ID&response_type=code&code_challenge_method=S256&code_challenge=ry3USnoiRbnteX-97HMq8iiTHOzPnoXSaytUNIuOXUg" ;
7067 expect ( authUrl ) . toEqual ( expected ) ;
@@ -172,4 +169,66 @@ describe("NDI Singpass Helper", () => {
172169 expect ( axiosMock ) . toHaveBeenCalledTimes ( 2 ) ;
173170 } ) ;
174171 } ) ;
172+
173+ describe ( "getUserInfo()" , ( ) => {
174+ const mockOverrideDecryptKey =
175+ '{"kty": "EC","d": "AA1YtF2O779tiuJ4Rs3UVItxgX3GFOgQ-aycS-n-lFU","use": "enc","crv": "P-256","kid": "MOCK-OVERRIDE-DECRYPT-KEY-ID","x": "MFqQFZrB74cDhiBHhIBg9iCB-qj86vU45dj2iA-RAjs","y": "yUOsmZh4rd3qwqXRgRCIaAyRcOj4S0mD6tEsd-aTlL0","alg": "ECDH-ES+A256KW"}' ;
176+
177+ const mockVerifiedJws = { payload : JSON . stringify ( { mockResults : "VERIFIED_JWS" } ) } ;
178+
179+ it ( "should use overrideDecryptKey when specified" , async ( ) => {
180+ const corppassHelper = new NdiOidcHelper ( {
181+ ...props ,
182+ } ) ;
183+
184+ const mockDecryptJwe = jest
185+ . spyOn ( JweUtils , "decryptJWE" )
186+ . mockResolvedValueOnce ( { payload : "DECRYPT_RESULTS" } as unknown as JWE . DecryptResult ) ;
187+ const mockVerifyJWSUsingKeyStore = jest
188+ . spyOn ( JweUtils , "verifyJwsUsingKeyStore" )
189+ . mockResolvedValueOnce ( mockVerifiedJws as unknown as JWS . VerificationResult ) ;
190+
191+ const mockJwksUrl = "https://www.mocksingpass.gov.sg/.well-known/keys" ;
192+ const mockTokenEndpoint = "https://www.mocksingpass.gov.sg/mga/sps/oauth/oauth20/token" ;
193+ const mockIssuer = "https://www.mocksingpass.gov.sg" ;
194+ const mockAuthorizationInfoEndpoint = "https://www.mocksingpass.gov.sg/authorization-info" ;
195+ const axiosMock = jest . fn ( ) ;
196+ // First get is to get OIDC Config
197+ axiosMock . mockImplementationOnce ( ( ) => {
198+ return {
199+ status : 200 ,
200+ data : {
201+ token_endpoint : mockTokenEndpoint ,
202+ issuer : mockIssuer ,
203+ "authorization-info_endpoint" : mockAuthorizationInfoEndpoint ,
204+ jwks_uri : mockJwksUrl ,
205+ } ,
206+ } ;
207+ } ) ;
208+
209+ // Second get is to get JWKS
210+ axiosMock . mockImplementationOnce ( ( ) => {
211+ return {
212+ status : 200 ,
213+ data : {
214+ keys : [ "MOCK_KEY" ] ,
215+ } ,
216+ } ;
217+ } ) ;
218+
219+ corppassHelper . _testExports . getSingpassClient ( ) . get = axiosMock ;
220+
221+ await corppassHelper . getUserInfo ( mockTokenResponse . access_token , {
222+ key : mockOverrideDecryptKey ,
223+ format : "json" ,
224+ } ) ;
225+
226+ expect ( axiosMock . mock . calls [ 0 ] ) . toEqual ( expect . arrayContaining ( [ mockOidcConfigUrl ] ) ) ;
227+ expect ( axiosMock . mock . calls [ 1 ] ) . toEqual ( expect . arrayContaining ( [ mockJwksUrl ] ) ) ;
228+
229+ expect ( mockDecryptJwe ) . toHaveBeenCalledWith ( mockTokenResponse . id_token , mockOverrideDecryptKey , "json" ) ;
230+ expect ( mockVerifyJWSUsingKeyStore ) . toHaveBeenCalledWith ( "DECRYPT_RESULTS" , [ "MOCK_KEY" ] ) ;
231+ expect ( axiosMock ) . toHaveBeenCalledTimes ( 2 ) ;
232+ } ) ;
233+ } ) ;
175234} ) ;
0 commit comments