diff --git a/README.md b/README.md index 9976bc4..8d1072d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Credentials from a mobile wallet. But building that takes considerable time and expertise. -> [!NOTE] +> [!NOTE] > As a new feature, the bridge now supports incremental authorization. > This allows the service provider to request additional Verifiable Credentials > from the user via the bridge. Please see the @@ -196,7 +196,7 @@ dynamic API endpoints. The API is documented using Swagger, which provides a user-friendly interface to explore and test the API. -> [!NOTE] +> [!NOTE] > To access the Swagger documentation, you need to run the bridge in development mode and > navigate to `http://localhost:5002/api-docs`. @@ -204,7 +204,7 @@ To authenticate requests to the dynamic API in Swagger, you need to provide a valid API key. The API key is stored in the `.env` file in the `vclogin` folder. -> [!NOTE] +> [!NOTE] > To authenticate requests to the dynamic API in Swagger, first click on > the "Authorize" button in the top right corner of the Swagger UI. Then, enter > the API key in the "Value" field with the format `API_KEY `and click @@ -327,7 +327,7 @@ refer to the end of the previous section. ## Running Tests -This repository includes unit tests with `jest` and end-to-end tests with +This repository includes unit tests with `vitest` and end-to-end tests with `playwright`. You may run them as follows: ```bash @@ -490,18 +490,18 @@ authorization. An example of such a policy file is: ``` -> [!IMPORTANT] +> [!IMPORTANT] > Each `credentialId` should be unique across all policy objects, > and should have integer string values starting from 1, incrementing by 1 for each subsequent policy object. This helps us determine > the correct policy object to apply to the VCs. -> [!IMPORTANT] +> [!IMPORTANT] > Altough the `type` field is an optional parameter, it needs to be > present in a policy file that has multiple policy objects. This is crucial for the accurate application of policies. -> [!NOTE] +> [!NOTE] > First we reorder the policy objects in a policy file based on the `credentialId` and > then we reorder the credentials in the VP based on the `type` field from the reordered policy file. > This ensures that each credential is matched with the correct policy object. @@ -576,7 +576,7 @@ below, the first VC's `credentialSubject.id` is compared with the second VC's `credentialSubject.id` in the second policy object. -> [!IMPORTANT] +> [!IMPORTANT] > You need to correctly define the JSONPaths of the constraint > operands to be able to perform constraints check. The JSONPaths should have a > structure like `$.` when having multiple policy diff --git a/vclogin/.env.test b/vclogin/.env.test index 29bdbd0..45ed675 100644 --- a/vclogin/.env.test +++ b/vclogin/.env.test @@ -1,2 +1,3 @@ LOGIN_POLICY=./__tests__/testdata/policies/acceptAnything.json DID_KEY_JWK={"kty":"OKP","crv":"Ed25519","x":"cwa3dufHNLg8aQb2eEUqTyoM1cKQW3XnOkMkj_AAl5M","d":"me03qhLByT-NKrfXDeji-lpADSpVOKWoaMUzv5EyzKY"} +EXTERNAL_URL=http://example.com diff --git a/vclogin/__tests__/unit/pages/api/clientMetadata.test.ts b/vclogin/__tests__/unit/pages/api/clientMetadata.test.ts new file mode 100644 index 0000000..9244a9d --- /dev/null +++ b/vclogin/__tests__/unit/pages/api/clientMetadata.test.ts @@ -0,0 +1,40 @@ +/** + * Copyright 2024 Software Engineering for Business Information Systems (sebis) . + * SPDX-License-Identifier: MIT + */ + +import { describe, it, expect } from "vitest"; +import { createMocks } from "node-mocks-http"; +import handler from "@/api/clientMetadata"; +import type { NextApiRequest, NextApiResponse } from "next"; + +describe("/api/clientMetadata", () => { + const mockRequest = () => { + const { req, res } = createMocks({ + method: "GET", + url: "api/clientMetadata", + }); + return { req, res }; + }; + + it("returns 200 OK", async () => { + const { req, res } = mockRequest(); + + await handler(req, res); + + expect(res.statusCode).toBe(200); + }); + + it("returns valid JSON", async () => { + const { req, res } = mockRequest(); + + await handler(req, res); + + expect(res._isJSON()).toBe(true); + expect(res._getJSONData()).toEqual( + expect.objectContaining({ + client_name: "SSI-to-OIDC Bridge", + }), + ); + }); +}); diff --git a/vclogin/lib/getMetadata.ts b/vclogin/lib/getMetadata.ts index 530ad77..991ad08 100644 --- a/vclogin/lib/getMetadata.ts +++ b/vclogin/lib/getMetadata.ts @@ -43,7 +43,7 @@ export const getMetadata = (redirect_uris: string[]) => { ], subject_trust_frameworks_supported: ["ebsi"], id_token_types_supported: ["subject_signed_id_token"], - client_name: "VP Login Service", + client_name: "SSI-to-OIDC Bridge", request_uri_parameter_supported: true, request_parameter_supported: false, redirect_uris, diff --git a/vclogin/package-lock.json b/vclogin/package-lock.json index 1ded84c..183445a 100644 --- a/vclogin/package-lock.json +++ b/vclogin/package-lock.json @@ -47,6 +47,7 @@ "eslint": "8.38.0", "eslint-config-next": "13.3.0", "eslint-plugin-react-hooks": "^4.6.0", + "node-mocks-http": "^1.15.1", "postcss": "^8.4.39", "prettier": "^2.8.8", "swagger-ui": "^5.17.14", @@ -2615,10 +2616,11 @@ "dev": true }, "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -3217,6 +3219,20 @@ "node": ">=6.5" } }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", @@ -4448,6 +4464,19 @@ "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", "dev": true }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", @@ -4867,6 +4896,16 @@ "node": ">=0.10" } }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/detect-libc": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", @@ -6107,6 +6146,16 @@ "tslib": "^2.1.0" } }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -7714,6 +7763,16 @@ "node": ">= 0.6" } }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -7729,6 +7788,16 @@ "node": ">= 8" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", @@ -7743,6 +7812,19 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -7933,6 +8015,16 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/next": { "version": "14.2.4", "resolved": "https://registry.npmjs.org/next/-/next-14.2.4.tgz", @@ -8183,6 +8275,30 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/node-mocks-http": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.15.1.tgz", + "integrity": "sha512-X/GpUpNNiPDYUeUD183W8V4OW6OHYWI29w/QDyb+c/GzOfVEAlo6HjbW9++eXT2aV2lGg+uS+XqTD2q0pNREQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.21", + "@types/node": "*", + "accepts": "^1.3.7", + "content-disposition": "^0.5.3", + "depd": "^1.1.0", + "fresh": "^0.5.2", + "merge-descriptors": "^1.0.1", + "methods": "^1.1.2", + "mime": "^1.3.4", + "parseurl": "^1.3.3", + "range-parser": "^1.2.0", + "type-is": "^1.6.18" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -8515,6 +8631,16 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -9224,6 +9350,16 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", diff --git a/vclogin/package.json b/vclogin/package.json index 9b0160b..6167003 100644 --- a/vclogin/package.json +++ b/vclogin/package.json @@ -51,6 +51,7 @@ "eslint": "8.38.0", "eslint-config-next": "13.3.0", "eslint-plugin-react-hooks": "^4.6.0", + "node-mocks-http": "^1.15.1", "postcss": "^8.4.39", "prettier": "^2.8.8", "swagger-ui": "^5.17.14", diff --git a/vclogin/tsconfig.json b/vclogin/tsconfig.json index 2029343..3abb003 100644 --- a/vclogin/tsconfig.json +++ b/vclogin/tsconfig.json @@ -18,6 +18,7 @@ "paths": { "@/testdata/*": ["__tests__/testdata/*"], "@/lib/*": ["lib/*"], + "@/api/*": ["pages/api/*"], "@/config/*": ["config/*"], "@/types/*": ["types/*"], "@/pages/*": ["pages/*"],