@velocitycareerlabs/server-webwallet 1.25.0-dev-build.12642c864

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/.localdev.env +57 -0
  2. package/.standalone.env +22 -0
  3. package/LICENSE +248 -0
  4. package/README.md +11 -0
  5. package/jest.config.js +20 -0
  6. package/migrate-mongo.config.js +23 -0
  7. package/package.json +72 -0
  8. package/src/config/config.js +74 -0
  9. package/src/controllers/accounts/autohooks.js +28 -0
  10. package/src/controllers/accounts/controller.js +209 -0
  11. package/src/controllers/accounts/schemas/index.js +6 -0
  12. package/src/controllers/accounts/schemas/webwallet-accounts-request.schema.js +25 -0
  13. package/src/controllers/accounts/schemas/webwallet-accounts-response.schema.js +72 -0
  14. package/src/controllers/accounts/schemas/webwallet-accounts-update-request.schema.js +23 -0
  15. package/src/controllers/accounts/schemas/webwallet-test-personas-response.schema.js +110 -0
  16. package/src/controllers/consent/autohooks.js +14 -0
  17. package/src/controllers/consent/controller.js +91 -0
  18. package/src/controllers/consent/schemas/index.js +3 -0
  19. package/src/controllers/consent/schemas/webwallet-consent-response.schema.js +23 -0
  20. package/src/controllers/credentials/autohooks.js +36 -0
  21. package/src/controllers/credentials/controller.js +92 -0
  22. package/src/controllers/credentials/schemas/index.js +4 -0
  23. package/src/controllers/credentials/schemas/webwallet-credential-categories-response.schema.js +21 -0
  24. package/src/controllers/credentials/schemas/webwallet-credentials-response.schema.js +29 -0
  25. package/src/controllers/disclosures/autohooks.js +21 -0
  26. package/src/controllers/disclosures/controller.js +168 -0
  27. package/src/controllers/disclosures/schemas/index.js +7 -0
  28. package/src/controllers/disclosures/schemas/webwallet-accept-presentation-request-body.schema.js +28 -0
  29. package/src/controllers/disclosures/schemas/webwallet-accept-presentation-response.schema.js +16 -0
  30. package/src/controllers/disclosures/schemas/webwallet-get-disclosures-response.schema.js +18 -0
  31. package/src/controllers/disclosures/schemas/webwallet-get-presentation-request-query.schema.js +21 -0
  32. package/src/controllers/disclosures/schemas/webwallet-get-presentation-request-response.schema.js +16 -0
  33. package/src/controllers/feedback/autohooks.js +11 -0
  34. package/src/controllers/feedback/controller.js +48 -0
  35. package/src/controllers/issuing/common-schemas/index.js +10 -0
  36. package/src/controllers/issuing/common-schemas/webwallet-get-credential-manifest-query.schema.js +27 -0
  37. package/src/controllers/issuing/common-schemas/webwallet-get-credential-manifest-response.schema.js +31 -0
  38. package/src/controllers/issuing/deep-link/autohooks.js +51 -0
  39. package/src/controllers/issuing/deep-link/controller.js +192 -0
  40. package/src/controllers/issuing/deep-link/schemas/index.js +6 -0
  41. package/src/controllers/issuing/deep-link/schemas/webwallet-deep-link-accept-offers-request.schema.js +30 -0
  42. package/src/controllers/issuing/deep-link/schemas/webwallet-deep-link-accept-offers-response.schema.js +36 -0
  43. package/src/controllers/issuing/deep-link/schemas/webwallet-deep-link-offers-request.schema.js +28 -0
  44. package/src/controllers/issuing/deep-link/schemas/webwallet-deep-link-offers-response.schema.js +48 -0
  45. package/src/controllers/issuing/identity-credentials/autohooks.js +42 -0
  46. package/src/controllers/issuing/identity-credentials/controller.js +188 -0
  47. package/src/controllers/issuing/identity-credentials/schemas/index.js +6 -0
  48. package/src/controllers/issuing/identity-credentials/schemas/webwallet-identity-credentials-confirm-body.schema.js +20 -0
  49. package/src/controllers/issuing/identity-credentials/schemas/webwallet-identity-credentials-confirm-response.schema.js +37 -0
  50. package/src/controllers/issuing/identity-credentials/schemas/webwallet-identity-credentials-request-code-body.schema.js +14 -0
  51. package/src/controllers/issuing/identity-credentials/schemas/webwallet-identity-credentials-request-code-params.schema.js +19 -0
  52. package/src/controllers/linkedin/autohooks.js +16 -0
  53. package/src/controllers/linkedin/controller.js +276 -0
  54. package/src/controllers/linkedin/schemas/index.js +3 -0
  55. package/src/controllers/linkedin/schemas/webwallet-linkedin-me-response.schema.js +14 -0
  56. package/src/controllers/root/controller.js +29 -0
  57. package/src/entities/.gitkeep +0 -0
  58. package/src/entities/accounts/constants.js +5 -0
  59. package/src/entities/accounts/domains/extract-auth0-id-token-or-access-token.js +22 -0
  60. package/src/entities/accounts/domains/index.js +5 -0
  61. package/src/entities/accounts/domains/validate-account-permissions.js +36 -0
  62. package/src/entities/accounts/domains/validate-logo-size.js +25 -0
  63. package/src/entities/accounts/index.js +5 -0
  64. package/src/entities/accounts/repos/accounts.repo.js +63 -0
  65. package/src/entities/credentials/domains/index.js +3 -0
  66. package/src/entities/credentials/domains/offer-to-credential-mongo-dto.js +43 -0
  67. package/src/entities/credentials/index.js +6 -0
  68. package/src/entities/credentials/orchestrators/index.js +3 -0
  69. package/src/entities/credentials/orchestrators/load-additional-render-info.js +65 -0
  70. package/src/entities/credentials/repos/credentials.repo.js +132 -0
  71. package/src/entities/credentials/schemas/index.js +4 -0
  72. package/src/entities/credentials/schemas/webwallet-credential-response.schema.js +138 -0
  73. package/src/entities/credentials/schemas/webwallet-credentials-response.schemas.js +95 -0
  74. package/src/entities/credentials/schemas/webwallet-display-descriptor-response.schema.js +106 -0
  75. package/src/entities/disclosures/index.js +4 -0
  76. package/src/entities/disclosures/repos/disclosures.repo.js +31 -0
  77. package/src/entities/disclosures/schemas/index.js +10 -0
  78. package/src/entities/disclosures/schemas/webwallet-disclosure.schema.js +39 -0
  79. package/src/entities/disclosures/schemas/webwallet-presentation-request-field.schema.js +45 -0
  80. package/src/entities/disclosures/schemas/webwallet-presentation-request-filter.schema.js +30 -0
  81. package/src/entities/disclosures/schemas/webwallet-presentation-request-format.schema.js +36 -0
  82. package/src/entities/disclosures/schemas/webwallet-presentation-request-input-descriptors.schema.js +111 -0
  83. package/src/entities/disclosures/schemas/webwallet-presentation-request-schema.schema.js +14 -0
  84. package/src/entities/disclosures/schemas/webwallet-presentation-request-submission-requirements.schema.js +37 -0
  85. package/src/entities/disclosures/schemas/webwallet-presentation-request.schema.js +79 -0
  86. package/src/entities/index.js +6 -0
  87. package/src/entities/issuing/domain/constants.js +8 -0
  88. package/src/entities/issuing/domain/does-user-have-fresh-pending-verification.js +26 -0
  89. package/src/entities/issuing/domain/get-credentials-from-offers.js +18 -0
  90. package/src/entities/issuing/domain/index.js +5 -0
  91. package/src/entities/issuing/index.js +5 -0
  92. package/src/entities/issuing/orchestrators/build-issuing-input-credentials.js +35 -0
  93. package/src/entities/issuing/orchestrators/generate-offers-by-deep-link.js +74 -0
  94. package/src/entities/issuing/orchestrators/get-identity-issuer.js +35 -0
  95. package/src/entities/issuing/orchestrators/get-identity-offers-by-deeplink.js +74 -0
  96. package/src/entities/issuing/orchestrators/index.js +6 -0
  97. package/src/entities/issuing/schemas/index.js +9 -0
  98. package/src/entities/issuing/schemas/webwallet-credential-manifest.schema.js +198 -0
  99. package/src/errors/error-codes.js +12 -0
  100. package/src/fetchers/career-wallet/create-account-fetcher.js +7 -0
  101. package/src/fetchers/career-wallet/create-did-fetcher.js +17 -0
  102. package/src/fetchers/career-wallet/get-app-config.js +11 -0
  103. package/src/fetchers/career-wallet/get-consents.js +13 -0
  104. package/src/fetchers/career-wallet/get-credential-categories.js +7 -0
  105. package/src/fetchers/career-wallet/get-personas.js +7 -0
  106. package/src/fetchers/career-wallet/index.js +12 -0
  107. package/src/fetchers/career-wallet/post-consent.js +9 -0
  108. package/src/fetchers/career-wallet/send-feedback.js +14 -0
  109. package/src/fetchers/career-wallet/sign-fetcher.js +14 -0
  110. package/src/fetchers/career-wallet/verify-id-credential-confirm-code.js +19 -0
  111. package/src/fetchers/career-wallet/verify-id-credential-request-code.js +20 -0
  112. package/src/fetchers/index.js +4 -0
  113. package/src/fetchers/lib-api/get-credential-display-schema.js +12 -0
  114. package/src/fetchers/lib-api/index.js +3 -0
  115. package/src/fetchers/linkedin/create-linkedin-post.js +45 -0
  116. package/src/fetchers/linkedin/get-access-token.js +26 -0
  117. package/src/fetchers/linkedin/get-linkedin-user-email.js +13 -0
  118. package/src/fetchers/linkedin/get-linkedin-user-id.js +16 -0
  119. package/src/fetchers/linkedin/index.js +9 -0
  120. package/src/fetchers/linkedin/register-image-to-upload.js +30 -0
  121. package/src/fetchers/linkedin/revoke-linkedin-access.js +20 -0
  122. package/src/fetchers/linkedin/upload-image-to-linkedin.js +16 -0
  123. package/src/index.js +15 -0
  124. package/src/init-server.js +108 -0
  125. package/src/plugins/crypto-services/index.js +5 -0
  126. package/src/plugins/crypto-services/jwt-sign-service-impl.js +72 -0
  127. package/src/plugins/crypto-services/jwt-verify-service-impl.js +21 -0
  128. package/src/plugins/crypto-services/key-service-impl.js +28 -0
  129. package/src/plugins/fetch-errors-handler-plugin.js +64 -0
  130. package/src/plugins/index.js +4 -0
  131. package/src/plugins/vnf-sdk-plugin.js +53 -0
  132. package/src/standalone.js +8 -0
  133. package/test/accounts-controller.test.js +618 -0
  134. package/test/consent-controller.test.js +185 -0
  135. package/test/credentials-controller.test.js +307 -0
  136. package/test/crypro-services/jwt-sign-service-impl.test.js +83 -0
  137. package/test/crypro-services/jwt-verify-service-impl.test.js +27 -0
  138. package/test/crypro-services/key-service-impl.test.js +76 -0
  139. package/test/crypro-services/mocks/index.js +4 -0
  140. package/test/crypro-services/mocks/jwt-mock.js +15 -0
  141. package/test/crypro-services/mocks/public-jwk.js +14 -0
  142. package/test/disclosures-controller/disclosure-credentials.test.js +428 -0
  143. package/test/disclosures-controller/get-disclosures.test.js +169 -0
  144. package/test/disclosures-controller/mocks/get-credential-manifest.js +20 -0
  145. package/test/disclosures-controller/mocks/index.js +6 -0
  146. package/test/disclosures-controller/mocks/presentation-request.js +32 -0
  147. package/test/disclosures-controller/mocks/presentation-submission.js +21 -0
  148. package/test/disclosures-controller/mocks/submission-result.js +19 -0
  149. package/test/factories/accounts.js +25 -0
  150. package/test/factories/credentials.js +66 -0
  151. package/test/factories/disclosures.js +106 -0
  152. package/test/feedback-controller.test.js +125 -0
  153. package/test/fetch-errors-handler-plugin.test.js +97 -0
  154. package/test/filter-deleted-credentials-extension.test.js +82 -0
  155. package/test/helpers/.env.test +10 -0
  156. package/test/helpers/nock-consent-add.js +16 -0
  157. package/test/helpers/nock-consents-get.js +15 -0
  158. package/test/helpers/nock-feedback.js +9 -0
  159. package/test/helpers/nock-linkedin-access-token.js +9 -0
  160. package/test/helpers/nock-linkedin-email.js +15 -0
  161. package/test/helpers/nock-linkedin-image-register.js +28 -0
  162. package/test/helpers/nock-linkedin-me.js +13 -0
  163. package/test/helpers/nock-linkedin-post.js +37 -0
  164. package/test/helpers/nock-linkedin-revoke.js +9 -0
  165. package/test/helpers/nock-test-personas.js +13 -0
  166. package/test/helpers/webwallet-build-fastify.js +17 -0
  167. package/test/issuing-controller/issuing-by-deeplink-empty-offers.test.js +142 -0
  168. package/test/issuing-controller/issuing-by-deeplink-failed-offers.test.js +142 -0
  169. package/test/issuing-controller/issuing-by-deeplink.test.js +492 -0
  170. package/test/issuing-controller/issuing-identity-credentials.test.js +377 -0
  171. package/test/issuing-controller/mocks/accept-offers-response.js +90 -0
  172. package/test/issuing-controller/mocks/accepted-credentials.js +47 -0
  173. package/test/issuing-controller/mocks/credential-manifest-presentation.js +72 -0
  174. package/test/issuing-controller/mocks/credential-manifest.js +45 -0
  175. package/test/issuing-controller/mocks/identity-issuing/accept-offers.js +22 -0
  176. package/test/issuing-controller/mocks/identity-issuing/confirm-verification-code.js +5 -0
  177. package/test/issuing-controller/mocks/identity-issuing/get-app-config.js +52 -0
  178. package/test/issuing-controller/mocks/identity-issuing/get-organization.js +118 -0
  179. package/test/issuing-controller/mocks/identity-issuing/index.js +6 -0
  180. package/test/issuing-controller/mocks/index.js +6 -0
  181. package/test/issuing-controller/mocks/issuers.js +126 -0
  182. package/test/issuing-controller/mocks/offers.js +48 -0
  183. package/test/issuing-controller/mocks/schema.js +107 -0
  184. package/test/linkedin-controller.test.js +452 -0
  185. package/test/mocks/credential-categories.js +115 -0
  186. package/test/mocks/credentials.js +15 -0
  187. package/test/mocks/didjwk.js +25 -0
  188. package/test/mocks/index.js +7 -0
  189. package/test/mocks/issuers.js +88 -0
  190. package/test/mocks/jwk.js +53 -0
  191. package/test/mocks/schema.js +107 -0
  192. package/test/root.test.js +42 -0
  193. package/test/vcl-sdk-plugin.test.js +86 -0
