@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,198 @@
1
+ /**
2
+ * Created by Michael Avoyan on 31/07/2024.
3
+ *
4
+ * Copyright 2022 Velocity Career Labs inc.
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+ const webWalletCredentialManifestSchema = {
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
+ properties: {
14
+ exchange_id: {
15
+ type: 'string',
16
+ description: 'Unique identifier for the exchange',
17
+ },
18
+ metadata: {
19
+ type: 'object',
20
+ description: 'Metadata about the client and exchange',
21
+ properties: {
22
+ client_name: {
23
+ type: 'string',
24
+ description: 'Name of the client',
25
+ },
26
+ logo_uri: {
27
+ type: 'string',
28
+ format: 'uri',
29
+ description: 'URI of the client logo',
30
+ },
31
+ tos_uri: {
32
+ type: 'string',
33
+ format: 'uri',
34
+ description: 'URI of the terms of service',
35
+ },
36
+ max_retention_period: {
37
+ type: 'string',
38
+ description: 'Maximum retention period',
39
+ },
40
+ progress_uri: {
41
+ type: 'string',
42
+ format: 'uri',
43
+ description: 'URI to check the progress of the exchange',
44
+ },
45
+ submit_presentation_uri: {
46
+ type: 'string',
47
+ format: 'uri',
48
+ description: 'URI to submit the presentation',
49
+ },
50
+ check_offers_uri: {
51
+ type: 'string',
52
+ format: 'uri',
53
+ description: 'URI to check credential offers',
54
+ },
55
+ finalize_offers_uri: {
56
+ type: 'string',
57
+ format: 'uri',
58
+ description: 'URI to finalize credential offers',
59
+ },
60
+ },
61
+ required: ['client_name', 'logo_uri', 'tos_uri'],
62
+ },
63
+ presentation_definition: {
64
+ type: 'object',
65
+ description: 'Definition of the presentation required for the exchange',
66
+ properties: {
67
+ id: {
68
+ type: 'string',
69
+ description: 'Unique identifier for the presentation definition',
70
+ },
71
+ purpose: {
72
+ type: 'string',
73
+ description: 'Purpose of the credential issuance',
74
+ },
75
+ name: {
76
+ type: 'string',
77
+ description: 'Name of the presentation definition',
78
+ },
79
+ format: {
80
+ type: 'object',
81
+ description: 'Format details of the presentation',
82
+ properties: {
83
+ jwt_vp: {
84
+ type: 'object',
85
+ properties: {
86
+ alg: {
87
+ type: 'array',
88
+ items: {
89
+ type: 'string',
90
+ },
91
+ },
92
+ },
93
+ },
94
+ },
95
+ },
96
+ input_descriptors: {
97
+ type: 'array',
98
+ items: {
99
+ type: 'object',
100
+ properties: {
101
+ id: {
102
+ type: 'string',
103
+ description: 'Identifier for the input descriptor',
104
+ },
105
+ name: {
106
+ type: 'string',
107
+ description: 'Name of the input descriptor',
108
+ },
109
+ schema: {
110
+ type: 'array',
111
+ items: {
112
+ type: 'object',
113
+ properties: {
114
+ uri: {
115
+ type: 'string',
116
+ format: 'uri',
117
+ description: 'URI of the schema',
118
+ },
119
+ },
120
+ required: ['uri'],
121
+ },
122
+ },
123
+ group: {
124
+ type: 'array',
125
+ items: {
126
+ type: 'string',
127
+ },
128
+ },
129
+ },
130
+ required: ['id', 'schema'],
131
+ },
132
+ },
133
+ submission_requirements: {
134
+ type: 'array',
135
+ items: {
136
+ type: 'object',
137
+ properties: {
138
+ rule: {
139
+ type: 'string',
140
+ description: 'Rule for submission requirements',
141
+ },
142
+ from: {
143
+ type: 'string',
144
+ description: 'Group from which the requirements are fulfilled',
145
+ },
146
+ min: {
147
+ type: 'integer',
148
+ description: 'Minimum number of items required',
149
+ },
150
+ },
151
+ },
152
+ },
153
+ },
154
+ required: ['id', 'input_descriptors'],
155
+ },
156
+ output_descriptors: {
157
+ type: 'array',
158
+ items: {
159
+ type: 'object',
160
+ },
161
+ description: 'Output descriptors of the exchange',
162
+ },
163
+ issuer: {
164
+ type: 'object',
165
+ properties: {
166
+ id: {
167
+ type: 'string',
168
+ description: 'Identifier of the issuer',
169
+ },
170
+ },
171
+ },
172
+ aud: {
173
+ type: 'string',
174
+ description: 'Audience of the credential',
175
+ },
176
+ nbf: {
177
+ type: 'integer',
178
+ description: 'Not before time for the exchange',
179
+ },
180
+ iss: {
181
+ type: 'string',
182
+ description: 'Issuer of the exchange',
183
+ },
184
+ exp: {
185
+ type: 'integer',
186
+ description: 'Expiration time of the exchange',
187
+ },
188
+ iat: {
189
+ type: 'integer',
190
+ description: 'Issued at time of the exchange',
191
+ },
192
+ },
193
+ required: ['metadata', 'exchange_id', 'presentation_definition'],
194
+ };
195
+
196
+ module.exports = {
197
+ webWalletCredentialManifestSchema,
198
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Created by Michael Avoyan on 12/08/2024.
3
+ *
4
+ * Copyright 2022 Velocity Career Labs inc.
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+
8
+ const WebWalletServerError = 'web_wallet_server_error';
9
+
10
+ module.exports = {
11
+ WebWalletServerError,
12
+ };
@@ -0,0 +1,7 @@
1
+ const createCareerWalletAccount = (payload, { careerWalletFetch }) => {
2
+ return careerWalletFetch.post('api/v0.6/accounts', { json: payload }).json();
3
+ };
4
+
5
+ module.exports = {
6
+ createCareerWalletAccount,
7
+ };
@@ -0,0 +1,17 @@
1
+ const createDidForAccount = (crv, accessToken, { careerWalletFetch }) => {
2
+ return careerWalletFetch
3
+ .post('api/v0.6/create_did_key', {
4
+ json: {
5
+ crv: `${crv}`,
6
+ didMethod: 'did:jwk',
7
+ },
8
+ headers: {
9
+ Authorization: `Bearer ${accessToken}`,
10
+ },
11
+ })
12
+ .json();
13
+ };
14
+
15
+ module.exports = {
16
+ createDidForAccount,
17
+ };
@@ -0,0 +1,11 @@
1
+ const getAppConfig = async ({ careerWalletFetch, cache }) => {
2
+ return careerWalletFetch
3
+ .get('api/v0.6/careerwallet/appconfig', {
4
+ cache,
5
+ })
6
+ .json();
7
+ };
8
+
9
+ module.exports = {
10
+ getAppConfig,
11
+ };
@@ -0,0 +1,13 @@
1
+ const getConsentLatest = (accountId, { careerWalletFetch, config }) => {
2
+ return careerWalletFetch
3
+ .get(`api/v0.6/careerwallet/consents/latest?accountId=${accountId}`, {
4
+ headers: {
5
+ Authorization: `Bearer ${config.careerWalletAdminAccessToken}`,
6
+ },
7
+ })
8
+ .json();
9
+ };
10
+
11
+ module.exports = {
12
+ getConsentLatest,
13
+ };
@@ -0,0 +1,7 @@
1
+ const getCredentialCategories = ({ careerWalletFetch }) => {
2
+ return careerWalletFetch.get('api/v0.6/credential-categories').json();
3
+ };
4
+
5
+ module.exports = {
6
+ getCredentialCategories,
7
+ };
@@ -0,0 +1,7 @@
1
+ const getPersonas = ({ careerWalletFetch, cache }) => {
2
+ return careerWalletFetch.get('reference/personas', { cache }).json();
3
+ };
4
+
5
+ module.exports = {
6
+ getPersonas,
7
+ };
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ ...require('./create-account-fetcher'),
3
+ ...require('./create-did-fetcher'),
4
+ ...require('./get-credential-categories'),
5
+ ...require('./verify-id-credential-request-code'),
6
+ ...require('./verify-id-credential-confirm-code'),
7
+ ...require('./get-app-config'),
8
+ ...require('./get-consents'),
9
+ ...require('./get-personas'),
10
+ ...require('./post-consent'),
11
+ ...require('./send-feedback'),
12
+ };
@@ -0,0 +1,9 @@
1
+ const postConsent = (payload, authorization, { careerWalletFetch }) => {
2
+ return careerWalletFetch
3
+ .post('api/v0.6/careerwallet/consents/add', { json: payload })
4
+ .json();
5
+ };
6
+
7
+ module.exports = {
8
+ postConsent,
9
+ };
@@ -0,0 +1,14 @@
1
+ const sendFeedback = (payload, { careerWalletFetch, config }) => {
2
+ return careerWalletFetch
3
+ .post('api/v0.6/feedback', {
4
+ json: payload,
5
+ headers: {
6
+ Authorization: `Bearer ${config.careerWalletAdminAccessToken}`,
7
+ },
8
+ })
9
+ .json();
10
+ };
11
+
12
+ module.exports = {
13
+ sendFeedback,
14
+ };
@@ -0,0 +1,14 @@
1
+ const signFetcher = (payload, accessToken, { careerWalletFetch }) => {
2
+ return careerWalletFetch
3
+ .post('api/v0.6/jwt/sign', {
4
+ json: { ...payload },
5
+ headers: {
6
+ Authorization: `Bearer ${accessToken}`,
7
+ },
8
+ })
9
+ .json();
10
+ };
11
+
12
+ module.exports = {
13
+ signFetcher,
14
+ };
@@ -0,0 +1,19 @@
1
+ const verifyIdCredentialConfirmCode = async (
2
+ verificationCode,
3
+ { careerWalletFetch, cache, config }
4
+ ) => {
5
+ return careerWalletFetch
6
+ .post('api/v0.6/verify/confirm', {
7
+ json: { verificationCode },
8
+ headers: {
9
+ 'x-vcl-verif-version': config.vclVerificationVersion,
10
+ Authorization: `Bearer ${config.careerWalletAdminAccessToken}`,
11
+ },
12
+ cache,
13
+ })
14
+ .json();
15
+ };
16
+
17
+ module.exports = {
18
+ verifyIdCredentialConfirmCode,
19
+ };
@@ -0,0 +1,20 @@
1
+ const verifyIdCredentialRequestCode = async (
2
+ credentialType,
3
+ value,
4
+ { careerWalletFetch, cache, config }
5
+ ) => {
6
+ return careerWalletFetch
7
+ .post(`api/v0.6/verify/${credentialType}/request-code`, {
8
+ json: { value },
9
+ headers: {
10
+ 'x-vcl-verif-version': config.vclVerificationVersion,
11
+ Authorization: `Bearer ${config.careerWalletAdminAccessToken}`,
12
+ },
13
+ cache,
14
+ })
15
+ .json();
16
+ };
17
+
18
+ module.exports = {
19
+ verifyIdCredentialRequestCode,
20
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ ...require('./career-wallet'),
3
+ ...require('./lib-api'),
4
+ };
@@ -0,0 +1,12 @@
1
+ const getCredentialDisplaySchema = async (
2
+ credentialType,
3
+ { libFetch, cache }
4
+ ) => {
5
+ return libFetch
6
+ .get(`display-descriptors/${credentialType}.descriptor.json`, { cache })
7
+ .json();
8
+ };
9
+
10
+ module.exports = {
11
+ getCredentialDisplaySchema,
12
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ ...require('./get-credential-display-schema'),
3
+ };
@@ -0,0 +1,45 @@
1
+ const createLinkedinPost = (
2
+ { accessToken, linkedinUserId, text, asset },
3
+ { linkedInFetch }
4
+ ) => {
5
+ return linkedInFetch
6
+ .post('ugcPosts', {
7
+ headers: {
8
+ 'Content-Type': 'application/json',
9
+ 'X-Restli-Protocol-Version': '2.0.0',
10
+ Authorization: `Bearer ${accessToken}`,
11
+ },
12
+ json: {
13
+ author: `urn:li:person:${linkedinUserId}`,
14
+ lifecycleState: 'PUBLISHED',
15
+ specificContent: {
16
+ 'com.linkedin.ugc.ShareContent': {
17
+ shareCommentary: {
18
+ text,
19
+ },
20
+ ...(asset
21
+ ? {
22
+ shareMediaCategory: 'IMAGE',
23
+ media: [
24
+ {
25
+ status: 'READY',
26
+ media: asset,
27
+ },
28
+ ],
29
+ }
30
+ : {
31
+ shareMediaCategory: 'NONE',
32
+ }),
33
+ },
34
+ },
35
+ visibility: {
36
+ 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC',
37
+ },
38
+ },
39
+ })
40
+ .json();
41
+ };
42
+
43
+ module.exports = {
44
+ createLinkedinPost,
45
+ };
@@ -0,0 +1,26 @@
1
+ const getLinkedInAccessToken = (
2
+ { code, redirectUri },
3
+ { config, linkedInAuthFetch }
4
+ ) => {
5
+ return linkedInAuthFetch
6
+ .post('accessToken', {
7
+ headers: {
8
+ 'Content-Type': ' application/x-www-form-urlencoded',
9
+ },
10
+ body: String(
11
+ new URLSearchParams({
12
+ code,
13
+ redirect_uri:
14
+ redirectUri || `${config.webWalletBaseUrl}/share-to-linkedin`,
15
+ client_id: config.linkedIn.clientId,
16
+ client_secret: config.linkedIn.clientSecret,
17
+ grant_type: 'authorization_code',
18
+ })
19
+ ),
20
+ })
21
+ .json();
22
+ };
23
+
24
+ module.exports = {
25
+ getLinkedInAccessToken,
26
+ };
@@ -0,0 +1,13 @@
1
+ const getLinkedInUserEmail = (accessToken, { linkedInFetch }) => {
2
+ return linkedInFetch
3
+ .get('emailAddress?q=members&projection=(elements*(handle~))', {
4
+ headers: {
5
+ Authorization: `Bearer ${accessToken}`,
6
+ },
7
+ })
8
+ .json();
9
+ };
10
+
11
+ module.exports = {
12
+ getLinkedInUserEmail,
13
+ };
@@ -0,0 +1,16 @@
1
+ const getLinkedInUserId = (accessToken, { linkedInFetch }) => {
2
+ return linkedInFetch
3
+ .get(
4
+ 'me?projection=(id,localizedFirstName,localizedLastName,profilePicture(displayImage~digitalmediaAsset:playableStreams))',
5
+ {
6
+ headers: {
7
+ Authorization: `Bearer ${accessToken}`,
8
+ },
9
+ }
10
+ )
11
+ .json();
12
+ };
13
+
14
+ module.exports = {
15
+ getLinkedInUserId,
16
+ };
@@ -0,0 +1,9 @@
1
+ module.exports = {
2
+ ...require('./get-access-token'),
3
+ ...require('./get-linkedin-user-id'),
4
+ ...require('./get-linkedin-user-email'),
5
+ ...require('./register-image-to-upload'),
6
+ ...require('./upload-image-to-linkedin'),
7
+ ...require('./create-linkedin-post'),
8
+ ...require('./revoke-linkedin-access'),
9
+ };
@@ -0,0 +1,30 @@
1
+ const registerImageToUpload = (
2
+ { linkedinUserId, accessToken },
3
+ { linkedInFetch }
4
+ ) => {
5
+ return linkedInFetch
6
+ .post('assets?action=registerUpload', {
7
+ headers: {
8
+ 'Content-Type': 'application/json',
9
+ 'X-Restli-Protocol-Version': '2.0.0',
10
+ Authorization: `Bearer ${accessToken}`,
11
+ },
12
+ json: {
13
+ registerUploadRequest: {
14
+ recipes: ['urn:li:digitalmediaRecipe:feedshare-image'],
15
+ owner: `urn:li:person:${linkedinUserId}`,
16
+ serviceRelationships: [
17
+ {
18
+ relationshipType: 'OWNER',
19
+ identifier: 'urn:li:userGeneratedContent',
20
+ },
21
+ ],
22
+ },
23
+ },
24
+ })
25
+ .json();
26
+ };
27
+
28
+ module.exports = {
29
+ registerImageToUpload,
30
+ };
@@ -0,0 +1,20 @@
1
+ const revokeLinkedinAccess = (accessToken, { config, linkedInAuthFetch }) => {
2
+ return linkedInAuthFetch
3
+ .post('revoke', {
4
+ headers: {
5
+ 'Content-Type': ' application/x-www-form-urlencoded',
6
+ },
7
+ body: String(
8
+ new URLSearchParams({
9
+ client_id: config.linkedIn.clientId,
10
+ client_secret: config.linkedIn.clientSecret,
11
+ token: accessToken,
12
+ })
13
+ ),
14
+ })
15
+ .json();
16
+ };
17
+
18
+ module.exports = {
19
+ revokeLinkedinAccess,
20
+ };
@@ -0,0 +1,16 @@
1
+ const { default: got } = require('got');
2
+
3
+ const uploadImageToLinkedin = ({ accessToken, uploadUrl, file }) => {
4
+ return got
5
+ .post(uploadUrl, {
6
+ headers: {
7
+ Authorization: `Bearer ${accessToken}`,
8
+ },
9
+ body: file,
10
+ })
11
+ .json();
12
+ };
13
+
14
+ module.exports = {
15
+ uploadImageToLinkedin,
16
+ };
package/src/index.js ADDED
@@ -0,0 +1,15 @@
1
+ const {
2
+ createServer,
3
+ listenServer,
4
+ } = require('@velocitycareerlabs/server-provider');
5
+ const { flow } = require('lodash/fp');
6
+ const config = require('./config/config');
7
+ const { initServer } = require('./init-server');
8
+
9
+ /* istanbul ignore next */
10
+ process.on('unhandledRejection', (error) => {
11
+ console.error(error);
12
+ process.exit(1);
13
+ });
14
+
15
+ flow(createServer, initServer, listenServer)(config);