diff --git a/package-lock.json b/package-lock.json index d5c2b4e..244683e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "jose": "4.9.2", + "node-fetch": "2.6.4", "node-rsa": "1.1.1", "openid-client": "5.4.0" }, @@ -17,6 +18,7 @@ "@types/jest": "^29.5.0", "@types/jsonwebtoken": "^9.0.1", "@types/node": "*", + "@types/node-fetch": "2.6.4", "@types/node-rsa": "^1.1.1", "@typescript-eslint/eslint-plugin": "^5.59.2", "@typescript-eslint/parser": "^5.59.2", @@ -1502,6 +1504,16 @@ "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==", "dev": true }, + "node_modules/@types/node-fetch": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", + "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, "node_modules/@types/node-rsa": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/node-rsa/-/node-rsa-1.1.1.tgz", @@ -2206,6 +2218,12 @@ "node": ">=8" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -2747,6 +2765,18 @@ "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -2873,6 +2903,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -3931,6 +3970,20 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5940,6 +5993,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -6022,6 +6096,26 @@ } } }, + "node_modules/msw/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/msw/node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -6053,23 +6147,14 @@ "dev": true }, "node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "dev": true, + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.4.tgz", + "integrity": "sha512-aD1fO+xtLiSCc9vuD+sYMxpIuQyhHscGSkBEo2o5LTV/3bTEAYvdUii29n8LlO5uLCmWdGP7uVUVXFo5SRdkLA==", "dependencies": { "whatwg-url": "^5.0.0" }, "engines": { "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } } }, "node_modules/node-int64": { @@ -7201,8 +7286,7 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/ts-jest": { "version": "29.0.5", @@ -7477,14 +7561,12 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -8814,6 +8896,16 @@ "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==", "dev": true }, + "@types/node-fetch": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", + "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + } + }, "@types/node-rsa": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/node-rsa/-/node-rsa-1.1.1.tgz", @@ -9272,6 +9364,12 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -9648,6 +9746,15 @@ "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -9742,6 +9849,12 @@ "object-keys": "^1.1.1" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -10557,6 +10670,17 @@ "is-callable": "^1.1.3" } }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -12059,6 +12183,21 @@ "picomatch": "^2.2.3" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -12113,6 +12252,15 @@ "yargs": "^17.3.1" }, "dependencies": { + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, "type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -12140,10 +12288,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "dev": true, + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.4.tgz", + "integrity": "sha512-aD1fO+xtLiSCc9vuD+sYMxpIuQyhHscGSkBEo2o5LTV/3bTEAYvdUii29n8LlO5uLCmWdGP7uVUVXFo5SRdkLA==", "requires": { "whatwg-url": "^5.0.0" } @@ -12972,8 +13119,7 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "ts-jest": { "version": "29.0.5", @@ -13170,14 +13316,12 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/package.json b/package.json index f1b63fd..756bd95 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@types/jest": "^29.5.0", "@types/jsonwebtoken": "^9.0.1", "@types/node": "*", + "@types/node-fetch": "2.6.4", "@types/node-rsa": "^1.1.1", "@typescript-eslint/eslint-plugin": "^5.59.2", "@typescript-eslint/parser": "^5.59.2", @@ -54,6 +55,7 @@ }, "dependencies": { "jose": "4.9.2", + "node-fetch": "2.6.4", "node-rsa": "1.1.1", "openid-client": "5.4.0" } diff --git a/src/SgidClient.ts b/src/SgidClient.ts index 0d301ee..5cc5f6a 100644 --- a/src/SgidClient.ts +++ b/src/SgidClient.ts @@ -1,4 +1,5 @@ import { compactDecrypt, importJWK, importPKCS8 } from 'jose' +import fetch from 'node-fetch' import { Client, Issuer } from 'openid-client' import { @@ -6,6 +7,7 @@ import { DEFAULT_SCOPE, DEFAULT_SGID_CODE_CHALLENGE_METHOD, SGID_AUTH_METHOD, + SGID_RULES_ENGINE_ENDPOINT, SGID_SIGNING_ALG, SGID_SUPPORTED_GRANT_TYPES, } from './constants' @@ -17,6 +19,8 @@ import { CallbackParams, CallbackReturn, ParsedSgidDataValue, + RulesParams, + RulesReturn, SgidClientParams, UserInfoParams, UserInfoReturn, @@ -30,18 +34,21 @@ import { export class SgidClient { private privateKey: string private sgID: Client + private rulesEngineEndpoint: string /** * Initialises an SgidClient instance. - * @param params Constructor arguments - * @param params.clientId Client ID provided during client registration - * @param params.clientSecret Client secret provided during client registration - * @param params.privateKey Client private key provided during client registration - * @param params.redirectUri Redirection URI for user to return to your application + * @param params Constructor arguments. + * @param params.clientId Client ID provided during client registration. + * @param params.clientSecret Client secret provided during client registration. + * @param params.privateKey Client private key provided during client registration. + * @param params.redirectUri Redirection URI for user to return to your application. * after login. If not provided in the constructor, this must be provided to the * authorizationUrl and callback functions. * @param params.hostname Hostname of OpenID provider (sgID). Defaults to * https://api.id.gov.sg. + * @param params.rulesEngineEndpoint API endpoint for sgID Rules Engine. Defaults to + * https://rules.id.gov.sg/api/rule/eval. */ constructor({ clientId, @@ -49,6 +56,7 @@ export class SgidClient { privateKey, redirectUri, hostname = 'https://api.id.gov.sg', + rulesEngineEndpoint = SGID_RULES_ENGINE_ENDPOINT, }: SgidClientParams) { /** * Note that issuer is appended with version number only from v2 onwards @@ -72,6 +80,8 @@ export class SgidClient { token_endpoint_auth_method: SGID_AUTH_METHOD, }) + this.rulesEngineEndpoint = rulesEngineEndpoint + /** * For backward compatibility with pkcs1 */ @@ -99,7 +109,7 @@ export class SgidClient { * param is provided, it will be used instead of the redirect URI provided in the * SgidClient constructor. If not provided in the constructor, the redirect URI * must be provided here. - * @param codeChallenge The code challenge from the code verifier used for PKCE enhancement + * @param codeChallenge The code challenge from the code verifier used for PKCE enhancement. */ authorizationUrl({ state, @@ -136,12 +146,12 @@ export class SgidClient { /** * Exchanges authorization code for access token. - * @param code The authorization code received from the authorization server + * @param code The authorization code received from the authorization server. * @param nonce Nonce passed to authorizationUrl for this request. Specify null * if no nonce was passed to authorizationUrl. * @param redirectUri The redirect URI used in the authorization request. Defaults to the one * passed to the SgidClient constructor. - * @param codeVerifier The code verifier that was used to generate the code challenge that was passed in `authorizationUrl` + * @param codeVerifier The code verifier that was used to generate the code challenge that was passed in `authorizationUrl`. * @returns The sub (subject identifier claim) of the user and access token. The subject * identifier claim is the end-user's unique ID. */ @@ -169,8 +179,8 @@ export class SgidClient { /** * Retrieves verified user info and decrypts it with your private key. - * @param sub The sub returned from the callback function - * @param accessToken The access token returned from the callback function + * @param sub The sub returned from the callback function. + * @param accessToken The access token returned from the callback function. * @returns The sub of the end-user and the end-user's verified data. The sub * returned is the same as the one passed in the params. */ @@ -209,6 +219,39 @@ export class SgidClient { return { sub, data: {} } } + /** + * Generates dynamic derived data based on rules defined on sgID Developer Portal. + * @param rulesParams The parameters for dynamic derived data calculation. + * @param rulesParams.accessToken The access token returned from the callback function. + * @param rulesParams.ruleIds The space-separated string containing rule IDs. + * @param rulesParams.userInfoData The end-user's verified data. + * @returns {RulesReturn} A list of rule IDs, alongside with their corresponding inputs and outputs. + */ + async rules(rulesParams: RulesParams): Promise { + try { + const { accessToken, ruleIds, userInfoData } = rulesParams + const response = await fetch(this.rulesEngineEndpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ + ruleIds, + userInfoData, + }), + }) + + if (!response.ok) { + // json() is less helpful if API users log errors with console.error() + throw new Error(await response.text()) + } + return await response.json() + } catch (err) { + return Promise.reject((err as Error).message) + } + } + private async decryptPayload( encryptedPayloadKey: string, data: Record, diff --git a/src/constants.ts b/src/constants.ts index a1ee242..13f4444 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -7,3 +7,6 @@ export const SGID_SUPPORTED_GRANT_TYPES: ResponseType[] = ['code'] export const SGID_AUTH_METHOD: ClientAuthMethod = 'client_secret_post' export const API_VERSION = 2 + +export const SGID_RULES_ENGINE_ENDPOINT = + 'https://rules.id.gov.sg/api/rule/eval' diff --git a/src/types.ts b/src/types.ts index e97ccd2..cdcc955 100644 --- a/src/types.ts +++ b/src/types.ts @@ -35,4 +35,17 @@ export type SgidClientParams = { privateKey: string redirectUri?: string hostname?: string + rulesEngineEndpoint?: string } + +export type RulesParams = { + accessToken: string + ruleIds: string + userInfoData: Record +} + +export type RulesReturn = { + ruleId: string + input: string + output: string +}[]