@@ -0,0 +1,377 @@
1
+ const nock = require('nock');
2
+ const { omit } = require('lodash/fp');
3
+ const { mongoDb } = require('@spencejs/spence-mongo-repos');
4
+ const {
5
+ VCLOrganizations,
6
+ VCLCredentialManifestDescriptorByDeepLink,
7
+ VCLDeepLink,
8
+ VCLIssuingType,
9
+ } = require('@velocitycareerlabs/vnf-nodejs-wallet-sdk');
10
+ const { errorResponseMatcher } = require('@velocitycareerlabs/tests-helpers');
11
+
12
+ jest.mock('@velocitycareerlabs/vnf-nodejs-wallet-sdk', () => {
13
+ const originalModule = jest.requireActual(
14
+ '@velocitycareerlabs/vnf-nodejs-wallet-sdk'
15
+ );
16
+
17
+ const { vclMockCredentialManifest } = require('./mocks/credential-manifest');
18
+ const { mockOffers } = require('./mocks/offers');
19
+ const {
20
+ getOrganizationMock,
21
+ } = require('./mocks/identity-issuing/get-organization');
22
+ const {
23
+ acceptOffersMock,
24
+ } = require('./mocks/identity-issuing/accept-offers');
25
+
26
+ return {
27
+ ...originalModule,
28
+ VCLProvider: {
29
+ getInstance: jest.fn().mockReturnValue({
30
+ initialize: jest.fn().mockResolvedValue(null),
31
+ getCredentialManifest: jest
32
+ .fn()
33
+ .mockResolvedValue(vclMockCredentialManifest),
34
+ generateOffers: jest.fn().mockResolvedValue(mockOffers),
35
+ searchForOrganizations: jest
36
+ .fn()
37
+ .mockResolvedValue(getOrganizationMock),
38
+ finalizeOffers: jest.fn().mockResolvedValue(acceptOffersMock),
39
+ }),
40
+ },
41
+ };
42
+ });
43
+
44
+ const { VCLProvider } = require('@velocitycareerlabs/vnf-nodejs-wallet-sdk');
45
+
46
+ const vclSdk = VCLProvider.getInstance();
47
+
48
+ const buildFastify = require('../helpers/webwallet-build-fastify');
49
+
50
+ const initAccountsFactory = require('../factories/accounts');
51
+
52
+ const {
53
+ getAppConfigMock,
54
+ confirmVerificationCodeMock,
55
+ } = require('./mocks/identity-issuing');
56
+ const { vclMockCredentialManifest } = require('./mocks/credential-manifest');
57
+
58
+ const auth0Token =
59
+ // eslint-disable-next-line max-len
60
+ 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IktFWSJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0LyIsImF1ZCI6ImZvbyIsInNjb3BlIjoicmVhZDp1c2VycyJ9.VwIIUqx9T-AxqbfL_FyNRAeOxTwiC2JpcwtrqnEWN3DdF07ijUkF1WYy8Ahfr_p4R3KnoPbiefZnIbVANCt-lt0ej32rfil2yHhQEsvFxSOjcrx6ARmPp0YAfWlN-5Sotzkxy29jaOZMEDkmRFZg3jkdC7wosPW_S6M-olC4g3HHfylpZI8O3Jdd87Qr9wD_QtUzANwnPbl2Q-9NEyxVjAZIWg_HWK9JAAaf_2IY5VwHBvyp0oeQSEHKi4hogcM59EOc4FxdR5WH45B_PenVa6W4mHFBkH8sAXxt2Zs9s2efujkfWYfyXvgL_lN7vT-TEADlAPP2L6CpWpDISOMsQWUSgGHcN_KwRh_E7qJwahR6mv4QHY6ReEoyjkmSS3swrD1l74jNs7QLAdsMywvzCMDsHabs7DYcEMGQBdP14PJ_ucLFnkivZeBDAc6sS445ocbyrpyO40XMaMorD5khRd9ej89SxR7d_v0W6Ne2Nn4XgW3pAZzu5Rdc4JvqfzLFxkp95jxy1MTAddjWISPmNOYYyXHM9SSqSpqVECOFS0f4z2zycHRqXUcOytWrvED6VGo9x7-IVCgu8vFzj0zToIWQmsDs3UoH9RnV12z0PMwGXQzca1lT_zGwJxBF3e4zJjmcJ05OMF2JgZ2_G48O3M4Dtb0jlgWbKLd0kWlIFzQ;';
61
+
62
+ const deepLink =
63
+ // eslint-disable-next-line max-len
64
+ 'velocity-network-devnet://issue?request_uri=https%3A%2F%2Fdevverifagent.velocitycareerlabs.io%2Fapi%2Fholder%2Fv0.6%2Forg%2Fdid%3Aion%3AEiAehWmpX5mHBuc93SIhPXF8bsEx68G6mPcdIaLNGbozPA%2Fissue%2Fget-credential-manifest%3FvendorOriginContext%3D3ozF14srt3drS_9lL3p1e&vendorOriginContext=3ozF14srt3drS_9lL3p1e';
65
+
66
+ describe('Test Disclosures controller, get disclosures list', () => {
67
+ let fastify;
68
+ let persistAccounts;
69
+
70
+ beforeAll(async () => {
71
+ fastify = buildFastify();
72
+
73
+ nock('https://localhost/').get('/.well-known/jwks.json').reply(200, jwks);
74
+ await fastify.ready();
75
+
76
+ ({ persistAccounts } = initAccountsFactory(fastify));
77
+ });
78
+
79
+ beforeEach(async () => {
80
+ await persistAccounts({
81
+ userId: '1234567890',
82
+ did: 'did:example:123',
83
+ });
84
+ });
85
+
86
+ afterEach(async () => {
87
+ nock.cleanAll();
88
+ jest.clearAllMocks();
89
+ await mongoDb().collection('credentials').deleteMany();
90
+ });
91
+
92
+ afterAll(async () => {
93
+ nock.restore();
94
+ await mongoDb().collection('accounts').deleteMany();
95
+ await fastify.close();
96
+ });
97
+
98
+ describe('POST /issuing/identity-credentials/request-code/email', () => {
99
+ it('should return 204 when code is sent and should trigger underlying API', async () => {
100
+ const nockedRequest = nockRequestCode('email', fastify);
101
+
102
+ const response = await fastify.injectJson({
103
+ method: 'POST',
104
+ url: '/issuing/identity-credentials/request-code/email',
105
+ payload: {
106
+ value: 'test@example.com',
107
+ },
108
+ headers: {
109
+ authorization: `Bearer ${auth0Token}`,
110
+ },
111
+ });
112
+
113
+ expect(nockedRequest.isDone()).toBe(true);
114
+
115
+ expect(response.statusCode).toBe(204);
116
+ });
117
+
118
+ it('should return proper error response when underlying API returns error', async () => {
119
+ const nockedRequest = nockRequestCodeError('email', fastify);
120
+
121
+ const response = await fastify.injectJson({
122
+ method: 'POST',
123
+ url: '/issuing/identity-credentials/request-code/email',
124
+ payload: {
125
+ value: 'test_error@example.com',
126
+ },
127
+ headers: {
128
+ authorization: `Bearer ${auth0Token}`,
129
+ },
130
+ });
131
+
132
+ expect(nockedRequest.isDone()).toBe(true);
133
+
134
+ expect(response.statusCode).toBe(400);
135
+
136
+ expect(response.json).toEqual(
137
+ errorResponseMatcher({
138
+ statusCode: 400,
139
+ errorCode: 'too_many_attempts',
140
+ error: 'Bad Request',
141
+ message: 'Too many attempts.',
142
+ })
143
+ );
144
+ });
145
+
146
+ it('should return error 401 if there is incorrect token', async () => {
147
+ const response = await fastify.injectJson({
148
+ method: 'POST',
149
+ url: '/issuing/identity-credentials/request-code/email',
150
+ payload: {
151
+ value: 'test@mail.com',
152
+ },
153
+ headers: {
154
+ authorization: 'Bearer randomIncorrectToken',
155
+ },
156
+ });
157
+
158
+ expect(response.statusCode).toBe(401);
159
+ });
160
+ });
161
+
162
+ describe('POST /issuing/identity-credentials/confirm', () => {
163
+ it('should return 200 when code is confirmed and should trigger underlying API', async () => {
164
+ const nockedAppConfig = nockAppConfig(fastify);
165
+ const nockedConfirmVerification = nockConfirmVerificationCode(
166
+ '123456',
167
+ fastify
168
+ );
169
+
170
+ const response = await fastify.injectJson({
171
+ method: 'POST',
172
+ url: '/issuing/identity-credentials/confirm',
173
+ payload: {
174
+ verificationCode: '123456',
175
+ type: 'email',
176
+ },
177
+ headers: {
178
+ authorization: `Bearer ${auth0Token}`,
179
+ },
180
+ });
181
+
182
+ expect(response.statusCode).toEqual(200);
183
+
184
+ expect(nockedAppConfig.isDone()).toBe(true);
185
+ expect(nockedConfirmVerification.isDone()).toBe(true);
186
+
187
+ expect(vclSdk.getCredentialManifest).toHaveBeenCalledTimes(1);
188
+ expect(vclSdk.getCredentialManifest).toHaveBeenCalledWith(
189
+ new VCLCredentialManifestDescriptorByDeepLink(
190
+ new VCLDeepLink(deepLink),
191
+ VCLIssuingType.Identity,
192
+ null,
193
+ null,
194
+ null
195
+ )
196
+ );
197
+
198
+ expect(vclSdk.generateOffers).toHaveBeenCalledTimes(1);
199
+ expect(vclSdk.generateOffers).toHaveBeenCalledWith(
200
+ expect.objectContaining({
201
+ credentialManifest: vclMockCredentialManifest,
202
+ })
203
+ );
204
+
205
+ const savedCredential = await mongoDb()
206
+ .collection('credentials')
207
+ .findOne({
208
+ auth0UserId: '1234567890',
209
+ });
210
+
211
+ expect({
212
+ ...omit(['_id'], savedCredential),
213
+ id: savedCredential._id.toHexString(),
214
+ updatedAt: savedCredential.updatedAt.toISOString(),
215
+ createdAt: savedCredential.createdAt.toISOString(),
216
+ }).toEqual(response.json.credentials[0]);
217
+ });
218
+
219
+ it('should return error 401 if there is incorrect token', async () => {
220
+ const response = await fastify.injectJson({
221
+ method: 'POST',
222
+ url: '/issuing/identity-credentials/confirm',
223
+ payload: {
224
+ verificationCode: '123456',
225
+ type: 'email',
226
+ },
227
+ headers: {
228
+ authorization: 'Bearer incorrectToken',
229
+ },
230
+ });
231
+
232
+ expect(response.statusCode).toBe(401);
233
+ });
234
+
235
+ it('should return error 400 if SDK failed to find issuer', async () => {
236
+ nockAppConfig(fastify);
237
+ nockConfirmVerificationCode('123456', fastify);
238
+
239
+ vclSdk.searchForOrganizations.mockResolvedValueOnce(
240
+ new VCLOrganizations([])
241
+ );
242
+
243
+ const response = await fastify.injectJson({
244
+ method: 'POST',
245
+ url: '/issuing/identity-credentials/confirm',
246
+ payload: {
247
+ verificationCode: '123456',
248
+ type: 'email',
249
+ },
250
+ headers: {
251
+ authorization: `Bearer ${auth0Token}`,
252
+ },
253
+ });
254
+
255
+ expect(response.statusCode).toBe(400);
256
+
257
+ expect(response.json).toEqual(
258
+ errorResponseMatcher({
259
+ error: 'Bad Request',
260
+ errorCode: 'verification_error',
261
+ message: 'Failed to find identity issuer',
262
+ statusCode: 400,
263
+ })
264
+ );
265
+ });
266
+
267
+ it('should return error 400 if SDK failed to get offers', async () => {
268
+ nockAppConfig(fastify);
269
+ nockConfirmVerificationCode('123456', fastify);
270
+
271
+ vclSdk.generateOffers.mockResolvedValueOnce({
272
+ all: [],
273
+ });
274
+
275
+ const response = await fastify.injectJson({
276
+ method: 'POST',
277
+ url: '/issuing/identity-credentials/confirm',
278
+ payload: {
279
+ verificationCode: '123456',
280
+ type: 'email',
281
+ },
282
+ headers: {
283
+ authorization: `Bearer ${auth0Token}`,
284
+ },
285
+ });
286
+
287
+ expect(response.statusCode).toBe(400);
288
+
289
+ expect(response.json).toEqual(
290
+ errorResponseMatcher({
291
+ error: 'Bad Request',
292
+ errorCode: 'verification_error',
293
+ message: 'Failed to finalize offers',
294
+ statusCode: 400,
295
+ })
296
+ );
297
+ });
298
+ });
299
+ });
300
+
301
+ const nockRequestCode = (credentialType, fastify) => {
302
+ return nock(fastify.config.careerWalletUrl)
303
+ .post(`/api/v0.6/verify/${credentialType}/request-code`, {
304
+ value: 'test@example.com',
305
+ })
306
+ .once()
307
+ .reply(204, {});
308
+ };
309
+
310
+ const nockRequestCodeError = (credentialType, fastify) => {
311
+ return nock(fastify.config.careerWalletUrl)
312
+ .post(`/api/v0.6/verify/${credentialType}/request-code`, {
313
+ value: 'test_error@example.com',
314
+ })
315
+ .once()
316
+ .reply(400, {
317
+ message: 'Too many attempts.',
318
+ errorCode: 'too_many_attempts',
319
+ });
320
+ };
321
+
322
+ const nockAppConfig = (fastify) => {
323
+ return nock(fastify.config.careerWalletUrl)
324
+ .get('/api/v0.6/careerwallet/appconfig')
325
+ .once()
326
+ .reply(200, getAppConfigMock);
327
+ };
328
+
329
+ const nockConfirmVerificationCode = (verificationCode, fastify) => {
330
+ return nock(fastify.config.careerWalletUrl)
331
+ .post('/api/v0.6/verify/confirm', { verificationCode })
332
+ .once()
333
+ .reply(200, confirmVerificationCodeMock);
334
+ };
335
+
336
+ const jwks = {
337
+ keys: [
338
+ {
339
+ alg: 'RS512',
340
+ kid: 'KEY',
341
+ x5c: ['UNUSED'],
342
+ },
343
+ {
344
+ alg: 'RS256',
345
+ kid: 'KEY',
346
+ x5c: [
347
+ `
348
+ MIIEnjCCAoYCCQDmnGII6qzGlTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZ1
349
+ bnVzZWQwHhcNMjEwOTE5MDcxODQ2WhcNMjExMDE5MDcxODQ2WjARMQ8wDQYDVQQD
350
+ DAZ1bnVzZWQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDY2acJ8JAH
351
+ XjK8j3sAXOokSWwvaEg65UJS0C7KdnfbLTeaeYFHBRY0v9Jkk/PJSXv9hMWw1aD3
352
+ n7NrhVwXeRXi/7VZuW/S4ek+hK+IMDvpKqzn+XeCpaMoRpAgloADeNY0qhYKxpr2
353
+ L0SmRQDwVy1r/g31ECewD2WpEiRSmXsQ2Q2uYT3V60BmbhUw31KGEr4SLXL9pzmb
354
+ arOH/5Rhqg+YFMywNY6i01S3UdOlUtAyWT/mVRAkVTsUEou9tBw61zputPdMrl7p
355
+ d4InmlfCmXNTPFh9EDczPQiAVPq8MDyEdRGP134+HM9+YgQUZjy+WsxmGEvplJIf
356
+ KrYtlWe11//oAXC3690LUYtvg49lNY4+H0/nngjnCDXkZo6f+PEvnBZfYl596VTV
357
+ Fx4FGNOqLwg4bAyE5j5jXtEGW1oKo1pxBg7Oe3MteQUDwMrONB3CbxdxDiN3YH94
358
+ 2nWGW9Le+CeA1QUhfjQqSoZRJURGYGoztVuIXOElnkrgwcJreX4b8y+Uo5kpp2By
359
+ 6UUaD/mMj9XQ+Ygp/J8DlJlqDXOIp6JUJ75aSK5ZIjRtWq/Go5RUjW9IW0ldEehh
360
+ /4j0ZWC0vR1/le2UmAE6tXhkH4sdx9JM84V+qRzjiGqQx3Wn00uwMiHHhte17t41
361
+ vk+b75wuHbfiq9R8irL6wqWeeuzvCC37NwIDAQABMA0GCSqGSIb3DQEBCwUAA4IC
362
+ AQCZOT6S5HLUp0gBtWK6Fxyzb9lWPE+AJipjJ80lS3OnaOIyVtyJexJ2BjTKWldJ
363
+ 48zkzLNIRsTEGEipNS6NkrkElfmoaNBpdbDch2WBkME3UYlFIR9GgbXPMlACQlwJ
364
+ f4qT3iIZ9zjpVMP8F63TzRRr7KEYW2PGHEtVQktMPprGEfU4Sz0OIa9RRV+BLsfh
365
+ x8he2pimJEzoEaWPgyJXV1S+tLUif8A/CEkZVRZ2vADA7WMGl2ZTdbmsTjXh4bf2
366
+ A4l4Zec+jwOjUPiEk5lLJwv1KeYos9wuUczAk7ku8wRzyZbrjwgRam9VQA5qmRzJ
367
+ PegEQwJaKMRu8PPK0L4KFN4v3ma7Ux6D719nko8mZ0kA2oUs6phsFmoWQfsbRbsD
368
+ CdUGnM2fPp6V285r9w9Y6+1nVdtJpbAPFJR3SxIpfYVfx3tI6C3BR9bIMr8uCf81
369
+ G+Ebvo4qTuY6Cg/mTpPLZ4cKpwSvB6cE+xeSHvKIRYm6QUYEReRxQ3b4aUKBSNwl
370
+ FEQufVGhGzeblNC3fjP+mMtqbyC8c1zkHc6tjJYO5yesKf8bjO71by2jgSced7nN
371
+ 5JvJawfEcabgHJ1aAFLj0tlPMrViFzu6y8/A5aZLc5UMISXAZXfB4wIEdyUUXJh4
372
+ rJKE/ZCb2+W8g29N5cv2P6nhahT3mYatMiQ0U/gfaIrA0A==
373
+ `.trim(),
374
+ ],
375
+ },
376
+ ],
377
+ };
@@ -0,0 +1,90 @@
1
+ const { VelocityRevocationListType } = require('@velocitycareerlabs/vc-checks');
2
+ const { mockAcceptedCredentials } = require('./accepted-credentials');
3
+
4
+ const mockParsedResponse = {
5
+ passedCredentials: [
6
+ {
7
+ id: expect.any(String),
8
+ auth0UserId: '1234567890',
9
+ userDid: 'did:example:123',
10
+ contentHash: {
11
+ type: 'VelocityContentHash2020',
12
+ value:
13
+ 'e6111d72559b84448ee3c844d4d3dafaa63cf97091ee203c68e257fab9cf0337',
14
+ },
15
+ context: [
16
+ 'https://www.w3.org/2018/credentials/v1',
17
+ 'https://devlib.velocitynetwork.foundation/contexts/credential-extensions-2022.jsonld.json',
18
+ ],
19
+ createdAt: expect.any(String),
20
+ credentialSchema: {
21
+ id: 'https://devregistrar.velocitynetwork.foundation/schemas/open-badge-v2.0.schema.json',
22
+ type: 'JsonSchemaValidator2018',
23
+ },
24
+ credentialStatus: {
25
+ // eslint-disable-next-line max-len
26
+ id: 'ethereum:0xD890F2D60B429f9e257FC0Bc58Ef2237776DD91B/getRevokedStatus?address=0xa27F300621a7474A68fd5a417D9560d24f9d9F74&listId=255664421176378&index=3270',
27
+ statusListCredential:
28
+ // eslint-disable-next-line max-len
29
+ 'ethereum:0xD890F2D60B429f9e257FC0Bc58Ef2237776DD91B/getRevokedStatus?address=0xa27F300621a7474A68fd5a417D9560d24f9d9F74&listId=255664421176378',
30
+ statusListIndex: 3270,
31
+ type: VelocityRevocationListType,
32
+ },
33
+ credentialSubject: {
34
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
35
+ hasCredential: {
36
+ criteria: 'https://example.com/velocity-badge.html',
37
+ description: 'For issuing a Badge on the Velocity Network',
38
+ id: 'https://example.com/velocity-badge.json',
39
+ image:
40
+ 'https://www.velocitynetwork.foundation/wp-content/uploads/2020/02/fb.jpg',
41
+ issuer: 'did:ion:EiApMLdMb4NPb8sae9-hXGHP79W1gisApVSE80USPEbtJA',
42
+ name: 'Velocity Badge',
43
+ type: 'BadgeClass',
44
+ },
45
+ type: 'Badge',
46
+ },
47
+ did: 'did:velocity:v2:0xa27f300621a7474a68fd5a417d9560d24f9d9f74:56898051534679:2985',
48
+ iss: 'did:ion:EiApMLdMb4NPb8sae9-hXGHP79W1gisApVSE80USPEbtJA',
49
+ issuer: {
50
+ id: 'did:ion:EiApMLdMb4NPb8sae9-hXGHP79W1gisApVSE80USPEbtJA',
51
+ },
52
+ jti: 'did:velocity:v2:0xa27f300621a7474a68fd5a417d9560d24f9d9f74:56898051534679:2985',
53
+ linkCodeCommitment: {
54
+ type: 'VelocityCredentialLinkCodeCommitment2022',
55
+ value: 'EiBYXN+pEkLCGjtMvZGBMj6mQQeNtS6iaD6E6ZdhtC98Ng==',
56
+ },
57
+ type: ['OpenBadgeV2.0', 'VerifiableCredential'],
58
+ updatedAt: expect.any(String),
59
+ vnfProtocolVersion: 1,
60
+ encodedCredential:
61
+ mockAcceptedCredentials.passedCredentials[0].encodedJwt,
62
+ },
63
+ ],
64
+ failedCredentials: [],
65
+ };
66
+
67
+ const mockParsedEmptyResponse = {
68
+ passedCredentials: [],
69
+ failedCredentials: [],
70
+ };
71
+
72
+ const mockParsedFailedResponse = {
73
+ passedCredentials: [],
74
+ failedCredentials: [
75
+ {
76
+ encodedJwt: mockAcceptedCredentials.passedCredentials[0].encodedJwt,
77
+ signedJwt: {
78
+ header: expect.any(String),
79
+ payload: expect.any(String),
80
+ signature: expect.any(String),
81
+ },
82
+ },
83
+ ],
84
+ };
85
+
86
+ module.exports = {
87
+ mockParsedResponse,
88
+ mockParsedEmptyResponse,
89
+ mockParsedFailedResponse,
90
+ };
@@ -0,0 +1,47 @@
1
+ /* eslint-disable max-len */
2
+ const mockAcceptedCredentials = {
3
+ passedCredentials: [
4
+ {
5
+ signedJwt: {
6
+ header:
7
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6dmVsb2NpdHk6djI6MHhhMjdmMzAwNjIxYTc0NzRhNjhmZDVhNDE3ZDk1NjBkMjRmOWQ5Zjc0OjU2ODk4MDUxNTM0Njc5OjI5ODUja2V5LTEifQ',
8
+ payload:
9
+ 'eyJ2YyI6eyJ0eXBlIjpbIk9wZW5CYWRnZVYyLjAiLCJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpZCI6ImRpZDp2ZWxvY2l0eTp2MjoweGEyN2YzMDA2MjFhNzQ3NGE2OGZkNWE0MTdkOTU2MGQyNGY5ZDlmNzQ6NTY4OTgwNTE1MzQ2Nzk6Mjk4NSIsImNyZWRlbnRpYWxTdGF0dXMiOnsidHlwZSI6IlZlbG9jaXR5UmV2b2NhdGlvbkxpc3RKYW4yMDIxIiwiaWQiOiJldGhlcmV1bToweEQ4OTBGMkQ2MEI0MjlmOWUyNTdGQzBCYzU4RWYyMjM3Nzc2REQ5MUIvZ2V0UmV2b2tlZFN0YXR1cz9hZGRyZXNzPTB4YTI3RjMwMDYyMWE3NDc0QTY4ZmQ1YTQxN0Q5NTYwZDI0ZjlkOUY3NCZsaXN0SWQ9MjU1NjY0NDIxMTc2Mzc4JmluZGV4PTMyNzAiLCJzdGF0dXNMaXN0SW5kZXgiOjMyNzAsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiZXRoZXJldW06MHhEODkwRjJENjBCNDI5ZjllMjU3RkMwQmM1OEVmMjIzNzc3NkREOTFCL2dldFJldm9rZWRTdGF0dXM_YWRkcmVzcz0weGEyN0YzMDA2MjFhNzQ3NEE2OGZkNWE0MTdEOTU2MGQyNGY5ZDlGNzQmbGlzdElkPTI1NTY2NDQyMTE3NjM3OCJ9LCJsaW5rQ29kZUNvbW1pdG1lbnQiOnsidHlwZSI6IlZlbG9jaXR5Q3JlZGVudGlhbExpbmtDb2RlQ29tbWl0bWVudDIwMjIiLCJ2YWx1ZSI6IkVpQllYTitwRWtMQ0dqdE12WkdCTWo2bVFRZU50UzZpYUQ2RTZaZGh0Qzk4Tmc9PSJ9LCJpc3N1ZXIiOnsiaWQiOiJkaWQ6aW9uOkVpQXBNTGRNYjROUGI4c2FlOS1oWEdIUDc5VzFnaXNBcFZTRTgwVVNQRWJ0SkEifSwiY29udGVudEhhc2giOnsidHlwZSI6IlZlbG9jaXR5Q29udGVudEhhc2gyMDIwIiwidmFsdWUiOiJlNjExMWQ3MjU1OWI4NDQ0OGVlM2M4NDRkNGQzZGFmYWE2M2NmOTcwOTFlZTIwM2M2OGUyNTdmYWI5Y2YwMzM3In0sImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2RldnJlZ2lzdHJhci52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi9zY2hlbWFzL29wZW4tYmFkZ2UtdjIuMC5zY2hlbWEuanNvbiIsInR5cGUiOiJKc29uU2NoZW1hVmFsaWRhdG9yMjAxOCJ9LCJ2bmZQcm90b2NvbFZlcnNpb24iOjEsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9kZXZsaWIudmVsb2NpdHluZXR3b3JrLmZvdW5kYXRpb24vY29udGV4dHMvY3JlZGVudGlhbC1leHRlbnNpb25zLTIwMjIuanNvbmxkLmpzb24iXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaGFzQ3JlZGVudGlhbCI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuanNvbiIsInR5cGUiOiJCYWRnZUNsYXNzIiwibmFtZSI6IlZlbG9jaXR5IEJhZGdlIiwiZGVzY3JpcHRpb24iOiJGb3IgaXNzdWluZyBhIEJhZGdlIG9uIHRoZSBWZWxvY2l0eSBOZXR3b3JrIiwiaW1hZ2UiOiJodHRwczovL3d3dy52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi93cC1jb250ZW50L3VwbG9hZHMvMjAyMC8wMi9mYi5qcGciLCJjcml0ZXJpYSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuaHRtbCIsImlzc3VlciI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSJ9LCJ0eXBlIjoiQmFkZ2UiLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdfX0sIm5iZiI6MTY5NjE2MzQ0MywianRpIjoiZGlkOnZlbG9jaXR5OnYyOjB4YTI3ZjMwMDYyMWE3NDc0YTY4ZmQ1YTQxN2Q5NTYwZDI0ZjlkOWY3NDo1Njg5ODA1MTUzNDY3OToyOTg1IiwiaXNzIjoiZGlkOmlvbjpFaUFwTUxkTWI0TlBiOHNhZTktaFhHSFA3OVcxZ2lzQXBWU0U4MFVTUEVidEpBIiwiaWF0IjoxNjk2MTYzNDQzfQ',
10
+ signature:
11
+ '17acEH7Qn3XOg9RpVqY9TDV64F6Kyw9hNo2R7FT2-Jv8JmnkNU0n4KbCuV2ZiU95qMM5yvgzRF3hcFYkDHmmFQ',
12
+ },
13
+ encodedJwt:
14
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6dmVsb2NpdHk6djI6MHhhMjdmMzAwNjIxYTc0NzRhNjhmZDVhNDE3ZDk1NjBkMjRmOWQ5Zjc0OjU2ODk4MDUxNTM0Njc5OjI5ODUja2V5LTEifQ.eyJ2YyI6eyJ0eXBlIjpbIk9wZW5CYWRnZVYyLjAiLCJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpZCI6ImRpZDp2ZWxvY2l0eTp2MjoweGEyN2YzMDA2MjFhNzQ3NGE2OGZkNWE0MTdkOTU2MGQyNGY5ZDlmNzQ6NTY4OTgwNTE1MzQ2Nzk6Mjk4NSIsImNyZWRlbnRpYWxTdGF0dXMiOnsidHlwZSI6IlZlbG9jaXR5UmV2b2NhdGlvbkxpc3RKYW4yMDIxIiwiaWQiOiJldGhlcmV1bToweEQ4OTBGMkQ2MEI0MjlmOWUyNTdGQzBCYzU4RWYyMjM3Nzc2REQ5MUIvZ2V0UmV2b2tlZFN0YXR1cz9hZGRyZXNzPTB4YTI3RjMwMDYyMWE3NDc0QTY4ZmQ1YTQxN0Q5NTYwZDI0ZjlkOUY3NCZsaXN0SWQ9MjU1NjY0NDIxMTc2Mzc4JmluZGV4PTMyNzAiLCJzdGF0dXNMaXN0SW5kZXgiOjMyNzAsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiZXRoZXJldW06MHhEODkwRjJENjBCNDI5ZjllMjU3RkMwQmM1OEVmMjIzNzc3NkREOTFCL2dldFJldm9rZWRTdGF0dXM_YWRkcmVzcz0weGEyN0YzMDA2MjFhNzQ3NEE2OGZkNWE0MTdEOTU2MGQyNGY5ZDlGNzQmbGlzdElkPTI1NTY2NDQyMTE3NjM3OCJ9LCJsaW5rQ29kZUNvbW1pdG1lbnQiOnsidHlwZSI6IlZlbG9jaXR5Q3JlZGVudGlhbExpbmtDb2RlQ29tbWl0bWVudDIwMjIiLCJ2YWx1ZSI6IkVpQllYTitwRWtMQ0dqdE12WkdCTWo2bVFRZU50UzZpYUQ2RTZaZGh0Qzk4Tmc9PSJ9LCJpc3N1ZXIiOnsiaWQiOiJkaWQ6aW9uOkVpQXBNTGRNYjROUGI4c2FlOS1oWEdIUDc5VzFnaXNBcFZTRTgwVVNQRWJ0SkEifSwiY29udGVudEhhc2giOnsidHlwZSI6IlZlbG9jaXR5Q29udGVudEhhc2gyMDIwIiwidmFsdWUiOiJlNjExMWQ3MjU1OWI4NDQ0OGVlM2M4NDRkNGQzZGFmYWE2M2NmOTcwOTFlZTIwM2M2OGUyNTdmYWI5Y2YwMzM3In0sImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2RldnJlZ2lzdHJhci52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi9zY2hlbWFzL29wZW4tYmFkZ2UtdjIuMC5zY2hlbWEuanNvbiIsInR5cGUiOiJKc29uU2NoZW1hVmFsaWRhdG9yMjAxOCJ9LCJ2bmZQcm90b2NvbFZlcnNpb24iOjEsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9kZXZsaWIudmVsb2NpdHluZXR3b3JrLmZvdW5kYXRpb24vY29udGV4dHMvY3JlZGVudGlhbC1leHRlbnNpb25zLTIwMjIuanNvbmxkLmpzb24iXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaGFzQ3JlZGVudGlhbCI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuanNvbiIsInR5cGUiOiJCYWRnZUNsYXNzIiwibmFtZSI6IlZlbG9jaXR5IEJhZGdlIiwiZGVzY3JpcHRpb24iOiJGb3IgaXNzdWluZyBhIEJhZGdlIG9uIHRoZSBWZWxvY2l0eSBOZXR3b3JrIiwiaW1hZ2UiOiJodHRwczovL3d3dy52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi93cC1jb250ZW50L3VwbG9hZHMvMjAyMC8wMi9mYi5qcGciLCJjcml0ZXJpYSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuaHRtbCIsImlzc3VlciI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSJ9LCJ0eXBlIjoiQmFkZ2UiLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdfX0sIm5iZiI6MTY5NjE2MzQ0MywianRpIjoiZGlkOnZlbG9jaXR5OnYyOjB4YTI3ZjMwMDYyMWE3NDc0YTY4ZmQ1YTQxN2Q5NTYwZDI0ZjlkOWY3NDo1Njg5ODA1MTUzNDY3OToyOTg1IiwiaXNzIjoiZGlkOmlvbjpFaUFwTUxkTWI0TlBiOHNhZTktaFhHSFA3OVcxZ2lzQXBWU0U4MFVTUEVidEpBIiwiaWF0IjoxNjk2MTYzNDQzfQ.17acEH7Qn3XOg9RpVqY9TDV64F6Kyw9hNo2R7FT2-Jv8JmnkNU0n4KbCuV2ZiU95qMM5yvgzRF3hcFYkDHmmFQ',
15
+ },
16
+ ],
17
+ failedCredentials: [],
18
+ };
19
+
20
+ const mockAcceptedEmptyCredentials = {
21
+ passedCredentials: [],
22
+ failedCredentials: [],
23
+ };
24
+
25
+ const mockAcceptedFailedCredentials = {
26
+ passedCredentials: [],
27
+ failedCredentials: [
28
+ {
29
+ signedJwt: {
30
+ header:
31
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6dmVsb2NpdHk6djI6MHhhMjdmMzAwNjIxYTc0NzRhNjhmZDVhNDE3ZDk1NjBkMjRmOWQ5Zjc0OjU2ODk4MDUxNTM0Njc5OjI5ODUja2V5LTEifQ',
32
+ payload:
33
+ 'eyJ2YyI6eyJ0eXBlIjpbIk9wZW5CYWRnZVYyLjAiLCJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpZCI6ImRpZDp2ZWxvY2l0eTp2MjoweGEyN2YzMDA2MjFhNzQ3NGE2OGZkNWE0MTdkOTU2MGQyNGY5ZDlmNzQ6NTY4OTgwNTE1MzQ2Nzk6Mjk4NSIsImNyZWRlbnRpYWxTdGF0dXMiOnsidHlwZSI6IlZlbG9jaXR5UmV2b2NhdGlvbkxpc3RKYW4yMDIxIiwiaWQiOiJldGhlcmV1bToweEQ4OTBGMkQ2MEI0MjlmOWUyNTdGQzBCYzU4RWYyMjM3Nzc2REQ5MUIvZ2V0UmV2b2tlZFN0YXR1cz9hZGRyZXNzPTB4YTI3RjMwMDYyMWE3NDc0QTY4ZmQ1YTQxN0Q5NTYwZDI0ZjlkOUY3NCZsaXN0SWQ9MjU1NjY0NDIxMTc2Mzc4JmluZGV4PTMyNzAiLCJzdGF0dXNMaXN0SW5kZXgiOjMyNzAsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiZXRoZXJldW06MHhEODkwRjJENjBCNDI5ZjllMjU3RkMwQmM1OEVmMjIzNzc3NkREOTFCL2dldFJldm9rZWRTdGF0dXM_YWRkcmVzcz0weGEyN0YzMDA2MjFhNzQ3NEE2OGZkNWE0MTdEOTU2MGQyNGY5ZDlGNzQmbGlzdElkPTI1NTY2NDQyMTE3NjM3OCJ9LCJsaW5rQ29kZUNvbW1pdG1lbnQiOnsidHlwZSI6IlZlbG9jaXR5Q3JlZGVudGlhbExpbmtDb2RlQ29tbWl0bWVudDIwMjIiLCJ2YWx1ZSI6IkVpQllYTitwRWtMQ0dqdE12WkdCTWo2bVFRZU50UzZpYUQ2RTZaZGh0Qzk4Tmc9PSJ9LCJpc3N1ZXIiOnsiaWQiOiJkaWQ6aW9uOkVpQXBNTGRNYjROUGI4c2FlOS1oWEdIUDc5VzFnaXNBcFZTRTgwVVNQRWJ0SkEifSwiY29udGVudEhhc2giOnsidHlwZSI6IlZlbG9jaXR5Q29udGVudEhhc2gyMDIwIiwidmFsdWUiOiJlNjExMWQ3MjU1OWI4NDQ0OGVlM2M4NDRkNGQzZGFmYWE2M2NmOTcwOTFlZTIwM2M2OGUyNTdmYWI5Y2YwMzM3In0sImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2RldnJlZ2lzdHJhci52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi9zY2hlbWFzL29wZW4tYmFkZ2UtdjIuMC5zY2hlbWEuanNvbiIsInR5cGUiOiJKc29uU2NoZW1hVmFsaWRhdG9yMjAxOCJ9LCJ2bmZQcm90b2NvbFZlcnNpb24iOjEsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9kZXZsaWIudmVsb2NpdHluZXR3b3JrLmZvdW5kYXRpb24vY29udGV4dHMvY3JlZGVudGlhbC1leHRlbnNpb25zLTIwMjIuanNvbmxkLmpzb24iXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaGFzQ3JlZGVudGlhbCI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuanNvbiIsInR5cGUiOiJCYWRnZUNsYXNzIiwibmFtZSI6IlZlbG9jaXR5IEJhZGdlIiwiZGVzY3JpcHRpb24iOiJGb3IgaXNzdWluZyBhIEJhZGdlIG9uIHRoZSBWZWxvY2l0eSBOZXR3b3JrIiwiaW1hZ2UiOiJodHRwczovL3d3dy52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi93cC1jb250ZW50L3VwbG9hZHMvMjAyMC8wMi9mYi5qcGciLCJjcml0ZXJpYSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuaHRtbCIsImlzc3VlciI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSJ9LCJ0eXBlIjoiQmFkZ2UiLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdfX0sIm5iZiI6MTY5NjE2MzQ0MywianRpIjoiZGlkOnZlbG9jaXR5OnYyOjB4YTI3ZjMwMDYyMWE3NDc0YTY4ZmQ1YTQxN2Q5NTYwZDI0ZjlkOWY3NDo1Njg5ODA1MTUzNDY3OToyOTg1IiwiaXNzIjoiZGlkOmlvbjpFaUFwTUxkTWI0TlBiOHNhZTktaFhHSFA3OVcxZ2lzQXBWU0U4MFVTUEVidEpBIiwiaWF0IjoxNjk2MTYzNDQzfQ',
34
+ signature:
35
+ '17acEH7Qn3XOg9RpVqY9TDV64F6Kyw9hNo2R7FT2-Jv8JmnkNU0n4KbCuV2ZiU95qMM5yvgzRF3hcFYkDHmmFQ',
36
+ },
37
+ encodedJwt:
38
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6dmVsb2NpdHk6djI6MHhhMjdmMzAwNjIxYTc0NzRhNjhmZDVhNDE3ZDk1NjBkMjRmOWQ5Zjc0OjU2ODk4MDUxNTM0Njc5OjI5ODUja2V5LTEifQ.eyJ2YyI6eyJ0eXBlIjpbIk9wZW5CYWRnZVYyLjAiLCJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpZCI6ImRpZDp2ZWxvY2l0eTp2MjoweGEyN2YzMDA2MjFhNzQ3NGE2OGZkNWE0MTdkOTU2MGQyNGY5ZDlmNzQ6NTY4OTgwNTE1MzQ2Nzk6Mjk4NSIsImNyZWRlbnRpYWxTdGF0dXMiOnsidHlwZSI6IlZlbG9jaXR5UmV2b2NhdGlvbkxpc3RKYW4yMDIxIiwiaWQiOiJldGhlcmV1bToweEQ4OTBGMkQ2MEI0MjlmOWUyNTdGQzBCYzU4RWYyMjM3Nzc2REQ5MUIvZ2V0UmV2b2tlZFN0YXR1cz9hZGRyZXNzPTB4YTI3RjMwMDYyMWE3NDc0QTY4ZmQ1YTQxN0Q5NTYwZDI0ZjlkOUY3NCZsaXN0SWQ9MjU1NjY0NDIxMTc2Mzc4JmluZGV4PTMyNzAiLCJzdGF0dXNMaXN0SW5kZXgiOjMyNzAsInN0YXR1c0xpc3RDcmVkZW50aWFsIjoiZXRoZXJldW06MHhEODkwRjJENjBCNDI5ZjllMjU3RkMwQmM1OEVmMjIzNzc3NkREOTFCL2dldFJldm9rZWRTdGF0dXM_YWRkcmVzcz0weGEyN0YzMDA2MjFhNzQ3NEE2OGZkNWE0MTdEOTU2MGQyNGY5ZDlGNzQmbGlzdElkPTI1NTY2NDQyMTE3NjM3OCJ9LCJsaW5rQ29kZUNvbW1pdG1lbnQiOnsidHlwZSI6IlZlbG9jaXR5Q3JlZGVudGlhbExpbmtDb2RlQ29tbWl0bWVudDIwMjIiLCJ2YWx1ZSI6IkVpQllYTitwRWtMQ0dqdE12WkdCTWo2bVFRZU50UzZpYUQ2RTZaZGh0Qzk4Tmc9PSJ9LCJpc3N1ZXIiOnsiaWQiOiJkaWQ6aW9uOkVpQXBNTGRNYjROUGI4c2FlOS1oWEdIUDc5VzFnaXNBcFZTRTgwVVNQRWJ0SkEifSwiY29udGVudEhhc2giOnsidHlwZSI6IlZlbG9jaXR5Q29udGVudEhhc2gyMDIwIiwidmFsdWUiOiJlNjExMWQ3MjU1OWI4NDQ0OGVlM2M4NDRkNGQzZGFmYWE2M2NmOTcwOTFlZTIwM2M2OGUyNTdmYWI5Y2YwMzM3In0sImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2RldnJlZ2lzdHJhci52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi9zY2hlbWFzL29wZW4tYmFkZ2UtdjIuMC5zY2hlbWEuanNvbiIsInR5cGUiOiJKc29uU2NoZW1hVmFsaWRhdG9yMjAxOCJ9LCJ2bmZQcm90b2NvbFZlcnNpb24iOjEsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9kZXZsaWIudmVsb2NpdHluZXR3b3JrLmZvdW5kYXRpb24vY29udGV4dHMvY3JlZGVudGlhbC1leHRlbnNpb25zLTIwMjIuanNvbmxkLmpzb24iXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaGFzQ3JlZGVudGlhbCI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuanNvbiIsInR5cGUiOiJCYWRnZUNsYXNzIiwibmFtZSI6IlZlbG9jaXR5IEJhZGdlIiwiZGVzY3JpcHRpb24iOiJGb3IgaXNzdWluZyBhIEJhZGdlIG9uIHRoZSBWZWxvY2l0eSBOZXR3b3JrIiwiaW1hZ2UiOiJodHRwczovL3d3dy52ZWxvY2l0eW5ldHdvcmsuZm91bmRhdGlvbi93cC1jb250ZW50L3VwbG9hZHMvMjAyMC8wMi9mYi5qcGciLCJjcml0ZXJpYSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdmVsb2NpdHktYmFkZ2UuaHRtbCIsImlzc3VlciI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSJ9LCJ0eXBlIjoiQmFkZ2UiLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdfX0sIm5iZiI6MTY5NjE2MzQ0MywianRpIjoiZGlkOnZlbG9jaXR5OnYyOjB4YTI3ZjMwMDYyMWE3NDc0YTY4ZmQ1YTQxN2Q5NTYwZDI0ZjlkOWY3NDo1Njg5ODA1MTUzNDY3OToyOTg1IiwiaXNzIjoiZGlkOmlvbjpFaUFwTUxkTWI0TlBiOHNhZTktaFhHSFA3OVcxZ2lzQXBWU0U4MFVTUEVidEpBIiwiaWF0IjoxNjk2MTYzNDQzfQ.17acEH7Qn3XOg9RpVqY9TDV64F6Kyw9hNo2R7FT2-Jv8JmnkNU0n4KbCuV2ZiU95qMM5yvgzRF3hcFYkDHmmFQ',
39
+ },
40
+ ],
41
+ };
42
+
43
+ module.exports = {
44
+ mockAcceptedCredentials,
45
+ mockAcceptedEmptyCredentials,
46
+ mockAcceptedFailedCredentials,
47
+ };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Created by Michael Avoyan on 06/08/2024.
3
+ *
4
+ * Copyright 2022 Velocity Career Labs inc.
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+ const credentialManifestPresentation = {
8
+ $schema: 'http://json-schema.org/draft-07/schema#',
9
+ $id: 'https://velocitycareerlabs.io/credential-manifest.schema.json',
10
+ title: 'credential-manifest',
11
+ description: 'The schema for credential manifest to issue credentials',
12
+ type: 'object',
13
+ exchange_id: 'exchange-56789',
14
+ metadata: {
15
+ client_name: 'Acme Corporation',
16
+ logo_uri: 'https://acme-corp.com/logo.png',
17
+ tos_uri: 'https://acme-corp.com/terms',
18
+ max_retention_period: '90 days',
19
+ progress_uri: 'https://acme-corp.com/progress',
20
+ submit_presentation_uri: 'https://acme-corp.com/submit',
21
+ check_offers_uri: 'https://acme-corp.com/check-offers',
22
+ finalize_offers_uri: 'https://acme-corp.com/finalize-offers',
23
+ },
24
+ presentation_definition: {
25
+ id: 'presentation-def-101',
26
+ purpose: 'Verify employment history',
27
+ name: 'Employment Verification',
28
+ format: {
29
+ jwt_vp: {
30
+ alg: ['ES256K'],
31
+ },
32
+ },
33
+ input_descriptors: [
34
+ {
35
+ id: 'input-desc-1',
36
+ name: 'Employment Credential',
37
+ schema: [
38
+ {
39
+ uri: 'https://schemas.acme-corp.com/employment-credential',
40
+ },
41
+ ],
42
+ group: ['employment-credentials'],
43
+ },
44
+ ],
45
+ submission_requirements: [
46
+ {
47
+ rule: 'pick',
48
+ from: 'employment-credentials',
49
+ min: 1,
50
+ },
51
+ ],
52
+ },
53
+ output_descriptors: [
54
+ {
55
+ id: 'output-desc-1',
56
+ name: 'Verified Employment Credential',
57
+ },
58
+ ],
59
+ issuer: {
60
+ id: 'issuer-001',
61
+ name: 'Acme Credential Issuer',
62
+ },
63
+ aud: 'client-001',
64
+ nbf: 1691246400,
65
+ iss: 'issuer-001',
66
+ exp: 1722782400,
67
+ iat: 1691246400,
68
+ };
69
+
70
+ module.exports = {
71
+ mockData: credentialManifestPresentation,
72
+ };
@@ -0,0 +1,45 @@
1
+ /* eslint-disable max-len */
2
+ // const {
3
+ // credentialManifestPresentation,
4
+ // } = require('./credential-manifest-presentation');
5
+
6
+ const {
7
+ VCLVerifiedProfile,
8
+ VCLJwt,
9
+ VCLDeepLink,
10
+ VCLCredentialManifest,
11
+ } = require('@velocitycareerlabs/vnf-nodejs-wallet-sdk');
12
+
13
+ const mockCredentialManifest = {
14
+ jwt: {
15
+ signedJwt: {
16
+ header:
17
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6aW9uOkVpQXBNTGRNYjROUGI4c2FlOS1oWEdIUDc5VzFnaXNBcFZTRTgwVVNQRWJ0SkEjZXhjaGFuZ2Uta2V5LTEifQ',
18
+ payload:
19
+ 'eyJleGNoYW5nZV9pZCI6IjY1MGMyYTU4Y2VhM2IzYTUzYjFiYjFlZiIsIm1ldGFkYXRhIjp7ImNsaWVudF9uYW1lIjoiVW5pdmVyc2l0eSBvZiBNYXNzYWNodXNldHRzIEFtaGVyc3QiLCJsb2dvX3VyaSI6Imh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvNC80Zi9VTWFzc19TZWFsX01lZGl1bV9QTVNfMjAyLnBuZyIsInRvc191cmkiOiJodHRwczovL3d3dy52ZWxvY2l0eWV4cGVyaWVuY2VjZW50ZXIuY29tL3Rlcm1zLWFuZC1jb25kaXRpb25zLXZuZiIsIm1heF9yZXRlbnRpb25fcGVyaW9kIjoiNm0iLCJwcm9ncmVzc191cmkiOiJodHRwczovL2RldmFnZW50LnZlbG9jaXR5Y2FyZWVybGFicy5pby9hcGkvaG9sZGVyL3YwLjYvb3JnL2RpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQS9nZXQtZXhjaGFuZ2UtcHJvZ3Jlc3MiLCJzdWJtaXRfcHJlc2VudGF0aW9uX3VyaSI6Imh0dHBzOi8vZGV2YWdlbnQudmVsb2NpdHljYXJlZXJsYWJzLmlvL2FwaS9ob2xkZXIvdjAuNi9vcmcvZGlkOmlvbjpFaUFwTUxkTWI0TlBiOHNhZTktaFhHSFA3OVcxZ2lzQXBWU0U4MFVTUEVidEpBL2lzc3VlL3N1Ym1pdC1pZGVudGlmaWNhdGlvbiIsImNoZWNrX29mZmVyc191cmkiOiJodHRwczovL2RldmFnZW50LnZlbG9jaXR5Y2FyZWVybGFicy5pby9hcGkvaG9sZGVyL3YwLjYvb3JnL2RpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQS9pc3N1ZS9jcmVkZW50aWFsLW9mZmVycyIsImZpbmFsaXplX29mZmVyc191cmkiOiJodHRwczovL2RldmFnZW50LnZlbG9jaXR5Y2FyZWVybGFicy5pby9hcGkvaG9sZGVyL3YwLjYvb3JnL2RpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQS9pc3N1ZS9maW5hbGl6ZS1vZmZlcnMifSwicHJlc2VudGF0aW9uX2RlZmluaXRpb24iOnsiaWQiOiI2NTBjMmE1OGNlYTNiM2E1M2IxYmIxZWYuNjM4NGEzYWQxNDhiMTk5MTY4N2Y2N2M5IiwicHVycG9zZSI6IkNyZWRlbnRpYWxzIG9mZmVyIiwibmFtZSI6IlNoYXJlIHlvdXIgSWQsIEVtYWlsIGFuZCBQaG9uZSBOdW1iZXIgdG8gZmFjaWxpdGF0ZSB0aGUgc2VhcmNoIGZvciB5b3VyIGNhcmVlciBjcmVkZW50aWFscyIsImZvcm1hdCI6eyJqd3RfdnAiOnsiYWxnIjpbInNlY3AyNTZrMSJdfX0sImlucHV0X2Rlc2NyaXB0b3JzIjpbeyJpZCI6IkVtYWlsVjEuMCIsIm5hbWUiOiJFbWFpbCIsInNjaGVtYSI6W3sidXJpIjoiaHR0cHM6Ly9kZXZyZWdpc3RyYXIudmVsb2NpdHluZXR3b3JrLmZvdW5kYXRpb24vc2NoZW1hcy9lbWFpbC12MS4wLnNjaGVtYS5qc29uIn1dLCJncm91cCI6WyJBIl19XSwic3VibWlzc2lvbl9yZXF1aXJlbWVudHMiOlt7InJ1bGUiOiJhbGwiLCJmcm9tIjoiQSIsIm1pbiI6MX1dfSwib3V0cHV0X2Rlc2NyaXB0b3JzIjpbeyJpZCI6Ik9wZW5CYWRnZVYyLjAiLCJuYW1lIjoiQmFkZ2UiLCJzY2hlbWEiOlt7InVyaSI6Imh0dHBzOi8vZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uL3NjaGVtYXMvb3Blbi1iYWRnZS12Mi4wLnNjaGVtYS5qc29uIn1dLCJkaXNwbGF5Ijp7InRpdGxlIjp7InBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLmlzc3Vlci5uYW1lIiwiJC5oYXNDcmVkZW50aWFsLmlzc3Vlci5pZCIsIiQuaGFzQ3JlZGVudGlhbC5pc3N1ZXIiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifSwiZmFsbGJhY2siOiItIn0sInN1YnRpdGxlIjp7InRleHQiOiJPcGVuIEJhZGdlIn0sInN1bW1hcnlfZGV0YWlsIjp7InBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLm5hbWUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifSwiZmFsbGJhY2siOiItIn0sImRlc2NyaXB0aW9uIjp7InRleHQiOiJPcGVuIGJhZGdlIn0sImxvZ28iOnsicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwuaW1hZ2UiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmciLCJmb3JtYXQiOiJ1cmkifX0sInByb3BlcnRpZXMiOlt7ImxhYmVsIjoiQmFkZ2UgbmFtZSIsInBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLm5hbWUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifSwiZmFsbGJhY2siOiItIn0seyJsYWJlbCI6IiIsInBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLmltYWdlIl0sInNjaGVtYSI6eyJ0eXBlIjoic3RyaW5nIn19LHsibGFiZWwiOiJEZXNjcmlwdGlvbiIsInBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLmRlc2NyaXB0aW9uIl0sInNjaGVtYSI6eyJ0eXBlIjoic3RyaW5nIn19LHsibGFiZWwiOiJUeXBlIiwicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwudHlwZSJdLCJzY2hlbWEiOnsidHlwZSI6InN0cmluZyJ9fSx7ImxhYmVsIjoiQ3JpdGVyaWEiLCJwYXRoIjpbIiQuaGFzQ3JlZGVudGlhbC5jcml0ZXJpYSIsIiQuaGFzQ3JlZGVudGlhbC5jcml0ZXJpYS5uYXJyYXRpdmUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifX0seyJsYWJlbCI6IlRhZ3MiLCJwYXRoIjpbIiQuaGFzQ3JlZGVudGlhbC50YWdzIl0sInNjaGVtYSI6eyJ0eXBlIjoiYXJyYXkiLCJpdGVtcyI6eyJ0eXBlIjoic3RyaW5nIn19fSx7ImxhYmVsIjoiQWxpZ25tZW50IiwicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwuYWxpZ25tZW50WzBdLnRhcmdldE5hbWUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifX0seyJsYWJlbCI6IkFsaWdubWVudCBVUkwiLCJwYXRoIjpbIiQuaGFzQ3JlZGVudGlhbC5hbGlnbm1lbnRbMF0udGFyZ2V0VXJsIl0sInNjaGVtYSI6eyJ0eXBlIjoic3RyaW5nIiwiZm9ybWF0IjoidXJpIn19LHsibGFiZWwiOiJBbGlnbm1lbnQgZnJhbWV3b3JrIiwicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwuYWxpZ25tZW50WzBdLnRhcmdldEZyYW1ld29yayJdLCJzY2hlbWEiOnsidHlwZSI6InN0cmluZyJ9fV19fV0sImlzc3VlciI6eyJpZCI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSJ9LCJuYmYiOjE2OTU4MDM1OTAsImlzcyI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSIsImV4cCI6MTY5NjQwODM5MCwiaWF0IjoxNjk1ODAzNTkwfQ',
20
+ signature:
21
+ '6qzFfXURbJGleXvJNztjjIw-ucWfKaWCDDqHuN745B3XJF1kJh3phRQy39oDn4V2tTgykGipjJUzckzgDFVTgw',
22
+ },
23
+ encodedJwt:
24
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6aW9uOkVpQXBNTGRNYjROUGI4c2FlOS1oWEdIUDc5VzFnaXNBcFZTRTgwVVNQRWJ0SkEjZXhjaGFuZ2Uta2V5LTEifQ.eyJleGNoYW5nZV9pZCI6IjY1MGMyYTU4Y2VhM2IzYTUzYjFiYjFlZiIsIm1ldGFkYXRhIjp7ImNsaWVudF9uYW1lIjoiVW5pdmVyc2l0eSBvZiBNYXNzYWNodXNldHRzIEFtaGVyc3QiLCJsb2dvX3VyaSI6Imh0dHBzOi8vdXBsb2FkLndpa2ltZWRpYS5vcmcvd2lraXBlZGlhL2NvbW1vbnMvNC80Zi9VTWFzc19TZWFsX01lZGl1bV9QTVNfMjAyLnBuZyIsInRvc191cmkiOiJodHRwczovL3d3dy52ZWxvY2l0eWV4cGVyaWVuY2VjZW50ZXIuY29tL3Rlcm1zLWFuZC1jb25kaXRpb25zLXZuZiIsIm1heF9yZXRlbnRpb25fcGVyaW9kIjoiNm0iLCJwcm9ncmVzc191cmkiOiJodHRwczovL2RldmFnZW50LnZlbG9jaXR5Y2FyZWVybGFicy5pby9hcGkvaG9sZGVyL3YwLjYvb3JnL2RpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQS9nZXQtZXhjaGFuZ2UtcHJvZ3Jlc3MiLCJzdWJtaXRfcHJlc2VudGF0aW9uX3VyaSI6Imh0dHBzOi8vZGV2YWdlbnQudmVsb2NpdHljYXJlZXJsYWJzLmlvL2FwaS9ob2xkZXIvdjAuNi9vcmcvZGlkOmlvbjpFaUFwTUxkTWI0TlBiOHNhZTktaFhHSFA3OVcxZ2lzQXBWU0U4MFVTUEVidEpBL2lzc3VlL3N1Ym1pdC1pZGVudGlmaWNhdGlvbiIsImNoZWNrX29mZmVyc191cmkiOiJodHRwczovL2RldmFnZW50LnZlbG9jaXR5Y2FyZWVybGFicy5pby9hcGkvaG9sZGVyL3YwLjYvb3JnL2RpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQS9pc3N1ZS9jcmVkZW50aWFsLW9mZmVycyIsImZpbmFsaXplX29mZmVyc191cmkiOiJodHRwczovL2RldmFnZW50LnZlbG9jaXR5Y2FyZWVybGFicy5pby9hcGkvaG9sZGVyL3YwLjYvb3JnL2RpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQS9pc3N1ZS9maW5hbGl6ZS1vZmZlcnMifSwicHJlc2VudGF0aW9uX2RlZmluaXRpb24iOnsiaWQiOiI2NTBjMmE1OGNlYTNiM2E1M2IxYmIxZWYuNjM4NGEzYWQxNDhiMTk5MTY4N2Y2N2M5IiwicHVycG9zZSI6IkNyZWRlbnRpYWxzIG9mZmVyIiwibmFtZSI6IlNoYXJlIHlvdXIgSWQsIEVtYWlsIGFuZCBQaG9uZSBOdW1iZXIgdG8gZmFjaWxpdGF0ZSB0aGUgc2VhcmNoIGZvciB5b3VyIGNhcmVlciBjcmVkZW50aWFscyIsImZvcm1hdCI6eyJqd3RfdnAiOnsiYWxnIjpbInNlY3AyNTZrMSJdfX0sImlucHV0X2Rlc2NyaXB0b3JzIjpbeyJpZCI6IkVtYWlsVjEuMCIsIm5hbWUiOiJFbWFpbCIsInNjaGVtYSI6W3sidXJpIjoiaHR0cHM6Ly9kZXZyZWdpc3RyYXIudmVsb2NpdHluZXR3b3JrLmZvdW5kYXRpb24vc2NoZW1hcy9lbWFpbC12MS4wLnNjaGVtYS5qc29uIn1dLCJncm91cCI6WyJBIl19XSwic3VibWlzc2lvbl9yZXF1aXJlbWVudHMiOlt7InJ1bGUiOiJhbGwiLCJmcm9tIjoiQSIsIm1pbiI6MX1dfSwib3V0cHV0X2Rlc2NyaXB0b3JzIjpbeyJpZCI6Ik9wZW5CYWRnZVYyLjAiLCJuYW1lIjoiQmFkZ2UiLCJzY2hlbWEiOlt7InVyaSI6Imh0dHBzOi8vZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uL3NjaGVtYXMvb3Blbi1iYWRnZS12Mi4wLnNjaGVtYS5qc29uIn1dLCJkaXNwbGF5Ijp7InRpdGxlIjp7InBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLmlzc3Vlci5uYW1lIiwiJC5oYXNDcmVkZW50aWFsLmlzc3Vlci5pZCIsIiQuaGFzQ3JlZGVudGlhbC5pc3N1ZXIiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifSwiZmFsbGJhY2siOiItIn0sInN1YnRpdGxlIjp7InRleHQiOiJPcGVuIEJhZGdlIn0sInN1bW1hcnlfZGV0YWlsIjp7InBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLm5hbWUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifSwiZmFsbGJhY2siOiItIn0sImRlc2NyaXB0aW9uIjp7InRleHQiOiJPcGVuIGJhZGdlIn0sImxvZ28iOnsicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwuaW1hZ2UiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmciLCJmb3JtYXQiOiJ1cmkifX0sInByb3BlcnRpZXMiOlt7ImxhYmVsIjoiQmFkZ2UgbmFtZSIsInBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLm5hbWUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifSwiZmFsbGJhY2siOiItIn0seyJsYWJlbCI6IiIsInBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLmltYWdlIl0sInNjaGVtYSI6eyJ0eXBlIjoic3RyaW5nIn19LHsibGFiZWwiOiJEZXNjcmlwdGlvbiIsInBhdGgiOlsiJC5oYXNDcmVkZW50aWFsLmRlc2NyaXB0aW9uIl0sInNjaGVtYSI6eyJ0eXBlIjoic3RyaW5nIn19LHsibGFiZWwiOiJUeXBlIiwicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwudHlwZSJdLCJzY2hlbWEiOnsidHlwZSI6InN0cmluZyJ9fSx7ImxhYmVsIjoiQ3JpdGVyaWEiLCJwYXRoIjpbIiQuaGFzQ3JlZGVudGlhbC5jcml0ZXJpYSIsIiQuaGFzQ3JlZGVudGlhbC5jcml0ZXJpYS5uYXJyYXRpdmUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifX0seyJsYWJlbCI6IlRhZ3MiLCJwYXRoIjpbIiQuaGFzQ3JlZGVudGlhbC50YWdzIl0sInNjaGVtYSI6eyJ0eXBlIjoiYXJyYXkiLCJpdGVtcyI6eyJ0eXBlIjoic3RyaW5nIn19fSx7ImxhYmVsIjoiQWxpZ25tZW50IiwicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwuYWxpZ25tZW50WzBdLnRhcmdldE5hbWUiXSwic2NoZW1hIjp7InR5cGUiOiJzdHJpbmcifX0seyJsYWJlbCI6IkFsaWdubWVudCBVUkwiLCJwYXRoIjpbIiQuaGFzQ3JlZGVudGlhbC5hbGlnbm1lbnRbMF0udGFyZ2V0VXJsIl0sInNjaGVtYSI6eyJ0eXBlIjoic3RyaW5nIiwiZm9ybWF0IjoidXJpIn19LHsibGFiZWwiOiJBbGlnbm1lbnQgZnJhbWV3b3JrIiwicGF0aCI6WyIkLmhhc0NyZWRlbnRpYWwuYWxpZ25tZW50WzBdLnRhcmdldEZyYW1ld29yayJdLCJzY2hlbWEiOnsidHlwZSI6InN0cmluZyJ9fV19fV0sImlzc3VlciI6eyJpZCI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSJ9LCJuYmYiOjE2OTU4MDM1OTAsImlzcyI6ImRpZDppb246RWlBcE1MZE1iNE5QYjhzYWU5LWhYR0hQNzlXMWdpc0FwVlNFODBVU1BFYnRKQSIsImV4cCI6MTY5NjQwODM5MCwiaWF0IjoxNjk1ODAzNTkwfQ.6qzFfXURbJGleXvJNztjjIw-ucWfKaWCDDqHuN745B3XJF1kJh3phRQy39oDn4V2tTgykGipjJUzckzgDFVTgw',
25
+ },
26
+ vendorOriginContext: 'akjndkjsdjkvjnsd',
27
+ };
28
+
29
+ const deepLink =
30
+ // eslint-disable-next-line max-len
31
+ 'velocity-network-devnet://issue?request_uri=https%3A%2F%2Fdevagent.velocitycareerlabs.io%2Fapi%2Fholder%2Fv0.6%2Forg%2Fdid%3Aion%3AEiApMLdMb4NPb8sae9-hXGHP79W1gisApVSE80USPEbtJA%2Fissue%2Fget-credential-manifest%3Fid%3D6384a3ad148b1991687f67c9%26exchange_id%3D650c2a58cea3b3a53b1bb1ef%26credential_types%3DOpenBadgeV2.0%26vendorOriginContext%3Dakjndkjsdjkvjnsd%0A';
32
+ const vclDeepLink = new VCLDeepLink(deepLink);
33
+ const vclMockCredentialManifest = new VCLCredentialManifest(
34
+ VCLJwt.fromEncodedJwt(mockCredentialManifest.jwt.encodedJwt),
35
+ vclDeepLink.vendorOriginContext,
36
+ new VCLVerifiedProfile({ some: 'thing' }),
37
+ vclDeepLink,
38
+ null
39
+ );
40
+
41
+ module.exports = {
42
+ mockCredentialManifest,
43
+ vclMockCredentialManifest,
44
+ deepLink,
45
+ };