{ "info": { "_postman_id": "85f81550-bf06-4933-9c9f-5dafdf71929d", "name": "Credentials Status Update Tutorial", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [ { "name": "Get Access Token", "event": [ { "listen": "test", "script": { "exec": [ "// Token requests are expected to return a `200 Success` response code. Any", "// other response code should trigger a failure.", "pm.test(\"must return `200 Success` status\", function() {", " pm.response.to.have.status(200);", "});", "", "// The response should include an `access_token` value - this will be presented", "// to authenticated API endpoints in the `Authentication` header (see the last", "// testing code block for details on how this is persisted).", "pm.test(\"response body must include non-empty access_token\", function () {", " const { access_token } = pm.response.json()", " pm.expect(access_token).to.be.a('string').that.is.not.empty;", "});", "", "// The type of `access_token` returned by the token request is expected to be", "// `Bearer`.", "pm.test(\"response body must represent `Bearer` token\", function() {", " const { token_type } = pm.response.json()", " pm.expect(token_type).to.equal(\"Bearer\");", "});", "", "// The returned data includes an `expires_in` field that indicates time until", "// token expiration. Validate that this value is a whole number greater than", "// zero, as anything less than or equal to zero means that the `access_token`", "// is already expired.", "pm.test(\"returned token must expire in the future\", function() {", " const { expires_in } = pm.response.json()", " pm.expect(expires_in).to.be.above(0);", "});", "", "// The returned `access_token` value is persisted as a Postman collection", "// variable that can be accessed by other requests in the collection by calling", "// `pm.collectionVariables.get(\"access_token\")`.", "pm.test(\"`access_token` persisted to collectionVariables\", function() {", " const { access_token } = pm.response.json()", " pm.collectionVariables.set(\"access_token\", access_token);", "});" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [], "body": { "mode": "urlencoded", "urlencoded": [ { "key": "audience", "value": "{{TOKEN_AUDIENCE}}", "type": "text" }, { "key": "client_id", "value": "{{CLIENT_ID}}", "type": "text" }, { "key": "client_secret", "value": "{{CLIENT_SECRET}}", "type": "text" }, { "key": "grant_type", "value": "client_credentials", "type": "text" }, { "key": "scope", "value": "{{CLIENT_SCOPE}}", "type": "text" } ] }, "url": { "raw": "{{TOKEN_ENDPOINT}}", "host": [ "{{TOKEN_ENDPOINT}}" ] } }, "response": [] }, { "name": "Get Organization DIDs", "event": [ { "listen": "test", "script": { "exec": [ "// This endpoint is authenticated. This test will not prevent the request from", "// running when the `access_token` collection variable is missing, but it will", "// give an indication of why the request failed in that scenario.", "pm.test(\"`access_token` collection variable must be set\", function () {", " const access_token = pm.collectionVariables.get(\"access_token\");", " pm.expect(access_token).to.be.a('string').that.is.not.empty;", "});", "", "pm.test(\"Status code is 200\", function () {", " pm.response.to.have.status(200);", "});", "", "pm.test(\"must include valid JSON response body\", function() {", " pm.response.json(); // will throw on parse failure", "});", "", "// The response JSON must include a didDocument property that contains the", "// resolved DID document.", "pm.test(\"didDocument must be present in response body\", function() {", " const jsonData = pm.response.json();", " pm.expect(jsonData).to.have.property('didDocument');", "});", "", "// If a verificationMethod property is present, the controller property must", "// match the didDocument.id property.", "pm.test(\"verification method controller must match did subject\", function() {", " const { didDocument } = pm.response.json();", " const vm = didDocument.verificationMethod || [];", " vm.forEach((m) => pm.expect(m.controller).to.equal(didDocument.id));", "});", "", "// The value of didDocument.id is persisted as a Postman collection variable", "// that can be accessed by other requests in the collection by calling", "// pm.collectionVariables.get(\"credential_issuer_id\").", "pm.test(\"`credential_issuer_id` persisted to collectionVariables\", function() {", " const { didDocument } = pm.response.json();", " pm.collectionVariables.set(\"credential_issuer_id\", didDocument.id);", "});" ], "type": "text/javascript" } } ], "protocolProfileBehavior": { "disabledSystemHeaders": {} }, "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{access_token}}", "type": "string" } ] }, "method": "GET", "header": [ { "key": "Accept", "value": "application/json", "type": "text" } ], "url": { "raw": "{{API_BASE_URL}}/identifiers/{{ORGANIZATION_DID_WEB}}", "host": [ "{{API_BASE_URL}}" ], "path": [ "identifiers", "{{ORGANIZATION_DID_WEB}}" ] } }, "response": [] }, { "name": "Issue Credential", "event": [ { "listen": "test", "script": { "exec": [ "pm.test(\"`access_token` collection variable must be set\", function () {", " pm.expect(pm.collectionVariables.get(\"access_token\")).to.not.be.undefined;", "});", "", "pm.test(\"`credential_issuer_id` collection variable must be set\", function () {", " pm.expect(pm.collectionVariables.get(\"credential_issuer_id\")).to.not.be.undefined;", "});", "", "pm.test(\"must return `201 Created` status\", function () {", " pm.response.to.have.status(201);", "});", "", "// Verifiable credential must be made available to later requests", "pm.test(\"`verifiable_credential` persisted to collectionVariables\", function() {", " const {verifiableCredential} = pm.response.json();", " pm.collectionVariables.set(\"verifiable_credential\", JSON.stringify(verifiableCredential));", "});" ], "type": "text/javascript" } }, { "listen": "prerequest", "script": { "exec": [ "" ], "type": "text/javascript" } } ], "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{access_token}}", "type": "string" } ] }, "method": "POST", "header": [ { "key": "Accept", "value": "application/vc+ld+json", "type": "text" } ], "body": { "mode": "raw", "raw": "{\n \"credential\": {\n \"@context\": [\n \"https://www.w3.org/2018/credentials/v1\",\n \"https://w3id.org/vc-revocation-list-2020/v1\"\n ],\n \"id\": \"urn:uuid:{{$randomUUID}}\",\n \"type\": [\n \"VerifiableCredential\"\n ],\n \"issuer\": \"{{credential_issuer_id}}\",\n \"issuanceDate\": \"{{$isoTimestamp}}\",\n \"credentialSubject\": {\n \"id\": \"did:example:123\"\n }\n },\n \"options\": {\n \"type\": \"Ed25519Signature2018\",\n \"created\": \"{{$isoTimestamp}}\",\n \"credentialStatus\": {\n \"type\": \"StatusList2021Entry\"\n }\n }\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{API_BASE_URL}}/credentials/issue", "host": [ "{{API_BASE_URL}}" ], "path": [ "credentials", "issue" ] } }, "response": [] }, { "name": "Verify Credential", "event": [ { "listen": "test", "script": { "exec": [ "// The `/credentials/verify` endpoint is authenticated. This test will not", "// prevent the request from running when the `access_token` collection variable", "// is missing, but it will give an indication of why the request failed in that", "// scenario.", "pm.test(\"`access_token` collection variable must be set\", function () {", " pm.expect(pm.collectionVariables.get(\"access_token\")).to.not.be.undefined;", "});", "", "// The `verifiable_credential` from the \"Credentials Issue\" request is used to", "// populate part of the request body. If this collection variable is missing,", "// the request will not be prevented, but this test will raise an error that", "// will help to identify the problem.", "pm.test(\"`verifiable_credential` collection variable must be set\", function () {", " pm.expect(pm.collectionVariables.get(\"verifiable_credential\")).to.not.be.undefined;", "});", "", "// The expected response code for a \"Credentials Verify\" request is", "// `200 Success`.", "pm.test(\"must return `200 Success` status\", function () {", " pm.response.to.have.status(200);", "});", "", "// The verification should succeed.", "pm.test(\"verification should be successful\", function() {", " const { verified } = pm.response.json()", " pm.expect(verified).to.be.true;", "});" ], "type": "text/javascript" } } ], "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{access_token}}", "type": "string" } ] }, "method": "POST", "header": [ { "key": "Accept", "value": "application/json", "type": "text" } ], "body": { "mode": "raw", "raw": "{\n \"verifiableCredential\": {{verifiable_credential}}\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{API_BASE_URL}}/credentials/verify", "host": [ "{{API_BASE_URL}}" ], "path": [ "credentials", "verify" ] } }, "response": [] }, { "name": "Update Credential Status", "event": [ { "listen": "prerequest", "script": { "exec": [ "// Extract credential ID from verifiable credential", "let verifiable_credential_id;", "try {", " const { id } = JSON.parse(pm.collectionVariables.get(\"verifiable_credential\"));", " pm.collectionVariables.set('verifiable_credential_id', id)", "} catch {}", "" ], "type": "text/javascript" } }, { "listen": "test", "script": { "exec": [ "// The `/credentials/status` endpoint is authenticated. This test will not", "// prevent the request from running when the `access_token` collection variable", "// is missing, but it will give an indication of why the request failed in that", "// scenario.", "pm.test(\"`access_token` collection variable must be set\", function () {", " pm.expect(pm.collectionVariables.get(\"access_token\")).to.not.be.undefined;", "});", "", "// Verifiable credential ID is a required element item used in the request body", "pm.test(\"`verifiable_credential_id` local variable must be set\", function () {", " pm.expect(\"verifiable_credential\").to.be.a('string').that.is.not.empty;", "});", "", "// The expected response code for a \"Update Credential Status\" request is `200 Success`", "pm.test(\"must return `200 Success` status\", function () {", " pm.response.to.have.status(200);", "});" ], "type": "text/javascript" } } ], "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{access_token}}", "type": "string" } ] }, "method": "POST", "header": [ { "key": "Accept", "value": "application/json", "type": "text" } ], "body": { "mode": "raw", "raw": "{\n \"credentialId\": \"{{verifiable_credential_id}}\",\n \"credentialStatus\": [\n {\n \"type\": \"StatusList2021Entry\",\n \"statusPurpose\": \"revocation\",\n \"status\": \"1\"\n }\n ]\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{API_BASE_URL}}/credentials/status", "host": [ "{{API_BASE_URL}}" ], "path": [ "credentials", "status" ] } }, "response": [] }, { "name": "Verify Status Update", "event": [ { "listen": "test", "script": { "exec": [ "// The `/credentials/verify` endpoint is authenticated. This test will not", "// prevent the request from running when the `access_token` collection variable", "// is missing, but it will give an indication of why the request failed in that", "// scenario.", "pm.test(\"`access_token` collection variable must be set\", function () {", " pm.expect(pm.collectionVariables.get(\"access_token\")).to.not.be.undefined;", "});", "", "// The `verifiable_credential` from the \"Credentials Issue\" request is used to", "// populate part of the request body. If this collection variable is missing,", "// the request will not be prevented, but this test will raise an error that", "// will help to identify the problem.", "pm.test(\"`verifiable_credential` collection variable must be set\", function () {", " pm.expect(pm.collectionVariables.get(\"verifiable_credential\")).to.not.be.undefined;", "});", "", "// The expected response code for a \"Credentials Verify\" request is", "// `200 Success`.", "pm.test(\"must return `200 Success` status\", function () {", " pm.response.to.have.status(200);", "});", "", "// Confirm error", "pm.test(\"Response 'verified' property should be false\", function() {", " const { verified } = pm.response.json()", " pm.expect(verified).to.be.false;", "});", "", "", "" ], "type": "text/javascript" } } ], "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{access_token}}", "type": "string" } ] }, "method": "POST", "header": [ { "key": "Accept", "value": "application/json", "type": "text" } ], "body": { "mode": "raw", "raw": "{\n \"verifiableCredential\": {{verifiable_credential}}\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{API_BASE_URL}}/credentials/verify", "host": [ "{{API_BASE_URL}}" ], "path": [ "credentials", "verify" ] } }, "response": [] } ], "event": [ { "listen": "prerequest", "script": { "type": "text/javascript", "exec": [ "pm.request.headers.add({key: 'User-Agent', value: 'W3C Traceability Interop Tests'});" ] } }, { "listen": "test", "script": { "type": "text/javascript", "exec": [ "" ] } } ], "variable": [ { "key": "foo", "value": "" }, { "key": "credential_issuer_id", "value": "" }, { "key": "access_token", "value": "" }, { "key": "verifiable_credential", "value": "" }, { "key": "verifiable_credential_id", "value": "" } ] }