diff --git a/README.md b/README.md index a6a1c05..8382e77 100644 --- a/README.md +++ b/README.md @@ -6,24 +6,21 @@ Policy Server implementation. To get the Policy Server up and running in a Docker container: - - - - ## ENV Example + ``` -AUTH_TYPE = "waltid" -WALTID_VERIFIER_URL="https://verifier.portal.walt.id" -OCEAN_NODE_URL="http://ocean-node-vm1.oceanenterprise.io:8000" -WALTID_SUCCESS_REDIRECT_URL="https://example.com/success?id=\$id" -WALTID_ERROR_REDIRECT_URL="https://example.com/error?id=\$id" -WALTID_VERIFY_RESPONSE_REDIRECT_URL="http://ocean-node-vm2.oceanenterprise.io:8100/verify/\$id" -WALTID_VERIFY_PRESENTATION_DEFINITION_URL="http://ocean-node-vm2.oceanenterprise.io:8100/pd/\$id" -DEFAULT_VP_POLICIES=["expired","signature","revoked-status-list","not-before"] -DEFAULT_VC_POLICIES=["expired","signature","revoked-status-list","not-before"] -ENABLE_LOGS="1" -MODE_PROXY="1" -MODE_PS="1" +AUTH_TYPE = waltid +WALTID_VERIFIER_URL=https://verifier.demo.walt.id +OCEAN_NODE_URL=http://ocean-node-vm1.oceanenterprise.io:8000 +WALTID_SUCCESS_REDIRECT_URL=https://example.com/success?id=$id +WALTID_ERROR_REDIRECT_URL=https://example.com/error?id=$id +WALTID_VERIFY_RESPONSE_REDIRECT_URL=http://ocean-node-vm2.oceanenterprise.io:8100/verify/$id +WALTID_VERIFY_PRESENTATION_DEFINITION_URL=http://ocean-node-vm2.oceanenterprise.io:8100/pd/$id +DEFAULT_VP_POLICIES=expired,signature,revoked-status-list,not-before +DEFAULT_VC_POLICIES=expired,signature,revoked-status-list,not-before +ENABLE_LOGS=1 +MODE_PROXY=1 +MODE_PS=1 ``` 1. Start the Docker container: @@ -31,6 +28,8 @@ MODE_PS="1" ```bash npm run start:docker + ``` + 2. Access the API Documentation [http://localhost:8000/api-docs](http://localhost:8000/api-docs) @@ -50,13 +49,14 @@ MODE_PS="1" - `validateDDO` - `passthrough` - ## 1) initiate ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example + ```json { "action": "initiate", @@ -70,9 +70,7 @@ MODE_PS="1" "presentationDefinitionUri": "" }, "ddo": { - "@context": [ - "https://www.w3.org/ns/credentials/v2" - ], + "@context": ["https://www.w3.org/ns/credentials/v2"], "id": "did:ope:1ec8435672854acf15ef3e61216900f314f8fae5e04e6b2fb0dc91c0579e0d02", "version": "5.0.0", "credentialSubject": { @@ -88,20 +86,14 @@ MODE_PS="1" "type": "UniversityDegree" } ], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], "type": "SSIpolicy" }, { - "values": [ - "*" - ], + "values": ["*"], "type": "address" } ], @@ -119,9 +111,7 @@ MODE_PS="1" "@direction": "", "@language": "" }, - "tags": [ - "test" - ], + "tags": ["test"], "author": "", "license": { "name": "https://github.com/MBadea17/testdata/blob/af26d4f968fdb6e1882c2a3cca16a1480ca44a9c/License%20Agreement.pdf", @@ -155,20 +145,14 @@ MODE_PS="1" "values": [ { "request_credentials": [], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], "type": "SSIpolicy" }, { - "values": [ - "0xd727fb9be39fa019d7c02fea19e54d688da3a662" - ], + "values": ["0xd727fb9be39fa019d7c02fea19e54d688da3a662"], "type": "address" } ], @@ -202,11 +186,7 @@ MODE_PS="1" "type": "VerifiableId" } ], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], @@ -237,11 +217,7 @@ MODE_PS="1" "values": [ { "request_credentials": [], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], @@ -251,9 +227,7 @@ MODE_PS="1" "match_deny": "any", "deny": [ { - "values": [ - "0x61db12d8b636cb49ea09eca58a893da9480e1f33" - ], + "values": ["0x61db12d8b636cb49ea09eca58a893da9480e1f33"], "type": "address" } ] @@ -324,9 +298,7 @@ MODE_PS="1" } }, "additionalDdos": [], - "type": [ - "VerifiableCredential" - ], + "type": ["VerifiableCredential"], "issuer": "did:jwk:eyJrdHkiOiJPS1AiLCJkIjoiUnBVOU5ONmdFbGtvMXpjYnR1VVRERlVXWEZCeks1Um9FZ3FRaVFHMWN4QSIsImNydiI6IkVkMjU1MTkiLCJraWQiOiI1TS1od19JbTZDalJDZ3NCVXhGX0R2aWxRRnhfdVU5RWpNcUpPbzdQOERnIiwieCI6IklaeXo1WVl6WkpJYWN3R21ockstYXdCa2ZJWmRqbUFWWTViVjFIbGNxYjgifQ", "proof": { "signature": "N2GQRLQbDUM7gLlUNweF-JjP9XS1uAWHWZy-8NLdlBdPJFrdvVkZk1z6UntVqATkCZU-l8MMQP_5DyMDzws3DA", @@ -408,33 +380,26 @@ MODE_PS="1" ] } } - ``` - ### Walt.Id Endpoint Example + **Endpoint**: `https://verifier.portal.walt.id/verify/` ### Walt.Id Params + **successRedirectUri**: `is an env variable, optional.` **StateId**: `Is generated by PolicyServer and represents the session id, included in response.` -```stateId: randomUUID()``` +`stateId: randomUUID()` -Policy Server will always add default VP and VC policies, if they are specified in ENV. (revoked-status-list is this case) +Policy Server will always add default VP and VC policies, if they are specified in ENV. (revoked-status-list is this case) ### Walt.Id Payload Example Generated by PolicyServer + ```json { - "vp_policies": [ - "expired", - "signature", - "revoked-status-list" - ], - "vc_policies": [ - "expired", - "signature", - "revoked-status-list" - ], + "vp_policies": ["expired", "signature", "revoked-status-list"], + "vc_policies": ["expired", "signature", "revoked-status-list"], "request_credentials": [ { "type": "VerifiableId", @@ -457,29 +422,30 @@ Policy Server will always add default VP and VC policies, if they are specified } ] } - ``` ### PolicyServer Response Example + ```json { "success": true, "message": "openid4vp://authorize?response_type=vp_token&client_id=https%3A%2F%2Fverifier.portal.walt.id%2Fopenid4vc%2Fverify&response_mode=direct_post&state=ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6&presentation_definition_uri=https%3A%2F%2Fverifier.portal.walt.id%2Fopenid4vc%2Fpd%2Fec64a21c-3d81-44f9-8b1d-099c1ec0c7b6&client_id_scheme=redirect_uri&client_metadata=%7B%22authorization_encrypted_response_alg%22%3A%22ECDH-ES%22%2C%22authorization_encrypted_response_enc%22%3A%22A256GCM%22%7D&nonce=a6a70049-c347-4046-89db-7090b43c858f&response_uri=https%3A%2F%2Fverifier.portal.walt.id%2Fopenid4vc%2Fverify%2Fec64a21c-3d81-44f9-8b1d-099c1ec0c7b6", "httpStatus": 200 } - ``` + In this case `state=ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6` represents Session Id. -Also, Policy Server replace default `response_uri` by `WALTID_VERIFY_RESPONSE_REDIRECT_URL` env variable and `presentation_definition_uri` by `WALTID_VERIFY_PRESENTATION_DEFINITION_URL` env variable, +Also, Policy Server replace default `response_uri` by `WALTID_VERIFY_RESPONSE_REDIRECT_URL` env variable and `presentation_definition_uri` by `WALTID_VERIFY_PRESENTATION_DEFINITION_URL` env variable, ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node-vm2.oceanenterprise.io:8100/pd/$id` where $id represents the session id. - ## 2) presentationRequest ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example + ```json { "action": "presentationRequest", @@ -491,22 +457,23 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node ``` ### Walt.Id Endpoint Example + **Endpoint**: `https://verifier.portal.walt.id/openid4vc/verify/{id}` **In this example**: `"https://verifier.portal.walt.id/openid4vc/verify/ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6"`. ### PolicyServer Response Example + ```json { "success": true, "message": { "successRedirectUri": "empty or the process.env.WALTID_SUCCESS_REDIRECT_URL", "sessionId": "ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6", - "errorRedirectUri": "empty or the error message if the process.env.WALTID_ERROR_REDIRECT_URL not specified", + "errorRedirectUri": "empty or the error message if the process.env.WALTID_ERROR_REDIRECT_URL not specified" }, "httpStatus": 200 } - ``` **success** is true, if **process.env.WALTID_SUCCESS_REDIRECT_URL** is null, or it is the same, as **redirect_uri** from response. @@ -514,22 +481,26 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node ## 3) checkSessionId ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example + ```json { "action": "checkSessionId", - "sessionId": "ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6" + "sessionId": "ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6" } ``` ### Walt.Id Endpoint Example + **Endpoint**: `https://verifier.portal.walt.id/openid4vc/session/{id}` **In this example**: `"https://verifier.portal.walt.id/openid4vc/session/ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6"`. ### PolicyServer Response Example + ```json { "success": true, @@ -541,26 +512,29 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node ``` - ## 4) getPD ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example + ```json { "action": "getPD", - "sessionId": "ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6" + "sessionId": "ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6" } ``` ### Walt.Id Endpoint Example + **Endpoint**: `https://verifier.portal.walt.id/openid4vc/pd/{id}` **In this example**: `"https://verifier.portal.walt.id/openid4vc/pd/ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6"`. ### PolicyServer Response Example + ```json { "success": true, @@ -577,9 +551,11 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node ## 5) download ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example + ```json { "action": "download", @@ -593,9 +569,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "presentationDefinitionUri": "" }, "ddo": { - "@context": [ - "https://www.w3.org/ns/credentials/v2" - ], + "@context": ["https://www.w3.org/ns/credentials/v2"], "id": "did:ope:1ec8435672854acf15ef3e61216900f314f8fae5e04e6b2fb0dc91c0579e0d02", "version": "5.0.0", "credentialSubject": { @@ -611,20 +585,14 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "type": "UniversityDegree" } ], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], "type": "SSIpolicy" }, { - "values": [ - "*" - ], + "values": ["*"], "type": "address" } ], @@ -642,9 +610,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "@direction": "", "@language": "" }, - "tags": [ - "test" - ], + "tags": ["test"], "author": "", "license": { "name": "https://github.com/MBadea17/testdata/blob/af26d4f968fdb6e1882c2a3cca16a1480ca44a9c/License%20Agreement.pdf", @@ -678,20 +644,14 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "values": [ { "request_credentials": [], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], "type": "SSIpolicy" }, { - "values": [ - "0xd727fb9be39fa019d7c02fea19e54d688da3a662" - ], + "values": ["0xd727fb9be39fa019d7c02fea19e54d688da3a662"], "type": "address" } ], @@ -725,11 +685,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "type": "VerifiableId" } ], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], @@ -760,11 +716,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "values": [ { "request_credentials": [], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], @@ -774,9 +726,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "match_deny": "any", "deny": [ { - "values": [ - "0x61db12d8b636cb49ea09eca58a893da9480e1f33" - ], + "values": ["0x61db12d8b636cb49ea09eca58a893da9480e1f33"], "type": "address" } ] @@ -847,9 +797,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node } }, "additionalDdos": [], - "type": [ - "VerifiableCredential" - ], + "type": ["VerifiableCredential"], "issuer": "did:jwk:eyJrdHkiOiJPS1AiLCJkIjoiUnBVOU5ONmdFbGtvMXpjYnR1VVRERlVXWEZCeks1Um9FZ3FRaVFHMWN4QSIsImNydiI6IkVkMjU1MTkiLCJraWQiOiI1TS1od19JbTZDalJDZ3NCVXhGX0R2aWxRRnhfdVU5RWpNcUpPbzdQOERnIiwieCI6IklaeXo1WVl6WkpJYWN3R21ockstYXdCa2ZJWmRqbUFWWTViVjFIbGNxYjgifQ", "proof": { "signature": "N2GQRLQbDUM7gLlUNweF-JjP9XS1uAWHWZy-8NLdlBdPJFrdvVkZk1z6UntVqATkCZU-l8MMQP_5DyMDzws3DA", @@ -934,11 +882,13 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node ``` ### Walt.Id Endpoint Example + **Endpoint**: `https://verifier.portal.walt.id/session/{id}` **In this example**: `"https://verifier.portal.walt.id/session/ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6"`. ### PolicyServer Response Example + ```json { "success": true, @@ -952,12 +902,14 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node **success** is true, if **verificationResult** property in presentation state object is also true. -## 6) startCompute +## 6) startCompute ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example + ```json { "action": "startCompute", @@ -965,18 +917,18 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "serviceId": "ff294c2e2c7d01bd5f9701abc117737917bb1f91044ba6b2d0903fc806db0d65", "consumerAddress": "0xd727fb9be39fa019d7c02fea19e54d688da3a662", "policyServer": [ - { + { "documentId": "did1", - "serviceId": "ff294c2e2c7d01bd5f9701abc117737917bb1f91044ba6b2d0903fc806db0d65", + "serviceId": "ff294c2e2c7d01bd5f9701abc117737917bb1f91044ba6b2d0903fc806db0d65", "successRedirectUri": "", "sessionId": "", "errorRedirectUri": "", "responseRedirectUri": "", "presentationDefinitionUri": "" }, - { + { "documentId": "did2", - "serviceId": "service2", + "serviceId": "service2", "successRedirectUri": "", "sessionId": "", "errorRedirectUri": "", @@ -985,9 +937,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node } ], "ddo": { - "@context": [ - "https://www.w3.org/ns/credentials/v2" - ], + "@context": ["https://www.w3.org/ns/credentials/v2"], "id": "did:ope:1ec8435672854acf15ef3e61216900f314f8fae5e04e6b2fb0dc91c0579e0d02", "version": "5.0.0", "credentialSubject": { @@ -1003,20 +953,14 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "type": "UniversityDegree" } ], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], "type": "SSIpolicy" }, { - "values": [ - "*" - ], + "values": ["*"], "type": "address" } ], @@ -1034,9 +978,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "@direction": "", "@language": "" }, - "tags": [ - "test" - ], + "tags": ["test"], "author": "", "license": { "name": "https://github.com/MBadea17/testdata/blob/af26d4f968fdb6e1882c2a3cca16a1480ca44a9c/License%20Agreement.pdf", @@ -1070,20 +1012,14 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "values": [ { "request_credentials": [], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], "type": "SSIpolicy" }, { - "values": [ - "0xd727fb9be39fa019d7c02fea19e54d688da3a662" - ], + "values": ["0xd727fb9be39fa019d7c02fea19e54d688da3a662"], "type": "address" } ], @@ -1117,11 +1053,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "type": "VerifiableId" } ], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], @@ -1152,11 +1084,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "values": [ { "request_credentials": [], - "vc_policies": [ - "signature", - "not-before", - "revoked-status-list" - ], + "vc_policies": ["signature", "not-before", "revoked-status-list"], "vp_policies": [] } ], @@ -1166,9 +1094,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "match_deny": "any", "deny": [ { - "values": [ - "0x61db12d8b636cb49ea09eca58a893da9480e1f33" - ], + "values": ["0x61db12d8b636cb49ea09eca58a893da9480e1f33"], "type": "address" } ] @@ -1239,9 +1165,7 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node } }, "additionalDdos": [], - "type": [ - "VerifiableCredential" - ], + "type": ["VerifiableCredential"], "issuer": "did:jwk:eyJrdHkiOiJPS1AiLCJkIjoiUnBVOU5ONmdFbGtvMXpjYnR1VVRERlVXWEZCeks1Um9FZ3FRaVFHMWN4QSIsImNydiI6IkVkMjU1MTkiLCJraWQiOiI1TS1od19JbTZDalJDZ3NCVXhGX0R2aWxRRnhfdVU5RWpNcUpPbzdQOERnIiwieCI6IklaeXo1WVl6WkpJYWN3R21ockstYXdCa2ZJWmRqbUFWWTViVjFIbGNxYjgifQ", "proof": { "signature": "N2GQRLQbDUM7gLlUNweF-JjP9XS1uAWHWZy-8NLdlBdPJFrdvVkZk1z6UntVqATkCZU-l8MMQP_5DyMDzws3DA", @@ -1326,11 +1250,13 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node ``` ### Walt.Id Endpoint Example + **Endpoint**: `https://verifier.portal.walt.id/session/{id}` **In this example**: `"https://verifier.portal.walt.id/session/ec64a21c-3d81-44f9-8b1d-099c1ec0c7b6"`. ### PolicyServer Response Example + ```json { "success": true, @@ -1344,33 +1270,30 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node **success** is true, if **verificationResult** property in presentation state object is also true. - ## 7 encrypt ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example ```json - { "action": "encrypt", "policyServer": {} } - ``` - ## 8 decrypt ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example ```json - { "action": "decrypt", "decrypterAddress": "0x123", @@ -1379,79 +1302,72 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "dataNftAddress": "0x123", "policyServer": {} } - ``` - ## 9 newDDO ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example ```json - - { - "action":"newDDO", +{ + "action": "newDDO", "rawDDO": {}, "chainId": 1, "txId": "0x123", "eventRaw": "raw event data" } - ``` - ## 10 updateDDO ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example ```json - - { - "action":"updateDDO", +{ + "action": "updateDDO", "rawDDO": {}, "chainId": 1, "txId": "0x123", "eventRaw": "raw event data" } - ``` - ## 11 validate DDO ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example ```json - - { - "action":"updateDDO", +{ + "action": "updateDDO", "rawDDO": {}, "chainId": 1, "txId": "0x123", "eventRaw": "raw event data" } - ``` ## 12 passthrough ### PolicyServer Endpoint Example + **Endpoint**: `http://localhost:3000/` ### PolicyServer Expected Payload Example ```json - - { +{ "action": "passthrough", "url": "/openid4vc/verify", "httpMethod": "POST", @@ -1462,86 +1378,52 @@ ex. `https://verifier.portal.walt.id/openid4vc/verify/$id`and `http://ocean-node "type": "OpenBadgeCredential" } ] - }, + } } - ``` ### PolicyServer Response Example -```json +```json { "success": true, "message": "openid4vp://authorize?response_type=vp_token&client_id=https%3A%2F%2Fverifier.portal.walt.id%2Fopenid4vc%2Fverify&response_mode=direct_post&state=yidllNybpwZe&presentation_definition_uri=https%3A%2F%2Fverifier.portal.walt.id%2Fopenid4vc%2Fpd%2FyidllNybpwZe&client_id_scheme=redirect_uri&client_metadata=%7B%22authorization_encrypted_response_alg%22%3A%22ECDH-ES%22%2C%22authorization_encrypted_response_enc%22%3A%22A256GCM%22%7D&nonce=a0d5ba73-e27d-45da-9780-8b05428c3a61&response_uri=https%3A%2F%2Fverifier.portal.walt.id%2Fopenid4vc%2Fverify%2FyidllNybpwZe", "httpStatus": 200 } +``` + +## Deploy docker image to server using .sh + +### Required .env file example + +``` +# --- .env file --- +IMAGE_NAME=ocean-policy-server +CONTAINER_NAME=ocean-policy-server +SERVER_USER=ubuntu +SERVER_IP= +SSH_KEY= # Example: /home/your_user/.ssh/id_rsa +REMOTE_PATH= # Example: /home/ubuntu/ +LOCAL_PORT=8100 +CONTAINER_PORT=8100 + +PORT=8100 +AUTH_TYPE=waltid +OCEAN_NODE_URL=http://ocean-node-vm1.oceanenterprise.io:8000 +WALTID_VERIFIER_URL=https://verifier.demo.walt.id +WALTID_SUCCESS_REDIRECT_URL=https://example.com/success?id=$id +WALTID_ERROR_REDIRECT_URL=https://example.com/error?id=$id +ENABLE_LOGS=1 +MODE_PROXY=1 +MODE_PS=1 +WALTID_VERIFY_RESPONSE_REDIRECT_URL=http://ocean-node-vm2.oceanenterprise.io:8100/verify/$id +WALTID_VERIFY_PRESENTATION_DEFINITION_URL=http://ocean-node-vm2.oceanenterprise.io:8100/pd/$id +DEFAULT_VP_POLICIES=expired,signature,revoked-status-list,not-before +DEFAULT_VC_POLICIES=expired,signature,revoked-status-list,not-before +``` + +### Run command in bash cli ``` -## Deploy .sh example +npm run deploy:docker ``` -#!/bin/bash - -IMAGE_NAME="ocean-policy-server" -CONTAINER_NAME="ocean-policy-server" -SERVER_USER="ubuntu" -SERVER_IP="" -#Route to ssh key -SSH_KEY="" -#Path where to store image -REMOTE_PATH="" -LOCAL_PORT=8100 -CONTAINER_PORT=8100 - -echo "Building docker image" -docker build -t $IMAGE_NAME:latest . - -echo "Exporting docker build image..." -docker save -o ${IMAGE_NAME}.tar $IMAGE_NAME:latest - -echo "Ziping docker image..." -gzip -f ${IMAGE_NAME}.tar - -echo "Trasmiting to server..." -scp -i $SSH_KEY ${IMAGE_NAME}.tar.gz $SERVER_USER@$SERVER_IP:$REMOTE_PATH - -echo "Runing commands on server..." -ssh -i $SSH_KEY $SERVER_USER@$SERVER_IP << EOF - echo "unzip tar.gz..." - gunzip -f ${REMOTE_PATH}/${IMAGE_NAME}.tar.gz - - echo "Importing docker..." - docker load -i ${REMOTE_PATH}/${IMAGE_NAME}.tar - - echo "Deleting old container..." - docker stop $CONTAINER_NAME || true - docker rm $CONTAINER_NAME || true - - echo "Starting new container..." - docker run -d \ - --name "$CONTAINER_NAME" \ - -p "$LOCAL_PORT:$CONTAINER_PORT" \ - -e PORT="$LOCAL_PORT" \ - -e AUTH_TYPE='waltid' \ - -e OCEAN_NODE_URL='http://ocean-node-vm1.oceanenterprise.io:8000' \ - -e WALTID_VERIFIER_URL='https://verifier.demo.walt.id' \ - -e WALTID_SUCCESS_REDIRECT_URL='https://example.com/success?id=\$id' \ - -e WALTID_ERROR_REDIRECT_URL='https://example.com/error?id=\$id' \ - -e ENABLE_LOGS='1' \ - -e MODE_PROXY='1' \ - -e MODE_PS='1' \ - -e WALTID_VERIFY_RESPONSE_REDIRECT_URL='http://ocean-node-vm2.oceanenterprise.io:8100/verify/\$id' \ - -e WALTID_VERIFY_PRESENTATION_DEFINITION_URL='http://ocean-node-vm2.oceanenterprise.io:8100/pd/\$id' \ - -e DEFAULT_VP_POLICIES='["expired","signature","revoked-status-list","not-before"]' \ - -e DEFAULT_VC_POLICIES='["expired","signature","revoked-status-list","not-before"]' \ - "$IMAGE_NAME:latest" - - - echo "Deleting temp data..." - rm -f ${REMOTE_PATH}/${IMAGE_NAME}.tar - - echo "Container is up!" -EOF - -echo "Done!" - -``` \ No newline at end of file diff --git a/package.json b/package.json index 0b7bb9a..bd8e94a 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "clean": "if [ -d ./dist ]; then find ./dist -mindepth 1 -delete; fi", "start": "node --trace-warnings --experimental-specifier-resolution=node dist/index.js", "start:docker": "./scripts/docker_build_run.sh", + "deploy:docker": "./scripts/deploy_docker.sh", "lint": "eslint --ignore-pattern .gitignore . && npm run type-check", "lint:fix": "eslint --ignore-pattern .gitignore . --fix", "format": "prettier --parser typescript --ignore-path .gitignore --write '**/*.{js,jsx,ts,tsx}'", diff --git a/scripts/deploy_docker.sh b/scripts/deploy_docker.sh new file mode 100644 index 0000000..0b49328 --- /dev/null +++ b/scripts/deploy_docker.sh @@ -0,0 +1,87 @@ +#!/bin/bash +set -euo pipefail + +# Loading envs +ENV_FILE="$(dirname "$0")/../.env" + +load_env() { + if [[ ! -f "$ENV_FILE" ]]; then + echo "ERROR: Environment file not found at $ENV_FILE. Aborting." + exit 1 + fi + echo "Loading variables from $ENV_FILE into Bash environment..." + while IFS='=' read -r key value; do + [[ -z "$key" || "$key" =~ ^# ]] && continue + value="${value%\"}"; value="${value#\"}" + export "$key"="$value" + done < "$ENV_FILE" +} +load_env + +: "${SSH_PORT:=22}" +echo "Using SSH Port: $SSH_PORT" + + +# Create local image +TAR_NAME="${IMAGE_NAME}.tar" +GZ_NAME="${TAR_NAME}.gz" + +echo "Building docker image: $IMAGE_NAME" +docker build -t "${IMAGE_NAME}:latest" "$(dirname "$0")/.." + +echo "Exporting docker build image..." +docker save -o "$TAR_NAME" "${IMAGE_NAME}:latest" + +echo "Zipping docker image..." +gzip -f "$TAR_NAME" + + +# Server transmitting +echo "Transmitting image to server ${SERVER_USER}@${SERVER_IP}:${SSH_PORT}..." +scp -i "$SSH_KEY" -P "$SSH_PORT" "$GZ_NAME" "$ENV_FILE" "${SERVER_USER}@${SERVER_IP}:${REMOTE_PATH}" + +# Server running +echo "Running commands on server..." +ssh -i "$SSH_KEY" -p "$SSH_PORT" \ + "${SERVER_USER}@${SERVER_IP}" \ + "REMOTE_PATH='${REMOTE_PATH}' GZ_NAME='${GZ_NAME}' TAR_NAME='${TAR_NAME}' CONTAINER_NAME='${CONTAINER_NAME}' IMAGE_NAME='${IMAGE_NAME}' LOCAL_PORT='${LOCAL_PORT}' CONTAINER_PORT='${CONTAINER_PORT}' bash -s" <<'EOF' +set -euo pipefail + +REMOTE_GZ_PATH="${REMOTE_PATH}/${GZ_NAME}" +REMOTE_TAR_PATH="${REMOTE_PATH}/${TAR_NAME}" +REMOTE_ENV_PATH="${REMOTE_PATH}/.env" + +echo "Unzip tar.gz..." +gunzip -f "$REMOTE_GZ_PATH" + +echo "Importing docker image..." +docker load -i "$REMOTE_TAR_PATH" + +echo "Deleting old container..." +docker stop "$CONTAINER_NAME" 2>/dev/null || true +docker rm "$CONTAINER_NAME" 2>/dev/null || true + +echo "Starting new container with --env-file..." +docker run -d \ + --name "$CONTAINER_NAME" \ + -p "$LOCAL_PORT:$CONTAINER_PORT" \ + --env-file "$REMOTE_ENV_PATH" \ + "$IMAGE_NAME:latest" + +echo "Checking container status..." +if docker ps -q -f "name=^/${CONTAINER_NAME}$" >/dev/null; then + echo "Successfully started container $CONTAINER_NAME." +else + echo "ERROR: Failed to start container $CONTAINER_NAME." + docker logs "$CONTAINER_NAME" || true +fi + +echo "Deleting temporary data on server..." +rm -f "$REMOTE_TAR_PATH" "$REMOTE_ENV_PATH" +EOF + +# 5)Local clear +echo "Deleting temporary data locally..." +rm -f "$GZ_NAME" + +echo "Done! Container $CONTAINER_NAME is running on $SERVER_IP:$LOCAL_PORT." diff --git a/scripts/docker_build_run.sh b/scripts/docker_build_run.sh index 6898c8c..bad4630 100755 --- a/scripts/docker_build_run.sh +++ b/scripts/docker_build_run.sh @@ -1,22 +1,40 @@ -#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail -# Image and container name IMAGE_NAME="policy-server" CONTAINER_NAME="policy-server" -PORT=8000 -# Build the image -echo "Building Docker image with the name $IMAGE_NAME..." -docker build -t $IMAGE_NAME:latest . +LOCAL_PORT=8000 +CONTAINER_PORT=8000 +ENV_FILE="$(dirname "$0")/../.env" -# Check if a container with the same name exists -if [ $(docker ps -a -q -f name=$CONTAINER_NAME) ]; then - echo "A container with the name $CONTAINER_NAME already exists. Removing it..." - docker rm -f $CONTAINER_NAME +echo "Building Docker image: $IMAGE_NAME" +docker build -t "$IMAGE_NAME:latest" "$(dirname "$0")/.." + +if docker ps -a -q -f "name=^/${CONTAINER_NAME}$" >/dev/null; then + echo "Removing existing container: $CONTAINER_NAME" + docker rm -f "$CONTAINER_NAME" +fi + +if [[ -f "$ENV_FILE" ]]; then + echo "Loading environment variables from $ENV_FILE and running container in detached mode (-d)" + docker run -d \ + --name "$CONTAINER_NAME" \ + -p "$LOCAL_PORT:$CONTAINER_PORT" \ + --env-file "$ENV_FILE" \ + "$IMAGE_NAME:latest" +else + echo "WARNING: .env file not found at $ENV_FILE, starting without environment variables" + docker run -d \ + --name "$CONTAINER_NAME" \ + -p "$LOCAL_PORT:$CONTAINER_PORT" \ + "$IMAGE_NAME:latest" fi -# Run the container -echo "Starting container $CONTAINER_NAME on port $PORT..." -docker run --name $CONTAINER_NAME -p $PORT:$PORT $IMAGE_NAME:latest +echo "Container $CONTAINER_NAME is running in detached mode on port $LOCAL_PORT." -echo "Container $CONTAINER_NAME is running on port $PORT." +if docker ps -q -f "name=^/${CONTAINER_NAME}$" >/dev/null; then + echo "Successfully started container $CONTAINER_NAME." +else + echo "ERROR: Failed to start container $CONTAINER_NAME." +fi \ No newline at end of file diff --git a/src/handlers/waltIdPolicyHandler.ts b/src/handlers/waltIdPolicyHandler.ts index c3bf071..e188272 100644 --- a/src/handlers/waltIdPolicyHandler.ts +++ b/src/handlers/waltIdPolicyHandler.ts @@ -163,7 +163,7 @@ export class WaltIdPolicyHandler extends PolicyHandler { // )) const responseData = { - redirectUri: response.data, + redirectUri: response.data.redirect_uri, sessionId: requestPayload.sessionId } @@ -721,7 +721,34 @@ export class WaltIdPolicyHandler extends PolicyHandler { .filter((p) => p !== undefined) } - const normalizePolicyNames = (arr: any[]): string[] => + const parseArgs = (args: any) => { + if (typeof args !== 'string') return args + try { + return JSON.parse(args) + } catch { + return args + } + } + + const normalizeVpPolicyNames = (arr: any[]): any[] => + arr + .map((p) => { + if (typeof p === 'string') { + return { policy: p } + } + + if (typeof p === 'object' && p.policy) { + return { + policy: p.policy, + ...(p.args !== undefined ? { args: parseArgs(p.args) } : {}) + } + } + + return null + }) + .filter(Boolean) + + const normalizeVcPolicyNames = (arr: any[]): string[] => arr .map((p) => typeof p === 'string' @@ -732,46 +759,30 @@ export class WaltIdPolicyHandler extends PolicyHandler { ) .filter((p): p is string => !!p) - const vp_policies = new Set() + const vp_policies: any[] = [] const vc_policies = new Set() - let envvp_policies: any[] = [] - let envvc_policies: any[] = [] - try { - envvp_policies = process.env.DEFAULT_VP_POLICIES - ? JSON.parse(process.env.DEFAULT_VP_POLICIES) - : [] - } catch (e) { - console.error('Failed to parse DEFAULT_VP_POLICIES', e) - logError(e) - } - try { - envvc_policies = process.env.DEFAULT_VC_POLICIES - ? JSON.parse(process.env.DEFAULT_VC_POLICIES) - : [] - } catch (e) { - console.error('Failed to parse DEFAULT_VC_POLICIES', e) - logError(e) - } + const envvp_policies: string[] = this.parseEnvArray(process.env.DEFAULT_VP_POLICIES) + const envvc_policies: string[] = this.parseEnvArray(process.env.DEFAULT_VC_POLICIES) - normalizePolicyNames(envvp_policies).forEach((pol) => vp_policies.add(pol)) - normalizePolicyNames(envvc_policies).forEach((pol) => vc_policies.add(pol)) + normalizeVpPolicyNames(envvp_policies).forEach((pol) => vp_policies.push(pol)) + normalizeVcPolicyNames(envvc_policies).forEach((pol) => vc_policies.add(pol)) const request_credentialsMap = new Map() combinedCredentials.forEach((entry: any) => { if (entry?.vp_policies) { - ;(Array.isArray(entry.vp_policies) + const vpArr = Array.isArray(entry.vp_policies) ? entry.vp_policies : [entry.vp_policies] - ).forEach((policy: any) => { - if (typeof policy === 'string') vp_policies.add(policy) - else if ( - policy && - typeof policy === 'object' && - typeof policy.policy === 'string' - ) { - vp_policies.add(policy.policy) + + vpArr.forEach((policy: any) => { + if (typeof policy === 'string') { + vp_policies.push({ policy }) + } else if (typeof policy === 'object' && typeof policy.policy === 'string') { + const obj: any = { policy: policy.policy } + if (policy.args !== undefined) obj.args = parseArgs(policy.args) + vp_policies.push(obj) } }) } @@ -819,6 +830,15 @@ export class WaltIdPolicyHandler extends PolicyHandler { } } + private parseEnvArray(envVar?: string): string[] { + if (!envVar) return [] + try { + return JSON.parse(envVar) + } catch { + return envVar.split(',').map((s) => s.trim()) + } + } + private verifyWeb3Address(requestPayload: any): { success: boolean message?: string diff --git a/src/index.ts b/src/index.ts index e998b93..5933a11 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,8 @@ import { handleVerifyPresentationRequest } from './utils/verifyPresentationRequest.js' import { downloadLogs } from './utils/logger.js' +import dotenv from 'dotenv' +dotenv.config() const app = express() const authType = process.env.AUTH_TYPE || 'waltid' async function handlePolicyRequest( diff --git a/src/test/.env.test b/src/test/.env.test index 388cd05..5930126 100644 --- a/src/test/.env.test +++ b/src/test/.env.test @@ -1,12 +1,12 @@ -AUTH_TYPE=waltid -WALTID_VERIFIER_URL=https://verifier.portal.test.waltid.cloud +AUTH_TYPE = waltid +WALTID_VERIFIER_URL=https://verifier.demo.walt.id OCEAN_NODE_URL=http://ocean-node-vm1.oceanenterprise.io:8000 WALTID_SUCCESS_REDIRECT_URL=https://example.com/success?id=$id WALTID_ERROR_REDIRECT_URL=https://example.com/error?id=$id WALTID_VERIFY_RESPONSE_REDIRECT_URL=http://ocean-node-vm2.oceanenterprise.io:8100/verify/$id WALTID_VERIFY_PRESENTATION_DEFINITION_URL=http://ocean-node-vm2.oceanenterprise.io:8100/pd/$id -DEFAULT_VP_POLICIES=["expired","signature","revoked-status-list","not-before"] -DEFAULT_VC_POLICIES=["expired","signature","revoked-status-list","not-before"] +DEFAULT_VP_POLICIES=expired,signature,revoked-status-list,not-before +DEFAULT_VC_POLICIES=expired,signature,revoked-status-list,not-before ENABLE_LOGS=1 MODE_PROXY=1 MODE_PS=1 \ No newline at end of file