@ajna-inc/openbadges 0.1.0

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 (224) hide show
  1. package/LICENSE +202 -0
  2. package/build/OpenBadgesModule.d.ts +10 -0
  3. package/build/OpenBadgesModule.js +75 -0
  4. package/build/OpenBadgesModule.js.map +1 -0
  5. package/build/OpenBadgesModuleConfig.d.ts +96 -0
  6. package/build/OpenBadgesModuleConfig.js +50 -0
  7. package/build/OpenBadgesModuleConfig.js.map +1 -0
  8. package/build/api/OpenBadgesApi.d.ts +48 -0
  9. package/build/api/OpenBadgesApi.js +81 -0
  10. package/build/api/OpenBadgesApi.js.map +1 -0
  11. package/build/api/index.d.ts +1 -0
  12. package/build/api/index.js +18 -0
  13. package/build/api/index.js.map +1 -0
  14. package/build/constants.d.ts +12 -0
  15. package/build/constants.js +27 -0
  16. package/build/constants.js.map +1 -0
  17. package/build/cryptosuites/EcdsaSd2023.d.ts +143 -0
  18. package/build/cryptosuites/EcdsaSd2023.js +518 -0
  19. package/build/cryptosuites/EcdsaSd2023.js.map +1 -0
  20. package/build/cryptosuites/EddsaRdfc2022.d.ts +112 -0
  21. package/build/cryptosuites/EddsaRdfc2022.js +356 -0
  22. package/build/cryptosuites/EddsaRdfc2022.js.map +1 -0
  23. package/build/cryptosuites/constants.d.ts +14 -0
  24. package/build/cryptosuites/constants.js +22 -0
  25. package/build/cryptosuites/constants.js.map +1 -0
  26. package/build/cryptosuites/contextPreprocessor.d.ts +24 -0
  27. package/build/cryptosuites/contextPreprocessor.js +127 -0
  28. package/build/cryptosuites/contextPreprocessor.js.map +1 -0
  29. package/build/cryptosuites/dataIntegrityV2Context.d.ts +144 -0
  30. package/build/cryptosuites/dataIntegrityV2Context.js +86 -0
  31. package/build/cryptosuites/dataIntegrityV2Context.js.map +1 -0
  32. package/build/cryptosuites/index.d.ts +11 -0
  33. package/build/cryptosuites/index.js +33 -0
  34. package/build/cryptosuites/index.js.map +1 -0
  35. package/build/http/OpenBadgesHttpModule.d.ts +9 -0
  36. package/build/http/OpenBadgesHttpModule.js +120 -0
  37. package/build/http/OpenBadgesHttpModule.js.map +1 -0
  38. package/build/http/OpenBadgesHttpModuleConfig.d.ts +55 -0
  39. package/build/http/OpenBadgesHttpModuleConfig.js +78 -0
  40. package/build/http/OpenBadgesHttpModuleConfig.js.map +1 -0
  41. package/build/http/endpoints/authorize.d.ts +3 -0
  42. package/build/http/endpoints/authorize.js +79 -0
  43. package/build/http/endpoints/authorize.js.map +1 -0
  44. package/build/http/endpoints/consent.d.ts +3 -0
  45. package/build/http/endpoints/consent.js +25 -0
  46. package/build/http/endpoints/consent.js.map +1 -0
  47. package/build/http/endpoints/credentials.d.ts +4 -0
  48. package/build/http/endpoints/credentials.js +85 -0
  49. package/build/http/endpoints/credentials.js.map +1 -0
  50. package/build/http/endpoints/did.d.ts +3 -0
  51. package/build/http/endpoints/did.js +48 -0
  52. package/build/http/endpoints/did.js.map +1 -0
  53. package/build/http/endpoints/introspect.d.ts +3 -0
  54. package/build/http/endpoints/introspect.js +37 -0
  55. package/build/http/endpoints/introspect.js.map +1 -0
  56. package/build/http/endpoints/jwks.d.ts +3 -0
  57. package/build/http/endpoints/jwks.js +46 -0
  58. package/build/http/endpoints/jwks.js.map +1 -0
  59. package/build/http/endpoints/profile.d.ts +4 -0
  60. package/build/http/endpoints/profile.js +58 -0
  61. package/build/http/endpoints/profile.js.map +1 -0
  62. package/build/http/endpoints/refresh.d.ts +15 -0
  63. package/build/http/endpoints/refresh.js +134 -0
  64. package/build/http/endpoints/refresh.js.map +1 -0
  65. package/build/http/endpoints/registration.d.ts +3 -0
  66. package/build/http/endpoints/registration.js +42 -0
  67. package/build/http/endpoints/registration.js.map +1 -0
  68. package/build/http/endpoints/revoke.d.ts +3 -0
  69. package/build/http/endpoints/revoke.js +38 -0
  70. package/build/http/endpoints/revoke.js.map +1 -0
  71. package/build/http/endpoints/serviceDescription.d.ts +3 -0
  72. package/build/http/endpoints/serviceDescription.js +52 -0
  73. package/build/http/endpoints/serviceDescription.js.map +1 -0
  74. package/build/http/endpoints/statusList.d.ts +10 -0
  75. package/build/http/endpoints/statusList.js +95 -0
  76. package/build/http/endpoints/statusList.js.map +1 -0
  77. package/build/http/endpoints/token.d.ts +3 -0
  78. package/build/http/endpoints/token.js +147 -0
  79. package/build/http/endpoints/token.js.map +1 -0
  80. package/build/http/middleware/auth.d.ts +5 -0
  81. package/build/http/middleware/auth.js +48 -0
  82. package/build/http/middleware/auth.js.map +1 -0
  83. package/build/http/router.d.ts +13 -0
  84. package/build/http/router.js +36 -0
  85. package/build/http/router.js.map +1 -0
  86. package/build/http/tenants.d.ts +2 -0
  87. package/build/http/tenants.js +20 -0
  88. package/build/http/tenants.js.map +1 -0
  89. package/build/http/util/auth.d.ts +8 -0
  90. package/build/http/util/auth.js +43 -0
  91. package/build/http/util/auth.js.map +1 -0
  92. package/build/index.d.ts +46 -0
  93. package/build/index.js +71 -0
  94. package/build/index.js.map +1 -0
  95. package/build/models/ClrCredential.d.ts +112 -0
  96. package/build/models/ClrCredential.js +52 -0
  97. package/build/models/ClrCredential.js.map +1 -0
  98. package/build/models/EndorsementCredential.d.ts +89 -0
  99. package/build/models/EndorsementCredential.js +11 -0
  100. package/build/models/EndorsementCredential.js.map +1 -0
  101. package/build/models/StatusListCredential.d.ts +81 -0
  102. package/build/models/StatusListCredential.js +28 -0
  103. package/build/models/StatusListCredential.js.map +1 -0
  104. package/build/models/index.d.ts +8 -0
  105. package/build/models/index.js +25 -0
  106. package/build/models/index.js.map +1 -0
  107. package/build/repository/OpenBadgeCredentialRecord.d.ts +44 -0
  108. package/build/repository/OpenBadgeCredentialRecord.js +46 -0
  109. package/build/repository/OpenBadgeCredentialRecord.js.map +1 -0
  110. package/build/repository/OpenBadgeCredentialRepository.d.ts +8 -0
  111. package/build/repository/OpenBadgeCredentialRepository.js +38 -0
  112. package/build/repository/OpenBadgeCredentialRepository.js.map +1 -0
  113. package/build/repository/OpenBadgesAuthCodeRecord.d.ts +35 -0
  114. package/build/repository/OpenBadgesAuthCodeRecord.js +28 -0
  115. package/build/repository/OpenBadgesAuthCodeRecord.js.map +1 -0
  116. package/build/repository/OpenBadgesAuthCodeRepository.d.ts +6 -0
  117. package/build/repository/OpenBadgesAuthCodeRepository.js +32 -0
  118. package/build/repository/OpenBadgesAuthCodeRepository.js.map +1 -0
  119. package/build/repository/OpenBadgesConsentRecord.d.ts +24 -0
  120. package/build/repository/OpenBadgesConsentRecord.js +23 -0
  121. package/build/repository/OpenBadgesConsentRecord.js.map +1 -0
  122. package/build/repository/OpenBadgesConsentRepository.d.ts +6 -0
  123. package/build/repository/OpenBadgesConsentRepository.js +32 -0
  124. package/build/repository/OpenBadgesConsentRepository.js.map +1 -0
  125. package/build/repository/OpenBadgesKeyBindingRecord.d.ts +24 -0
  126. package/build/repository/OpenBadgesKeyBindingRecord.js +32 -0
  127. package/build/repository/OpenBadgesKeyBindingRecord.js.map +1 -0
  128. package/build/repository/OpenBadgesKeyBindingRepository.d.ts +7 -0
  129. package/build/repository/OpenBadgesKeyBindingRepository.js +35 -0
  130. package/build/repository/OpenBadgesKeyBindingRepository.js.map +1 -0
  131. package/build/repository/OpenBadgesOAuthRecord.d.ts +35 -0
  132. package/build/repository/OpenBadgesOAuthRecord.js +25 -0
  133. package/build/repository/OpenBadgesOAuthRecord.js.map +1 -0
  134. package/build/repository/OpenBadgesOAuthRepository.d.ts +8 -0
  135. package/build/repository/OpenBadgesOAuthRepository.js +38 -0
  136. package/build/repository/OpenBadgesOAuthRepository.js.map +1 -0
  137. package/build/repository/OpenBadgesProfileRecord.d.ts +21 -0
  138. package/build/repository/OpenBadgesProfileRecord.js +22 -0
  139. package/build/repository/OpenBadgesProfileRecord.js.map +1 -0
  140. package/build/repository/OpenBadgesProfileRepository.d.ts +6 -0
  141. package/build/repository/OpenBadgesProfileRepository.js +32 -0
  142. package/build/repository/OpenBadgesProfileRepository.js.map +1 -0
  143. package/build/repository/OpenBadgesRevocationCacheRecord.d.ts +23 -0
  144. package/build/repository/OpenBadgesRevocationCacheRecord.js +23 -0
  145. package/build/repository/OpenBadgesRevocationCacheRecord.js.map +1 -0
  146. package/build/repository/OpenBadgesRevocationCacheRepository.d.ts +6 -0
  147. package/build/repository/OpenBadgesRevocationCacheRepository.js +32 -0
  148. package/build/repository/OpenBadgesRevocationCacheRepository.js.map +1 -0
  149. package/build/repository/OpenBadgesServiceDescriptionRecord.d.ts +21 -0
  150. package/build/repository/OpenBadgesServiceDescriptionRecord.js +22 -0
  151. package/build/repository/OpenBadgesServiceDescriptionRecord.js.map +1 -0
  152. package/build/repository/OpenBadgesServiceDescriptionRepository.d.ts +6 -0
  153. package/build/repository/OpenBadgesServiceDescriptionRepository.js +32 -0
  154. package/build/repository/OpenBadgesServiceDescriptionRepository.js.map +1 -0
  155. package/build/repository/OpenBadgesTokenRecord.d.ts +39 -0
  156. package/build/repository/OpenBadgesTokenRecord.js +36 -0
  157. package/build/repository/OpenBadgesTokenRecord.js.map +1 -0
  158. package/build/repository/OpenBadgesTokenRepository.d.ts +9 -0
  159. package/build/repository/OpenBadgesTokenRepository.js +45 -0
  160. package/build/repository/OpenBadgesTokenRepository.js.map +1 -0
  161. package/build/repository/StatusListRecord.d.ts +49 -0
  162. package/build/repository/StatusListRecord.js +47 -0
  163. package/build/repository/StatusListRecord.js.map +1 -0
  164. package/build/repository/StatusListRepository.d.ts +24 -0
  165. package/build/repository/StatusListRepository.js +52 -0
  166. package/build/repository/StatusListRepository.js.map +1 -0
  167. package/build/repository/index.d.ts +18 -0
  168. package/build/repository/index.js +35 -0
  169. package/build/repository/index.js.map +1 -0
  170. package/build/services/AchievementValidator.d.ts +158 -0
  171. package/build/services/AchievementValidator.js +238 -0
  172. package/build/services/AchievementValidator.js.map +1 -0
  173. package/build/services/ConsumerService.d.ts +24 -0
  174. package/build/services/ConsumerService.js +143 -0
  175. package/build/services/ConsumerService.js.map +1 -0
  176. package/build/services/ContextService.d.ts +14 -0
  177. package/build/services/ContextService.js +54 -0
  178. package/build/services/ContextService.js.map +1 -0
  179. package/build/services/DataIntegrityService.d.ts +51 -0
  180. package/build/services/DataIntegrityService.js +134 -0
  181. package/build/services/DataIntegrityService.js.map +1 -0
  182. package/build/services/DidCommLinkService.d.ts +7 -0
  183. package/build/services/DidCommLinkService.js +20 -0
  184. package/build/services/DidCommLinkService.js.map +1 -0
  185. package/build/services/DisplayMapper.d.ts +9 -0
  186. package/build/services/DisplayMapper.js +26 -0
  187. package/build/services/DisplayMapper.js.map +1 -0
  188. package/build/services/IssuerService.d.ts +38 -0
  189. package/build/services/IssuerService.js +225 -0
  190. package/build/services/IssuerService.js.map +1 -0
  191. package/build/services/JwtService.d.ts +19 -0
  192. package/build/services/JwtService.js +229 -0
  193. package/build/services/JwtService.js.map +1 -0
  194. package/build/services/KeyService.d.ts +102 -0
  195. package/build/services/KeyService.js +439 -0
  196. package/build/services/KeyService.js.map +1 -0
  197. package/build/services/OAuthClient.d.ts +26 -0
  198. package/build/services/OAuthClient.js +127 -0
  199. package/build/services/OAuthClient.js.map +1 -0
  200. package/build/services/ProofService.d.ts +15 -0
  201. package/build/services/ProofService.js +43 -0
  202. package/build/services/ProofService.js.map +1 -0
  203. package/build/services/RevocationService.d.ts +59 -0
  204. package/build/services/RevocationService.js +319 -0
  205. package/build/services/RevocationService.js.map +1 -0
  206. package/build/services/VerifyService.d.ts +17 -0
  207. package/build/services/VerifyService.js +54 -0
  208. package/build/services/VerifyService.js.map +1 -0
  209. package/build/services/crypto/CryptoDriver.d.ts +9 -0
  210. package/build/services/crypto/CryptoDriver.js +7 -0
  211. package/build/services/crypto/CryptoDriver.js.map +1 -0
  212. package/build/services/crypto/JsonLdCryptoDriver.d.ts +17 -0
  213. package/build/services/crypto/JsonLdCryptoDriver.js +45 -0
  214. package/build/services/crypto/JsonLdCryptoDriver.js.map +1 -0
  215. package/build/services/crypto/JwtCryptoDriver.d.ts +13 -0
  216. package/build/services/crypto/JwtCryptoDriver.js +42 -0
  217. package/build/services/crypto/JwtCryptoDriver.js.map +1 -0
  218. package/build/services/index.d.ts +12 -0
  219. package/build/services/index.js +29 -0
  220. package/build/services/index.js.map +1 -0
  221. package/build/utils/validate.d.ts +17 -0
  222. package/build/utils/validate.js +107 -0
  223. package/build/utils/validate.js.map +1 -0
  224. package/package.json +57 -0
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenBadgesHttpModuleConfig = void 0;
4
+ const router_1 = require("./router");
5
+ class OpenBadgesHttpModuleConfig {
6
+ constructor(options) {
7
+ this.options = options;
8
+ this.router = options.router ?? (0, router_1.importExpress)().Router();
9
+ }
10
+ get baseUrl() {
11
+ return this.options.baseUrl;
12
+ }
13
+ get defaultSubjectId() {
14
+ return this.options.defaultSubjectId;
15
+ }
16
+ get discoveryPath() {
17
+ return this.options.endpoints?.discovery ?? '/ims/ob/v3p0/discovery';
18
+ }
19
+ get jwksPath() {
20
+ return this.options.endpoints?.jwks ?? '/.well-known/jwks.json';
21
+ }
22
+ get didDocumentPath() {
23
+ return this.options.endpoints?.didDocument ?? '/.well-known/did.json';
24
+ }
25
+ get registrationPath() {
26
+ return this.options.endpoints?.registration ?? '/connect/register';
27
+ }
28
+ get authorizePath() {
29
+ return this.options.endpoints?.authorize ?? '/authorize';
30
+ }
31
+ get tokenPath() {
32
+ return this.options.endpoints?.token ?? '/token';
33
+ }
34
+ get revokePath() {
35
+ return this.options.endpoints?.revoke ?? '/revoke';
36
+ }
37
+ get introspectPath() {
38
+ return this.options.endpoints?.introspect ?? '/introspect';
39
+ }
40
+ get profilePath() {
41
+ return this.options.endpoints?.profile ?? '/ims/ob/v3p0/profile';
42
+ }
43
+ get credentialsPath() {
44
+ return this.options.endpoints?.credentials ?? '/ims/ob/v3p0/credentials';
45
+ }
46
+ get providerName() {
47
+ return this.options.providerName;
48
+ }
49
+ get privacyPolicyUrl() {
50
+ return this.options.privacyPolicyUrl;
51
+ }
52
+ get termsOfServiceUrl() {
53
+ return this.options.termsOfServiceUrl;
54
+ }
55
+ get requireConsent() {
56
+ return this.options.requireConsent ?? false;
57
+ }
58
+ get useTenantRouting() {
59
+ return this.options.useTenantRouting ?? false;
60
+ }
61
+ get actorParamName() {
62
+ return this.options.actorParamName ?? 'actorId';
63
+ }
64
+ get didWebId() {
65
+ return this.options.didWebId;
66
+ }
67
+ get consentPath() {
68
+ return this.options.endpoints?.consent ?? '/consent';
69
+ }
70
+ get statusListPath() {
71
+ return this.options.endpoints?.statusList ?? '/status-list';
72
+ }
73
+ get refreshPath() {
74
+ return this.options.endpoints?.refresh ?? '/ims/ob/v3p0/credentials/refresh';
75
+ }
76
+ }
77
+ exports.OpenBadgesHttpModuleConfig = OpenBadgesHttpModuleConfig;
78
+ //# sourceMappingURL=OpenBadgesHttpModuleConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenBadgesHttpModuleConfig.js","sourceRoot":"","sources":["../../src/http/OpenBadgesHttpModuleConfig.ts"],"names":[],"mappings":";;;AAEA,qCAAwC;AA8BxC,MAAa,0BAA0B;IAIrC,YAAmB,OAA0C;QAC3D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAA,sBAAa,GAAE,CAAC,MAAM,EAAE,CAAA;IAC1D,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAA;IAC7B,CAAC;IAED,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAA;IACtC,CAAC;IAED,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,IAAI,wBAAwB,CAAA;IACtE,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,IAAI,wBAAwB,CAAA;IACjE,CAAC;IAED,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,IAAI,uBAAuB,CAAA;IACvE,CAAC;IAED,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,IAAI,mBAAmB,CAAA;IACpE,CAAC;IAED,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,IAAI,YAAY,CAAA;IAC1D,CAAC;IAED,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,QAAQ,CAAA;IAClD,CAAC;IAED,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,IAAI,SAAS,CAAA;IACpD,CAAC;IAED,IAAW,cAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,IAAI,aAAa,CAAA;IAC5D,CAAC;IAED,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,IAAI,sBAAsB,CAAA;IAClE,CAAC;IAED,IAAW,eAAe;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,IAAI,0BAA0B,CAAA;IAC1E,CAAC;IAED,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAA;IAClC,CAAC;IAED,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAA;IACtC,CAAC;IAED,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAA;IACvC,CAAC;IAED,IAAW,cAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,KAAK,CAAA;IAC7C,CAAC;IAED,IAAW,gBAAgB;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAA;IAC/C,CAAC;IAED,IAAW,cAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,SAAS,CAAA;IACjD,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAA;IAC9B,CAAC;IAED,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,IAAI,UAAU,CAAA;IACtD,CAAC;IAED,IAAW,cAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,IAAI,cAAc,CAAA;IAC7D,CAAC;IAED,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,IAAI,kCAAkC,CAAA;IAC9E,CAAC;CACF;AAhGD,gEAgGC"}
@@ -0,0 +1,3 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModule } from '../OpenBadgesHttpModule';
3
+ export declare function configureAuthorizeEndpoint(router: Router, module: OpenBadgesHttpModule): void;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureAuthorizeEndpoint = configureAuthorizeEndpoint;
4
+ const router_1 = require("../router");
5
+ const OpenBadgesAuthCodeRepository_1 = require("../../repository/OpenBadgesAuthCodeRepository");
6
+ const OpenBadgesOAuthRepository_1 = require("../../repository/OpenBadgesOAuthRepository");
7
+ const auth_1 = require("../util/auth");
8
+ const OpenBadgesConsentRepository_1 = require("../../repository/OpenBadgesConsentRepository");
9
+ function urlEncode(params) {
10
+ return Object.entries(params)
11
+ .filter(([, v]) => v !== undefined)
12
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
13
+ .join('&');
14
+ }
15
+ function randomCode() {
16
+ return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
17
+ }
18
+ function configureAuthorizeEndpoint(router, module) {
19
+ router.get(module.config.authorizePath, async (req, res) => {
20
+ const { agentContext } = req.requestContext;
21
+ const { query } = req;
22
+ const client_id = String(query.client_id ?? '');
23
+ const redirect_uri = String(query.redirect_uri ?? '');
24
+ const response_type = String(query.response_type ?? 'code');
25
+ const scope = String(query.scope ?? '');
26
+ const state = String(query.state ?? '');
27
+ const code_challenge = query.code_challenge ? String(query.code_challenge) : undefined;
28
+ const code_challenge_method = query.code_challenge_method ? String(query.code_challenge_method) : undefined;
29
+ if (response_type !== 'code')
30
+ return (0, router_1.sendError)(res, 400, 'unsupported_response_type', 'Only code supported');
31
+ if (!client_id || !redirect_uri)
32
+ return (0, router_1.sendError)(res, 400, 'invalid_request', 'client_id and redirect_uri required');
33
+ // Validate client registration, redirect_uri and scope against registration
34
+ const oauthRepo = agentContext.dependencyManager.resolve(OpenBadgesOAuthRepository_1.OpenBadgesOAuthRepository);
35
+ const clientRec = await oauthRepo.findByClientId(agentContext, client_id);
36
+ if (!clientRec)
37
+ return (0, router_1.sendError)(res, 401, 'unauthorized_client', 'Unknown client_id');
38
+ const reg = clientRec.clientRegistration || {};
39
+ const redirectUris = Array.isArray(reg.redirect_uris) ? reg.redirect_uris : [];
40
+ if (!redirectUris.includes(redirect_uri))
41
+ return (0, router_1.sendError)(res, 400, 'invalid_request', 'redirect_uri not registered');
42
+ if (!(0, auth_1.isScopeSubset)(scope, reg.scope))
43
+ return (0, router_1.sendError)(res, 400, 'invalid_scope', 'Requested scope not allowed');
44
+ const subject = module.config.defaultSubjectId;
45
+ if (!subject)
46
+ return (0, router_1.sendError)(res, 500, 'server_error', 'No defaultSubjectId configured');
47
+ if (module.config.requireConsent) {
48
+ const consentRepo = agentContext.dependencyManager.resolve(OpenBadgesConsentRepository_1.OpenBadgesConsentRepository);
49
+ const consent = await consentRepo.findByClientAndSubject(agentContext, client_id, subject);
50
+ if (!consent) {
51
+ return res
52
+ .status(403)
53
+ .json({
54
+ error: 'consent_required',
55
+ consent_endpoint: new URL(module.config.consentPath, module.config.baseUrl).toString(),
56
+ client_id,
57
+ subject,
58
+ });
59
+ }
60
+ }
61
+ const code = randomCode();
62
+ const expiresAt = new Date(Date.now() + 60 * 1000);
63
+ const repo = agentContext.dependencyManager.resolve(OpenBadgesAuthCodeRepository_1.OpenBadgesAuthCodeRepository);
64
+ await repo.save(agentContext, new (require('../../repository/OpenBadgesAuthCodeRecord').OpenBadgesAuthCodeRecord)({
65
+ code,
66
+ clientId: client_id,
67
+ redirectUri: redirect_uri,
68
+ scope,
69
+ subject,
70
+ expiresAt,
71
+ codeChallenge: code_challenge,
72
+ codeChallengeMethod: code_challenge_method,
73
+ }));
74
+ const redirectUrl = `${redirect_uri}${redirect_uri.includes('?') ? '&' : '?'}${urlEncode({ code, state })}`;
75
+ agentContext.config.logger.debug('[OB][OAuth] Issued authorization code', { client_id });
76
+ res.redirect(302, redirectUrl);
77
+ });
78
+ }
79
+ //# sourceMappingURL=authorize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../../src/http/endpoints/authorize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModule } from '../OpenBadgesHttpModule';
3
+ export declare function configureConsentEndpoint(router: Router, module: OpenBadgesHttpModule): void;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureConsentEndpoint = configureConsentEndpoint;
4
+ const router_1 = require("../router");
5
+ const OpenBadgesConsentRepository_1 = require("../../repository/OpenBadgesConsentRepository");
6
+ function configureConsentEndpoint(router, module) {
7
+ router.post(module.config.consentPath, async (req, res) => {
8
+ const { agentContext } = (0, router_1.getRequestContext)(req);
9
+ const client_id = String(req.body?.client_id ?? '');
10
+ const subject = String(req.body?.subject ?? module.config.defaultSubjectId ?? '');
11
+ if (!client_id || !subject)
12
+ return (0, router_1.sendError)(res, 400, 'invalid_request', 'client_id and subject are required');
13
+ const repo = agentContext.dependencyManager.resolve(OpenBadgesConsentRepository_1.OpenBadgesConsentRepository);
14
+ const existing = await repo.findByClientAndSubject(agentContext, client_id, subject);
15
+ if (existing)
16
+ return (0, router_1.sendJson)(res, { ok: true, alreadyGranted: true });
17
+ await repo.save(agentContext, {
18
+ clientId: client_id,
19
+ subject,
20
+ grantedAt: new Date(),
21
+ });
22
+ return (0, router_1.sendJson)(res, { ok: true });
23
+ });
24
+ }
25
+ //# sourceMappingURL=consent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent.js","sourceRoot":"","sources":["../../../src/http/endpoints/consent.ts"],"names":[],"mappings":";;AAOA,4DAgBC;AAnBD,sCAAkE;AAClE,8FAA0F;AAE1F,SAAgB,wBAAwB,CAAC,MAAc,EAAE,MAA4B;IACnF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,GAAc,EAAE,GAAa,EAAE,EAAE;QAC7E,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,0BAAiB,EAAC,GAAG,CAAC,CAAA;QAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC,CAAA;QACnD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAA;QACjF,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO;YAAE,OAAO,IAAA,kBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,iBAAiB,EAAE,oCAAoC,CAAC,CAAA;QAC/G,MAAM,IAAI,GAAG,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,yDAA2B,CAAC,CAAA;QAChF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QACpF,IAAI,QAAQ;YAAE,OAAO,IAAA,iBAAQ,EAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAA;QACtE,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAC5B,QAAQ,EAAE,SAAS;YACnB,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE;SACf,CAAC,CAAA;QACT,OAAO,IAAA,iBAAQ,EAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModuleConfig } from '../OpenBadgesHttpModuleConfig';
3
+ import type { OpenBadgesHttpModule } from '../OpenBadgesHttpModule';
4
+ export declare function configureCredentialsEndpoints(router: Router, config: OpenBadgesHttpModuleConfig, module: OpenBadgesHttpModule): void;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureCredentialsEndpoints = configureCredentialsEndpoints;
4
+ const auth_1 = require("../middleware/auth");
5
+ const router_1 = require("../router");
6
+ const OpenBadgeCredentialRepository_1 = require("../../repository/OpenBadgeCredentialRepository");
7
+ const OpenBadgeCredentialRecord_1 = require("../../repository/OpenBadgeCredentialRecord");
8
+ const DisplayMapper_1 = require("../../services/DisplayMapper");
9
+ const OB_READ = 'https://purl.imsglobal.org/spec/ob/v3p0/scope/readonly';
10
+ const OB_WRITE = 'https://purl.imsglobal.org/spec/ob/v3p0/scope/replace';
11
+ const OB_DELETE = 'https://purl.imsglobal.org/spec/ob/v3p0/scope/delete';
12
+ function configureCredentialsEndpoints(router, config, module) {
13
+ // POST create/upsert
14
+ router.post(config.credentialsPath, (0, auth_1.bearerAuth)(module), (0, auth_1.requireScopes)([OB_WRITE]), async (req, res) => {
15
+ try {
16
+ const { agentContext } = (0, router_1.getRequestContext)(req);
17
+ const auth = req.requestContext.auth;
18
+ const body = req.body;
19
+ if (!body || typeof body !== 'object')
20
+ return (0, router_1.sendError)(res, 400, 'invalid_request', 'Missing credential body');
21
+ const repo = agentContext.dependencyManager.resolve(OpenBadgeCredentialRepository_1.OpenBadgeCredentialRepository);
22
+ const mapper = agentContext.dependencyManager.resolve(DisplayMapper_1.DisplayMapper);
23
+ const record = new OpenBadgeCredentialRecord_1.OpenBadgeCredentialRecord({
24
+ credential: body,
25
+ status: 'unknown',
26
+ derived: mapper.toDisplay(body),
27
+ tags: { subjectId: auth.subject },
28
+ });
29
+ await repo.save(agentContext, record);
30
+ return (0, router_1.sendJson)(res, { id: record.id }, 201);
31
+ }
32
+ catch (e) {
33
+ return (0, router_1.sendError)(res, 500, 'server_error', e?.message || 'Unexpected error');
34
+ }
35
+ });
36
+ // GET list
37
+ router.get(config.credentialsPath, (0, auth_1.bearerAuth)(module), (0, auth_1.requireScopes)([OB_READ]), async (req, res) => {
38
+ try {
39
+ const { agentContext } = (0, router_1.getRequestContext)(req);
40
+ const auth = req.requestContext.auth;
41
+ const repo = agentContext.dependencyManager.resolve(OpenBadgeCredentialRepository_1.OpenBadgeCredentialRepository);
42
+ const items = await repo.findByQuery(agentContext, { subjectId: auth.subject });
43
+ return (0, router_1.sendJson)(res, items.map((r) => ({ id: r.id, status: r.status, derived: r.derived })));
44
+ }
45
+ catch (e) {
46
+ return (0, router_1.sendError)(res, 500, 'server_error', e?.message || 'Unexpected error');
47
+ }
48
+ });
49
+ // GET one
50
+ router.get(`${config.credentialsPath}/:id`, (0, auth_1.bearerAuth)(module), (0, auth_1.requireScopes)([OB_READ]), async (req, res) => {
51
+ try {
52
+ const { agentContext } = (0, router_1.getRequestContext)(req);
53
+ const repo = agentContext.dependencyManager.resolve(OpenBadgeCredentialRepository_1.OpenBadgeCredentialRepository);
54
+ const id = String(req.params.id);
55
+ const record = await repo.getById(agentContext, id);
56
+ if (!record)
57
+ return (0, router_1.sendError)(res, 404, 'not_found', 'Credential not found');
58
+ return (0, router_1.sendJson)(res, record.credential);
59
+ }
60
+ catch (e) {
61
+ return (0, router_1.sendError)(res, 500, 'server_error', e?.message || 'Unexpected error');
62
+ }
63
+ });
64
+ // DELETE one
65
+ router.delete(`${config.credentialsPath}/:id`, (0, auth_1.bearerAuth)(module), (0, auth_1.requireScopes)([OB_DELETE]), async (req, res) => {
66
+ try {
67
+ const { agentContext } = (0, router_1.getRequestContext)(req);
68
+ const auth = req.requestContext.auth;
69
+ const repo = agentContext.dependencyManager.resolve(OpenBadgeCredentialRepository_1.OpenBadgeCredentialRepository);
70
+ const id = String(req.params.id);
71
+ const record = await repo.getById(agentContext, id);
72
+ if (!record)
73
+ return (0, router_1.sendError)(res, 404, 'not_found', 'Credential not found');
74
+ const tags = record.getTags();
75
+ if (tags.subjectId && tags.subjectId !== auth.subject)
76
+ return (0, router_1.sendError)(res, 404, 'not_found', 'Credential not found');
77
+ await repo.deleteById(agentContext, id);
78
+ return (0, router_1.sendJson)(res, { deleted: true });
79
+ }
80
+ catch (e) {
81
+ return (0, router_1.sendError)(res, 500, 'server_error', e?.message || 'Unexpected error');
82
+ }
83
+ });
84
+ }
85
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/http/endpoints/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModuleConfig } from '../OpenBadgesHttpModuleConfig';
3
+ export declare function configureDidDocumentEndpoint(router: Router, config: OpenBadgesHttpModuleConfig): void;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureDidDocumentEndpoint = configureDidDocumentEndpoint;
4
+ const router_1 = require("../router");
5
+ const OpenBadgesKeyBindingRepository_1 = require("../../repository/OpenBadgesKeyBindingRepository");
6
+ function parseDidWebToPath(did) {
7
+ // did:web:example.com[:path:segments]
8
+ const parts = did.split(':');
9
+ if (parts.length < 3 || parts[0] !== 'did' || parts[1] !== 'web')
10
+ return '';
11
+ const domainEnc = parts[2];
12
+ const pathSegs = parts.slice(3);
13
+ // Resolution rules: if path segments present => "/<segments>/did.json", else => "/.well-known/did.json"
14
+ return pathSegs.length > 0 ? `/${pathSegs.join('/')}/did.json` : '/.well-known/did.json';
15
+ }
16
+ function configureDidDocumentEndpoint(router, config) {
17
+ const did = config.didWebId;
18
+ if (!did)
19
+ return;
20
+ const path = config.didDocumentPath || parseDidWebToPath(did) || '/.well-known/did.json';
21
+ router.get(path, async (req, res) => {
22
+ const { agentContext } = (0, router_1.getRequestContext)(req);
23
+ const bindingRepo = agentContext.dependencyManager.resolve(OpenBadgesKeyBindingRepository_1.OpenBadgesKeyBindingRepository);
24
+ let bindings = [];
25
+ try {
26
+ const all = await bindingRepo.getAll(agentContext);
27
+ bindings = all.filter((b) => b.controller === did);
28
+ }
29
+ catch (e) {
30
+ agentContext.config.logger.warn('[OB][HTTP][DID] bindingRepo.getAll failed', { err: e?.message || e });
31
+ bindings = [];
32
+ }
33
+ const vm = bindings.map((b) => ({
34
+ id: b.vmId,
35
+ type: 'Ed25519VerificationKey2020',
36
+ controller: did,
37
+ publicKeyMultibase: b.publicKeyMultibase,
38
+ }));
39
+ const doc = {
40
+ '@context': 'https://www.w3.org/ns/did/v1',
41
+ id: did,
42
+ verificationMethod: vm,
43
+ assertionMethod: vm.map((v) => v.id),
44
+ };
45
+ (0, router_1.sendJson)(res, doc);
46
+ });
47
+ }
48
+ //# sourceMappingURL=did.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did.js","sourceRoot":"","sources":["../../../src/http/endpoints/did.ts"],"names":[],"mappings":";;AAiBA,oEA8BC;AA3CD,sCAAuD;AACvD,oGAAgG;AAEhG,SAAS,iBAAiB,CAAC,GAAW;IACpC,sCAAsC;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK;QAAE,OAAO,EAAE,CAAA;IAC3E,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC/B,wGAAwG;IACxG,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAA;AAC1F,CAAC;AAED,SAAgB,4BAA4B,CAAC,MAAc,EAAE,MAAkC;IAC7F,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAA;IAC3B,IAAI,CAAC,GAAG;QAAE,OAAM;IAChB,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,uBAAuB,CAAA;IACxF,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAc,EAAE,GAAa,EAAE,EAAE;QACvD,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,0BAAiB,EAAC,GAAG,CAAC,CAAA;QAC/C,MAAM,WAAW,GAAG,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,+DAA8B,CAAC,CAAA;QAC1F,IAAI,QAAQ,GAAG,EAAW,CAAA;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;YAClD,QAAQ,GAAI,GAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,CAAA;QAC/D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,EAAE,EAAE,GAAG,EAAG,CAAS,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAA;YAC/G,QAAQ,GAAG,EAAE,CAAA;QACf,CAAC;QAED,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YACnC,EAAE,EAAE,CAAC,CAAC,IAAI;YACV,IAAI,EAAE,4BAA4B;YAClC,UAAU,EAAE,GAAG;YACf,kBAAkB,EAAE,CAAC,CAAC,kBAAkB;SACzC,CAAC,CAAC,CAAA;QACH,MAAM,GAAG,GAAG;YACV,UAAU,EAAE,8BAA8B;YAC1C,EAAE,EAAE,GAAG;YACP,kBAAkB,EAAE,EAAE;YACtB,eAAe,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAA;QACD,IAAA,iBAAQ,EAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACpB,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModule } from '../OpenBadgesHttpModule';
3
+ export declare function configureIntrospectEndpoint(router: Router, module: OpenBadgesHttpModule): void;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureIntrospectEndpoint = configureIntrospectEndpoint;
4
+ const router_1 = require("../router");
5
+ const OpenBadgesTokenRepository_1 = require("../../repository/OpenBadgesTokenRepository");
6
+ const OpenBadgesOAuthRepository_1 = require("../../repository/OpenBadgesOAuthRepository");
7
+ const auth_1 = require("../util/auth");
8
+ function configureIntrospectEndpoint(router, module) {
9
+ router.post(module.config.introspectPath, async (req, res) => {
10
+ const { agentContext } = (0, router_1.getRequestContext)(req);
11
+ const basic = (0, auth_1.parseBasicAuth)(req) ?? (0, auth_1.parseBodyClientAuth)(req);
12
+ if (!basic)
13
+ return (0, router_1.sendError)(res, 401, 'invalid_client', 'Client authentication required');
14
+ const oauthRepo = agentContext.dependencyManager.resolve(OpenBadgesOAuthRepository_1.OpenBadgesOAuthRepository);
15
+ const clientRec = await oauthRepo.findByClientId(agentContext, basic.clientId);
16
+ const reg = clientRec?.clientRegistration || {};
17
+ if (!clientRec || reg.client_secret !== basic.clientSecret)
18
+ return (0, router_1.sendError)(res, 401, 'invalid_client', 'Invalid client credentials');
19
+ const token = String(req.body?.token ?? '');
20
+ if (!token)
21
+ return (0, router_1.sendError)(res, 400, 'invalid_request', 'token is required');
22
+ const tokenRepo = agentContext.dependencyManager.resolve(OpenBadgesTokenRepository_1.OpenBadgesTokenRepository);
23
+ const t = await tokenRepo.findByToken(agentContext, token);
24
+ if (!t || t.expiresAt.getTime() < Date.now())
25
+ return (0, router_1.sendJson)(res, { active: false });
26
+ return (0, router_1.sendJson)(res, {
27
+ active: true,
28
+ client_id: t.clientId,
29
+ scope: t.scope,
30
+ sub: t.subject,
31
+ token_type: t.tokenType,
32
+ exp: Math.floor(t.expiresAt.getTime() / 1000),
33
+ iat: Math.floor(t.createdAt.getTime() / 1000),
34
+ });
35
+ });
36
+ }
37
+ //# sourceMappingURL=introspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.js","sourceRoot":"","sources":["../../../src/http/endpoints/introspect.ts"],"names":[],"mappings":";;AASA,kEA2BC;AAhCD,sCAAkE;AAClE,0FAAsF;AACtF,0FAAsF;AACtF,uCAAkE;AAElE,SAAgB,2BAA2B,CAAC,MAAc,EAAE,MAA4B;IACtF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,EAAE,GAAc,EAAE,GAAa,EAAE,EAAE;QAChF,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,0BAAiB,EAAC,GAAG,CAAC,CAAA;QAC/C,MAAM,KAAK,GAAG,IAAA,qBAAc,EAAC,GAAG,CAAC,IAAI,IAAA,0BAAmB,EAAC,GAAG,CAAC,CAAA;QAC7D,IAAI,CAAC,KAAK;YAAE,OAAO,IAAA,kBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,EAAE,gCAAgC,CAAC,CAAA;QAE1F,MAAM,SAAS,GAAG,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,qDAAyB,CAAC,CAAA;QACnF,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC9E,MAAM,GAAG,GAAI,SAAS,EAAE,kBAA0B,IAAI,EAAE,CAAA;QACxD,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,aAAa,KAAK,KAAK,CAAC,YAAY;YACxD,OAAO,IAAA,kBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,EAAE,4BAA4B,CAAC,CAAA;QAE5E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAA;QAC3C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAA,kBAAS,EAAC,GAAG,EAAE,GAAG,EAAE,iBAAiB,EAAE,mBAAmB,CAAC,CAAA;QAC9E,MAAM,SAAS,GAAG,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,qDAAyB,CAAC,CAAA;QACnF,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;QAC1D,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,IAAA,iBAAQ,EAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QACrF,OAAO,IAAA,iBAAQ,EAAC,GAAG,EAAE;YACnB,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,QAAQ;YACrB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,GAAG,EAAE,CAAC,CAAC,OAAO;YACd,UAAU,EAAE,CAAC,CAAC,SAAS;YACvB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;YAC7C,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;SAC9C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModuleConfig } from '../OpenBadgesHttpModuleConfig';
3
+ export declare function configureJwksEndpoint(router: Router, config: OpenBadgesHttpModuleConfig): void;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureJwksEndpoint = configureJwksEndpoint;
4
+ const router_1 = require("../router");
5
+ const OpenBadgesKeyBindingRepository_1 = require("../../repository/OpenBadgesKeyBindingRepository");
6
+ const KeyService_1 = require("../../services/KeyService");
7
+ function base64UrlEncode(buf) {
8
+ return Buffer.from(buf)
9
+ .toString('base64')
10
+ .replace(/=/g, '')
11
+ .replace(/\+/g, '-')
12
+ .replace(/\//g, '_');
13
+ }
14
+ function configureJwksEndpoint(router, config) {
15
+ router.get(config.jwksPath, async (req, res) => {
16
+ const { agentContext } = (0, router_1.getRequestContext)(req);
17
+ const bindingRepo = agentContext.dependencyManager.resolve(OpenBadgesKeyBindingRepository_1.OpenBadgesKeyBindingRepository);
18
+ let bindings = [];
19
+ try {
20
+ const all = await bindingRepo.getAll(agentContext);
21
+ bindings = all.filter((b) => b.controller === (config.didWebId || ''));
22
+ }
23
+ catch (e) {
24
+ agentContext.config.logger.warn('[OB][HTTP][JWKS] bindingRepo.getAll failed', { err: e?.message || e });
25
+ bindings = [];
26
+ }
27
+ const keyService = agentContext.dependencyManager.resolve(KeyService_1.KeyService);
28
+ const jwks = {
29
+ keys: await (async () => {
30
+ const out = [];
31
+ for (const b of bindings) {
32
+ try {
33
+ const jwk = await keyService.getPublicJwkByVm(agentContext, b.vmId);
34
+ if (jwk?.kty === 'OKP' && jwk?.crv === 'Ed25519' && jwk?.x) {
35
+ out.push({ kty: 'OKP', crv: 'Ed25519', x: jwk.x, kid: b.vmId, use: 'sig', alg: 'EdDSA' });
36
+ }
37
+ }
38
+ catch { }
39
+ }
40
+ return out;
41
+ })(),
42
+ };
43
+ (0, router_1.sendJson)(res, jwks);
44
+ });
45
+ }
46
+ //# sourceMappingURL=jwks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwks.js","sourceRoot":"","sources":["../../../src/http/endpoints/jwks.ts"],"names":[],"mappings":";;AAiBA,sDA+BC;AA5CD,sCAAuD;AACvD,oGAAgG;AAChG,0DAAsD;AAGtD,SAAS,eAAe,CAAC,GAAe;IACtC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SACpB,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;SACjB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,SAAgB,qBAAqB,CAAC,MAAc,EAAE,MAAkC;IACtF,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAc,EAAE,GAAa,EAAE,EAAE;QAClE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,0BAAiB,EAAC,GAAG,CAAC,CAAA;QAC/C,MAAM,WAAW,GAAG,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,+DAA8B,CAAC,CAAA;QAC1F,IAAI,QAAQ,GAAG,EAAW,CAAA;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;YAClD,QAAQ,GAAI,GAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAA;QACnF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE,EAAE,GAAG,EAAG,CAAS,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAA;YAChH,QAAQ,GAAG,EAAE,CAAA;QACf,CAAC;QACD,MAAM,UAAU,GAAG,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,uBAAU,CAAC,CAAA;QAErE,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;gBACtB,MAAM,GAAG,GAAU,EAAE,CAAA;gBACrB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;oBACzB,IAAI,CAAC;wBACH,MAAM,GAAG,GAAQ,MAAM,UAAU,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;wBACxE,IAAI,GAAG,EAAE,GAAG,KAAK,KAAK,IAAI,GAAG,EAAE,GAAG,KAAK,SAAS,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC;4BAC3D,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;wBAC3F,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;gBACZ,CAAC;gBACD,OAAO,GAAG,CAAA;YACZ,CAAC,CAAC,EAAE;SACL,CAAA;QAED,IAAA,iBAAQ,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACrB,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModuleConfig } from '../OpenBadgesHttpModuleConfig';
3
+ import type { OpenBadgesHttpModule } from '../OpenBadgesHttpModule';
4
+ export declare function configureProfileEndpoints(router: Router, config: OpenBadgesHttpModuleConfig, module: OpenBadgesHttpModule): void;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureProfileEndpoints = configureProfileEndpoints;
4
+ const auth_1 = require("../middleware/auth");
5
+ const router_1 = require("../router");
6
+ const OpenBadgesProfileRepository_1 = require("../../repository/OpenBadgesProfileRepository");
7
+ const OpenBadgesProfileRecord_1 = require("../../repository/OpenBadgesProfileRecord");
8
+ const OB_READ = 'https://purl.imsglobal.org/spec/ob/v3p0/scope/readonly';
9
+ const OB_WRITE = 'https://purl.imsglobal.org/spec/ob/v3p0/scope/replace';
10
+ function configureProfileEndpoints(router, config, module) {
11
+ // GET profile by subject
12
+ router.get(config.profilePath, (0, auth_1.bearerAuth)(module), (0, auth_1.requireScopes)([OB_READ]), async (req, res) => {
13
+ try {
14
+ const { agentContext } = (0, router_1.getRequestContext)(req);
15
+ const auth = req.requestContext.auth;
16
+ const repo = agentContext.dependencyManager.resolve(OpenBadgesProfileRepository_1.OpenBadgesProfileRepository);
17
+ try {
18
+ const rec = await repo.findByProfileId(agentContext, auth.subject);
19
+ if (!rec)
20
+ return (0, router_1.sendError)(res, 404, 'not_found', 'Profile not found');
21
+ return (0, router_1.sendJson)(res, rec.profile);
22
+ }
23
+ catch {
24
+ return (0, router_1.sendError)(res, 404, 'not_found', 'Profile not found');
25
+ }
26
+ }
27
+ catch (e) {
28
+ return (0, router_1.sendError)(res, 500, 'server_error', e?.message || 'Unexpected error');
29
+ }
30
+ });
31
+ // PUT profile
32
+ router.put(config.profilePath, (0, auth_1.bearerAuth)(module), (0, auth_1.requireScopes)([OB_WRITE]), async (req, res) => {
33
+ try {
34
+ const { agentContext } = (0, router_1.getRequestContext)(req);
35
+ const auth = req.requestContext.auth;
36
+ const repo = agentContext.dependencyManager.resolve(OpenBadgesProfileRepository_1.OpenBadgesProfileRepository);
37
+ const body = req.body;
38
+ if (!body || typeof body !== 'object')
39
+ return (0, router_1.sendError)(res, 400, 'invalid_request', 'Missing profile body');
40
+ try {
41
+ const existing = await repo.findByProfileId(agentContext, auth.subject);
42
+ if (existing) {
43
+ existing.profile = body;
44
+ await repo.update(agentContext, existing);
45
+ return (0, router_1.sendJson)(res, { updated: true });
46
+ }
47
+ }
48
+ catch { }
49
+ const rec = new OpenBadgesProfileRecord_1.OpenBadgesProfileRecord({ profileId: auth.subject, profile: body });
50
+ await repo.save(agentContext, rec);
51
+ return (0, router_1.sendJson)(res, { created: true }, 201);
52
+ }
53
+ catch (e) {
54
+ return (0, router_1.sendError)(res, 500, 'server_error', e?.message || 'Unexpected error');
55
+ }
56
+ });
57
+ }
58
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../../src/http/endpoints/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Router } from 'express';
2
+ import type { OpenBadgesHttpModuleConfig } from '../OpenBadgesHttpModuleConfig';
3
+ import type { OpenBadgesHttpModule } from '../OpenBadgesHttpModule';
4
+ /**
5
+ * Credential Refresh Endpoint
6
+ *
7
+ * Allows holders to request a refreshed (renewed) version of their credential.
8
+ * The issuer may update validity dates or other information.
9
+ *
10
+ * POST /ims/ob/v3p0/credentials/refresh
11
+ * Body: { credentialId: string } or the full credential
12
+ *
13
+ * Returns: refreshed credential with new proof and updated dates
14
+ */
15
+ export declare function configureRefreshEndpoint(router: Router, config: OpenBadgesHttpModuleConfig, module: OpenBadgesHttpModule): void;