-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-implementing E-Signet flow to mosip repository #23
Changes from 19 commits
693c91f
2aa2ea2
4b67f2f
695007b
aed6020
4f4ddb7
f9a5720
fe72e50
8e9c98b
ef95c8f
fd610fd
ad5cb20
7e0e4b1
823cdc5
993c8b2
720bbb1
1175621
1825d50
54ae37e
9f0f475
9f68810
8781067
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
node_modules | ||
node_modules | ||
.secrets | ||
.turbo | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "@opencrvs/mosip", | ||
"version": "1.7.0-alpha.2", | ||
"license": "MPL-2.0", | ||
"private": true, | ||
"packageManager": "yarn@1.0.0", | ||
"workspaces": [ | ||
"packages/*" | ||
], | ||
"devDependencies": { | ||
"turbo": "^2.3.3", | ||
"typescript": "^5.6.3" | ||
}, | ||
"scripts": { | ||
"dev": "turbo run dev" | ||
} | ||
} |
euanmillar marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,84 @@ | ||
// @TODO: Yet to be implemented! Placeholders for NPM publish. | ||
|
||
/** | ||
* E-Signet popup button form definition | ||
* E-Signet popup button and hidden field form definitions | ||
* @example | ||
* ``` | ||
* [ | ||
* // ...other fields | ||
* ...esignet({ url: "https://opencrvs-mosip-gateway.farajaland.opencrvs.org" }) | ||
* ] | ||
* ``` | ||
*/ | ||
|
||
/** | ||
* | ||
* @description E-Signet REDIRECT button form definition. Calls E-Signet /authorize (this field may not be supported in the latest release of OpenCRVS yet) | ||
* | ||
*/ | ||
export const esignet = (esignetAuthUrl: string, openIdProviderClientId: string, openIdProviderClaims: string, fieldName: string, callbackFieldName: string) => { | ||
|
||
const url = new URL(esignetAuthUrl) | ||
|
||
url.searchParams.append( | ||
'client_id', | ||
openIdProviderClientId || 'mock-client_id' | ||
) | ||
url.searchParams.append('response_type', 'code') | ||
url.searchParams.append('scope', 'openid profile') | ||
url.searchParams.append('acr_values', 'mosip:idp:acr:static-code') | ||
url.searchParams.append('claims', openIdProviderClaims || 'mock-claims') | ||
url.searchParams.append('state', 'trigger-onmount') | ||
|
||
/* | ||
|
||
TODO: Understand from Tahmid about how to handle this: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tahmidrahman-dsi can you advise how we can send this state and callback URL to E-Signet using the REDIRECT button please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @euanmillar Current implementation saves no state. But can be saved if the requirement needs. Before developing, it would be great if I have a bit more understanding from my side.
As per my understanding, the above parameters are appended as search query params to the redirect url ( If my understanding is correct, does putting those params inside cc: @naftis There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are correct to this step:
After that though, the above URL redirects back to OpenCRVS with
The onmount-fetch should be able to be configured so that for example a https://docs.esignet.io/integration/relying-party There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tahmidrahman-dsi @naftis my question was, how does the REDIRECT button know the draftId in order to format the state URL query param so that this works with mock-authorizer HTML which appears to need it like this: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://github.com/opencrvs/opencrvs-countryconfig-mosip/pull/1/files#r1905329313 Referred to this question here |
||
|
||
url.searchParams.append( | ||
'redirect_uri', | ||
`${window.location.origin}${OIDP_VERIFICATION_CALLBACK}` | ||
) | ||
const stateToBeSent: INidCallbackState = { | ||
pathname: currentPathname, | ||
declarationId: declarationId, | ||
section: currentSection | ||
} | ||
url.searchParams.append('state', JSON.stringify(stateToBeSent)) | ||
*/ | ||
window.location.href = url.toString() | ||
|
||
return { | ||
name: fieldName, | ||
validator: [], | ||
icon: { | ||
desktop: 'Globe', | ||
mobile: 'Fingerprint' | ||
}, | ||
type: "REDIRECT", | ||
custom: true, | ||
label: { | ||
id: 'views.idReader.label.eSignet', | ||
defaultMessage: 'E-signet' | ||
}, | ||
hideInPreview: true, | ||
conditionals: [ | ||
{ | ||
action: "disable", | ||
expression: "!!$form.redirectCallbackFetch", | ||
}, | ||
], | ||
options: { | ||
url: esignetAuthUrl, | ||
callback: { | ||
params: { | ||
code: "esignet-mock-code", | ||
}, | ||
trigger: callbackFieldName | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
export const popupButton = ({ | ||
/** URL to OpenCRVS-MOSIP gateway (e.g. https://opencrvs-mosip-gateway.farajaland.opencrvs.org) */ | ||
url | ||
|
@@ -16,29 +92,63 @@ export const popupButton = ({ | |
}; | ||
}; | ||
|
||
export const hidden = () => { | ||
/** | ||
* | ||
* @description esignet callback button form definition. Calls server/esignet-api /esignet/get-oidp-user-info (this field may not be supported in the latest release of OpenCRVS yet) | ||
* | ||
*/ | ||
|
||
export const esignetCallback = ({ | ||
fieldName, | ||
getOIDPUserInfoUrl, | ||
openIdProviderClientId | ||
}: { | ||
fieldName: string; | ||
getOIDPUserInfoUrl: string; | ||
openIdProviderClientId: string; | ||
}) => ({ | ||
name: fieldName, | ||
type: 'HTTP', | ||
custom: true, | ||
label: { | ||
id: 'form.field.label.empty', | ||
defaultMessage: '' | ||
}, | ||
validator: [], | ||
options: { | ||
getOIDPUserInfoUrl, | ||
headers: { | ||
'Content-type': 'application/json' | ||
}, | ||
body: { | ||
code: "esignet-mock-code", | ||
clientId: openIdProviderClientId, | ||
redirectUri: "" | ||
}, | ||
method: 'POST' | ||
} | ||
}); | ||
|
||
export const returnExpression = (fieldName: string) => { | ||
return { | ||
dependsOn: ["redirectCallbackFetch"], | ||
expression: `$form.redirectCallbackFetch?.data?.${fieldName}`, | ||
}; | ||
}; | ||
|
||
export const esignetHidden = () => { | ||
return { | ||
name: 'INFORMANT_PSUT_TOKEN', | ||
type: 'HIDDEN' | ||
}; | ||
}; | ||
|
||
/** | ||
* E-Signet popup button and hidden field form definitions | ||
* @example | ||
* ``` | ||
* [ | ||
* // ...other fields | ||
* ...esignet({ url: "https://opencrvs-mosip-gateway.farajaland.opencrvs.org" }) | ||
* ] | ||
* ``` | ||
*/ | ||
|
||
/** | ||
* | ||
* @description ID reader field definition (this field may not be supported in the latest release of OpenCRVS yet) | ||
* @description QR reader type definition (this field may not be supported in the latest release of OpenCRVS yet) | ||
* | ||
*/ | ||
|
||
export const idReader = ( | ||
event: string, | ||
sectionId: string, | ||
|
@@ -73,76 +183,9 @@ export const idReader = ( | |
}; | ||
}; | ||
|
||
/** | ||
* | ||
* @description QR reader type definition (this field may not be supported in the latest release of OpenCRVS yet) | ||
* | ||
*/ | ||
export const qr = () => ({ | ||
type: 'QR' | ||
}); | ||
|
||
/** | ||
* | ||
* @description esignet reader type definition (this field may not be supported in the latest release of OpenCRVS yet) | ||
* | ||
*/ | ||
export const esignet = ({ | ||
url, | ||
callbackFieldName | ||
}: { | ||
url: string; | ||
callbackFieldName: string; | ||
}) => ({ | ||
name: 'redirect', | ||
validator: [], | ||
icon: { | ||
desktop: 'Globe', | ||
mobile: 'Fingerprint' | ||
}, | ||
type: 'REDIRECT', | ||
label: { | ||
id: 'views.idReader.label.eSignet', | ||
defaultMessage: 'E-signet' | ||
}, | ||
options: { | ||
url, | ||
callback: { | ||
params: { | ||
authorized: 'true' | ||
}, | ||
trigger: callbackFieldName | ||
} | ||
} | ||
}); | ||
|
||
export const esignetCallback = ({ | ||
fieldName, | ||
url | ||
}: { | ||
fieldName: string; | ||
url: string; | ||
}) => ({ | ||
name: fieldName, | ||
type: 'HTTP', | ||
custom: true, | ||
label: { | ||
id: 'form.field.label.empty', | ||
defaultMessage: '' | ||
}, | ||
validator: [], | ||
options: { | ||
url, | ||
headers: { | ||
'Content-type': 'application/json' | ||
}, | ||
method: 'GET' | ||
} | ||
}); | ||
|
||
// export const esignet = ({ | ||
// url | ||
// }: { | ||
// /** URL to OpenCRVS-MOSIP gateway (e.g. https://opencrvs-mosip-gateway.farajaland.opencrvs.org) */ | ||
// url: string; | ||
// }) => [popupButton({ url }), hidden()]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM node:23.1.0 | ||
WORKDIR /usr/src/app | ||
|
||
COPY package.json package.json | ||
COPY yarn.lock yarn.lock | ||
RUN yarn install --production --frozen-lockfile | ||
COPY src/ src/ | ||
|
||
CMD ["yarn", "start"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# esignet-mock | ||
|
||
This simple mock is used to simulate the ESIGNET application & API for local development. It simulates the eSignet flow by redirecting you instantly back to the redirect_uri and allows fecthing of user info once authenticated. | ||
|
||
## Usage | ||
|
||
1. Run the mock server: | ||
|
||
```bash | ||
yarn start | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "@opencrvs/esignet-mock", | ||
"license": "MPL-2.0", | ||
"version": "1.7.0-alpha.2", | ||
"main": "index.js", | ||
"scripts": { | ||
"dev": "NODE_ENV=development tsx watch src/index.ts", | ||
"start": "NODE_ENV=production tsx src/index.ts" | ||
}, | ||
"dependencies": { | ||
"@fastify/formbody": "^8.0.1", | ||
"@fastify/static": "^8.0.3", | ||
"@types/node": "^22.4.1", | ||
"envalid": "^8.0.0", | ||
"fastify": "^5.0.0", | ||
"jose": "^5.9.6", | ||
"jsonwebtoken": "^9.0.2", | ||
"tsx": "^4.19.2", | ||
"typescript": "^5.6.3" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,7 @@ | ||||||
import { cleanEnv, port, str, url } from "envalid"; | ||||||
|
||||||
export const env = cleanEnv(process.env, { | ||||||
PORT: port({ default: 20260 }), | ||||||
HOST: str({ default: "0.0.0.0", devDefault: "localhost" }), | ||||||
CLIENT_URL: url({ devDefault: "http://localhost:3000" }), | ||||||
}); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
hmmm have I might have forgot to install Prettier to this repo. I can action on that |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
eyJwIjoiX2lyZGtxaWJUQXk0ZjR0R2pnYUJsVzNtbXJIakZFb1hYTnEzdlN4UUZSLWFkU2dHQjN3eWQzckJxZkZKOFhZY1B5YVpnZy1kLTNxXzhscEVHel9rZ2VDNkFsRFFfd0gwSDFrSVV2Y0NueHAxR0hTMXF2YWFSWThQQUFTbkVyVzM5Tm9GR3JFblhOVFo5cHpwRHZ3WEwtcERkU3V4T2dSRXhkekdna0dDVURzIiwia3R5IjoiUlNBIiwicSI6InYySUp4NEV3VjdudXYzSFdpMjBqdkcyWm5SdnQtOENfRWgyOXp6NWJTM1NUeDlsUGw4dlNyZWJmVzVoRjJuZ1o3eW94NEF4R2h3UjZtdFo0SEJpcVR3RjQ3U28yMGdBeENpa1FadG9CSG1TdFpyTVo3Z011cGVDdXh3WHNhc0prRGdrVks5RmJ5UzFzdk1aTzRaWTdxVHhsZ3pRWl9uRi1ERGpRenN4OGpOTSIsImQiOiJYbHBKY28zTjZfd0F6UE4wZEliRjkxR0xLT2J5NVN5WVFjTWQ0eUV6ZkVYa2xKWU9nc1N1TTBiTTloU0loVU50U1JTV1B6U045aXBqb3RQc29yZExMa25qTkY3aWw2NGtkQVZaSTA4SnVjWXVHSDNVZ3ppTDB3WkNnNnBDRnd4NzlPVDkwU0xxTl9GV3NyNllYWXJIbDhiRHNENTBQSTlCaUgzTmdRTEx3SWowcFdLXzZ0OFhoZ3BJUElON2ZwdF9oQkVCTkNYenpUbEtoMHVBYTZ0VHd6eHdEOHlHWjB5LU42VVlYbkJoLUwzREZ4UWdzQ09zU050ZHhlQVBFRHBzeU1zTzRhU3FyLWxxZVpCTWI5MHR0T3FoczJ0UTlzVXRKcklaMy15WVJCN2N3VUg5TkVzQzV4UjIzZm5rSHFZbk5BYXd3a2Q1WDlSTXlrYU5saWpXN1EiLCJlIjoiQVFBQiIsInVzZSI6InNpZyIsInFpIjoic2JQWVpPNDdRbG04NXRWR19INDJfdjIxcDVQNUVJeEtBZmNLd3RfZDR1UW84MXNpa3VmVTg3MDkzaTA1R2RXeTUzUXo3bkgyNkItdGliN3p0bHVSUXhEdV9uaEpTUm9XRnk2M3pRLUVrd3picmFGN2xSZXRYZjYxcGZjNy1XTFJTcWpPa1J3LVc0VGROdURmdWxicGNyUFBURVNQS0w4ZVpNMzdoU0JnMTFrIiwiZHAiOiJaWllZYlUtNmtsRGJSUThUcWh4cm1xQU1kWFA0QU5vRU1IYXl6WWR5a3A3SkMxNXQybndIWjczR3ZmZlV5QS1mQnBhVThHanhpZHZyOEItbjdRUkNmcTZsYWR1SFRRVW8zNGFrVHhTdkZZeHJsTlRBNzQ0VTV3eGd3Rzhibjl6Rm83V29LSno1MEo2Nloxa2J4WU40ZVF3MjNoUVNoOF9BOVJ4aXN4a2Z6cFUiLCJhbGciOiJSUzI1NiIsImRxIjoiS3phcDJxQnpGX3ZseXRpYmh4UDNzNzVUcDBQOU1wRk5FM3dmdGNId3YxTHRZM3pRR2dodDQ5SnpzS3pyYU84aGVfMWRFYWZ6N055NENtcE82Smt4SzNHN3FtR1R5MHM3eDMyS05JOFpIWkhDRGFSM1FHVDdqWHowT2dBLVo4VEk3dHBpSzJpMGZ2S0EwUWMtSEhYZHR0THFZUHZNdXNWSm50emRXVFNYRXYwIiwibiI6InZnTlJidE5RWnVpLXNSdlZ2YTNnb1FvWXRGRXVTNV9wOWZrZk5WbjFYRDdvU1VZVFg3U2RiS0wyNzlTUTJqZDZubzUxRVY0aHpOck1OV1Q2Ylh4UVVGZGNqVFJrQlBJcDhnOFkyd0ZTWkhSa1ZiYUUxNTBnU2VZUmZwb1dYZTVDMURyMUR3WGZCOExCb0liREd6d3FCdnpfcDJpT3dQWXM2bkxKeEV1bWdWcUYtZVc3N09LVzZFdl9KSG02U28wUmVYVHFlakpqQlF4eGFlMFA3akFPcTFOU3lobTBYTG5XQ08yNlpvM0RMUklrb1hPWlZZQl9peGkyLUtsUF9uVnFRajF4VEtGWmpWSURIcE5WVnJmX2YxZUpvRkYyQklJTXNfWXpYUWxoRTZHbGkwTmJwanhmX21LWVVJS1I4eE4zY1VQbVItMjhjRnl0eHV1M0l0eGtvUSJ9Cg== |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 nice, please introduce Turbo to me!