@textrp/briij-js-sdk 41.0.0 → 42.0.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 (375) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/LICENSE +177 -177
  3. package/README.md +47 -46
  4. package/lib/@types/AESEncryptedSecretStoragePayload.js.map +1 -1
  5. package/lib/@types/IIdentityServerProvider.js.map +1 -1
  6. package/lib/@types/PushRules.js +14 -14
  7. package/lib/@types/PushRules.js.map +1 -1
  8. package/lib/@types/another-json.d.js.map +1 -1
  9. package/lib/@types/auth.d.ts +19 -1
  10. package/lib/@types/auth.d.ts.map +1 -1
  11. package/lib/@types/auth.js +55 -54
  12. package/lib/@types/auth.js.map +1 -1
  13. package/lib/@types/beacon.js +100 -100
  14. package/lib/@types/beacon.js.map +1 -1
  15. package/lib/@types/common.js.map +1 -1
  16. package/lib/@types/crypto.js.map +1 -1
  17. package/lib/@types/event.d.ts +27 -0
  18. package/lib/@types/event.d.ts.map +1 -1
  19. package/lib/@types/event.js +105 -102
  20. package/lib/@types/event.js.map +1 -1
  21. package/lib/@types/events.js.map +1 -1
  22. package/lib/@types/extensible_events.js +53 -53
  23. package/lib/@types/extensible_events.js.map +1 -1
  24. package/lib/@types/local_notifications.js.map +1 -1
  25. package/lib/@types/location.js +41 -41
  26. package/lib/@types/location.js.map +1 -1
  27. package/lib/@types/matrix-sdk-crypto-wasm.d.js.map +1 -1
  28. package/lib/@types/media.js.map +1 -1
  29. package/lib/@types/membership.js +39 -39
  30. package/lib/@types/membership.js.map +1 -1
  31. package/lib/@types/partials.js +25 -25
  32. package/lib/@types/partials.js.map +1 -1
  33. package/lib/@types/polls.js +46 -46
  34. package/lib/@types/polls.js.map +1 -1
  35. package/lib/@types/read_receipts.js +14 -14
  36. package/lib/@types/read_receipts.js.map +1 -1
  37. package/lib/@types/registration.js.map +1 -1
  38. package/lib/@types/search.js +14 -14
  39. package/lib/@types/search.js.map +1 -1
  40. package/lib/@types/signed.js.map +1 -1
  41. package/lib/@types/spaces.js.map +1 -1
  42. package/lib/@types/state_events.js.map +1 -1
  43. package/lib/@types/synapse.js.map +1 -1
  44. package/lib/@types/sync.js +18 -18
  45. package/lib/@types/sync.js.map +1 -1
  46. package/lib/@types/threepids.js +14 -14
  47. package/lib/@types/threepids.js.map +1 -1
  48. package/lib/@types/topic.js +47 -47
  49. package/lib/@types/topic.js.map +1 -1
  50. package/lib/@types/uia.js.map +1 -1
  51. package/lib/NamespacedValue.js +20 -20
  52. package/lib/NamespacedValue.js.map +1 -1
  53. package/lib/ReEmitter.js +16 -16
  54. package/lib/ReEmitter.js.map +1 -1
  55. package/lib/base64.js +32 -32
  56. package/lib/base64.js.map +1 -1
  57. package/lib/briij.d.ts +3 -0
  58. package/lib/briij.d.ts.map +1 -1
  59. package/lib/briij.js +3 -0
  60. package/lib/briij.js.map +1 -1
  61. package/lib/client.d.ts +18 -1
  62. package/lib/client.d.ts.map +1 -1
  63. package/lib/client.js +166 -103
  64. package/lib/client.js.map +1 -1
  65. package/lib/common-crypto/key-passphrase.js +19 -19
  66. package/lib/common-crypto/key-passphrase.js.map +1 -1
  67. package/lib/content-helpers.js +57 -57
  68. package/lib/content-helpers.js.map +1 -1
  69. package/lib/content-repo.js +36 -36
  70. package/lib/content-repo.js.map +1 -1
  71. package/lib/crypto/store/base.js +69 -69
  72. package/lib/crypto/store/base.js.map +1 -1
  73. package/lib/crypto/store/indexeddb-crypto-store-backend.js +58 -58
  74. package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -1
  75. package/lib/crypto/store/indexeddb-crypto-store.js +193 -193
  76. package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -1
  77. package/lib/crypto/store/localStorage-crypto-store.js +72 -72
  78. package/lib/crypto/store/localStorage-crypto-store.js.map +1 -1
  79. package/lib/crypto/store/memory-crypto-store.js +74 -74
  80. package/lib/crypto/store/memory-crypto-store.js.map +1 -1
  81. package/lib/crypto-api/CryptoEventHandlerMap.js.map +1 -1
  82. package/lib/crypto-api/key-passphrase.js +22 -22
  83. package/lib/crypto-api/key-passphrase.js.map +1 -1
  84. package/lib/crypto-api/keybackup.js.map +1 -1
  85. package/lib/crypto-api/recovery-key.js +20 -20
  86. package/lib/crypto-api/recovery-key.js.map +1 -1
  87. package/lib/digest.js +21 -21
  88. package/lib/digest.js.map +1 -1
  89. package/lib/extensible_events_v1/ExtensibleEvent.js +39 -39
  90. package/lib/extensible_events_v1/ExtensibleEvent.js.map +1 -1
  91. package/lib/extensible_events_v1/InvalidEventError.js +16 -16
  92. package/lib/extensible_events_v1/InvalidEventError.js.map +1 -1
  93. package/lib/extensible_events_v1/MessageEvent.js +39 -39
  94. package/lib/extensible_events_v1/MessageEvent.js.map +1 -1
  95. package/lib/extensible_events_v1/PollEndEvent.js +29 -29
  96. package/lib/extensible_events_v1/PollEndEvent.js.map +1 -1
  97. package/lib/extensible_events_v1/PollResponseEvent.js +39 -39
  98. package/lib/extensible_events_v1/PollResponseEvent.js.map +1 -1
  99. package/lib/extensible_events_v1/PollStartEvent.js +52 -52
  100. package/lib/extensible_events_v1/PollStartEvent.js.map +1 -1
  101. package/lib/extensible_events_v1/utilities.js +22 -22
  102. package/lib/extensible_events_v1/utilities.js.map +1 -1
  103. package/lib/feature.js +16 -16
  104. package/lib/feature.js.map +1 -1
  105. package/lib/http-api/method.js +14 -14
  106. package/lib/http-api/method.js.map +1 -1
  107. package/lib/http-api/prefix.js +26 -26
  108. package/lib/http-api/prefix.js.map +1 -1
  109. package/lib/indexeddb-helpers.js +21 -21
  110. package/lib/indexeddb-helpers.js.map +1 -1
  111. package/lib/indexeddb-worker.js +18 -18
  112. package/lib/indexeddb-worker.js.map +1 -1
  113. package/lib/matrixrtc/IKeyTransport.js +17 -17
  114. package/lib/matrixrtc/IKeyTransport.js.map +1 -1
  115. package/lib/matrixrtc/IMembershipManager.js +27 -27
  116. package/lib/matrixrtc/IMembershipManager.js.map +1 -1
  117. package/lib/matrixrtc/LivekitTransport.js +19 -19
  118. package/lib/matrixrtc/LivekitTransport.js.map +1 -1
  119. package/lib/matrixrtc/index.js +14 -14
  120. package/lib/matrixrtc/index.js.map +1 -1
  121. package/lib/matrixrtc/utils.js +27 -27
  122. package/lib/matrixrtc/utils.js.map +1 -1
  123. package/lib/models/ToDeviceMessage.js.map +1 -1
  124. package/lib/models/device.js +24 -24
  125. package/lib/models/device.js.map +1 -1
  126. package/lib/models/event-status.js +17 -17
  127. package/lib/models/event-status.js.map +1 -1
  128. package/lib/models/invites-ignorer-types.js +25 -25
  129. package/lib/models/invites-ignorer-types.js.map +1 -1
  130. package/lib/models/profile-keys.js +26 -26
  131. package/lib/models/profile-keys.js.map +1 -1
  132. package/lib/models/room-summary.js +26 -26
  133. package/lib/models/room-summary.js.map +1 -1
  134. package/lib/models/search-result.js +22 -22
  135. package/lib/models/search-result.js.map +1 -1
  136. package/lib/models/typed-event-emitter.js +122 -122
  137. package/lib/models/typed-event-emitter.js.map +1 -1
  138. package/lib/oidc/authorize.js +76 -76
  139. package/lib/oidc/authorize.js.map +1 -1
  140. package/lib/oidc/error.js +17 -17
  141. package/lib/oidc/error.js.map +1 -1
  142. package/lib/oidc/index.js +17 -17
  143. package/lib/oidc/index.js.map +1 -1
  144. package/lib/oidc/register.js +41 -41
  145. package/lib/oidc/register.js.map +1 -1
  146. package/lib/oidc/tokenRefresher.js +51 -51
  147. package/lib/oidc/tokenRefresher.js.map +1 -1
  148. package/lib/oidc/validate.js +59 -59
  149. package/lib/oidc/validate.js.map +1 -1
  150. package/lib/randomstring.js +35 -35
  151. package/lib/randomstring.js.map +1 -1
  152. package/lib/realtime-callbacks.js +39 -39
  153. package/lib/realtime-callbacks.js.map +1 -1
  154. package/lib/receipt-accumulator.js +44 -44
  155. package/lib/receipt-accumulator.js.map +1 -1
  156. package/lib/rendezvous/RendezvousChannel.js.map +1 -1
  157. package/lib/rendezvous/RendezvousCode.js.map +1 -1
  158. package/lib/rendezvous/RendezvousError.js +14 -14
  159. package/lib/rendezvous/RendezvousError.js.map +1 -1
  160. package/lib/rendezvous/RendezvousFailureReason.js +14 -14
  161. package/lib/rendezvous/RendezvousFailureReason.js.map +1 -1
  162. package/lib/rendezvous/RendezvousIntent.js +14 -14
  163. package/lib/rendezvous/RendezvousIntent.js.map +1 -1
  164. package/lib/rendezvous/RendezvousTransport.js.map +1 -1
  165. package/lib/rendezvous/channels/MSC4108SecureChannel.js +63 -63
  166. package/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -1
  167. package/lib/rendezvous/channels/index.js +14 -14
  168. package/lib/rendezvous/channels/index.js.map +1 -1
  169. package/lib/rendezvous/index.js +14 -14
  170. package/lib/rendezvous/index.js.map +1 -1
  171. package/lib/rendezvous/transports/index.js +14 -14
  172. package/lib/rendezvous/transports/index.js.map +1 -1
  173. package/lib/rust-crypto/CrossSigningIdentity.js +29 -29
  174. package/lib/rust-crypto/CrossSigningIdentity.js.map +1 -1
  175. package/lib/rust-crypto/OutgoingRequestsManager.js +37 -37
  176. package/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -1
  177. package/lib/rust-crypto/device-converter.js +30 -30
  178. package/lib/rust-crypto/device-converter.js.map +1 -1
  179. package/lib/rust-crypto/secret-storage.js +30 -30
  180. package/lib/rust-crypto/secret-storage.js.map +1 -1
  181. package/lib/service-types.js +14 -14
  182. package/lib/service-types.js.map +1 -1
  183. package/lib/store/local-storage-events-emitter.js +21 -21
  184. package/lib/store/local-storage-events-emitter.js.map +1 -1
  185. package/lib/sync-accumulator.js +50 -50
  186. package/lib/sync-accumulator.js.map +1 -1
  187. package/lib/thread-utils.js +20 -20
  188. package/lib/thread-utils.js.map +1 -1
  189. package/lib/types.js +34 -34
  190. package/lib/types.js.map +1 -1
  191. package/lib/utils/decryptAESSecretStorageItem.js +22 -22
  192. package/lib/utils/decryptAESSecretStorageItem.js.map +1 -1
  193. package/lib/utils/encryptAESSecretStorageItem.js +26 -26
  194. package/lib/utils/encryptAESSecretStorageItem.js.map +1 -1
  195. package/lib/utils/internal/deriveKeys.js +21 -21
  196. package/lib/utils/internal/deriveKeys.js.map +1 -1
  197. package/lib/utils/roomVersion.js +26 -26
  198. package/lib/utils/roomVersion.js.map +1 -1
  199. package/lib/version-support.js +26 -26
  200. package/lib/version-support.js.map +1 -1
  201. package/lib/webrtc/audioContext.js +24 -24
  202. package/lib/webrtc/audioContext.js.map +1 -1
  203. package/lib/webrtc/callEventTypes.js.map +1 -1
  204. package/lib/webrtc/stats/callFeedStatsReporter.js +14 -14
  205. package/lib/webrtc/stats/callFeedStatsReporter.js.map +1 -1
  206. package/lib/webrtc/stats/callStatsReportGatherer.js +14 -14
  207. package/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -1
  208. package/lib/webrtc/stats/callStatsReportSummary.js.map +1 -1
  209. package/lib/webrtc/stats/connectionStats.js +14 -14
  210. package/lib/webrtc/stats/connectionStats.js.map +1 -1
  211. package/lib/webrtc/stats/connectionStatsBuilder.js +14 -14
  212. package/lib/webrtc/stats/connectionStatsBuilder.js.map +1 -1
  213. package/lib/webrtc/stats/connectionStatsReportBuilder.js +14 -14
  214. package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -1
  215. package/lib/webrtc/stats/groupCallStats.js +14 -14
  216. package/lib/webrtc/stats/groupCallStats.js.map +1 -1
  217. package/lib/webrtc/stats/media/mediaSsrcHandler.js +14 -14
  218. package/lib/webrtc/stats/media/mediaSsrcHandler.js.map +1 -1
  219. package/lib/webrtc/stats/media/mediaTrackHandler.js +14 -14
  220. package/lib/webrtc/stats/media/mediaTrackHandler.js.map +1 -1
  221. package/lib/webrtc/stats/media/mediaTrackStats.js +27 -27
  222. package/lib/webrtc/stats/media/mediaTrackStats.js.map +1 -1
  223. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +20 -20
  224. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -1
  225. package/lib/webrtc/stats/statsReport.js +14 -14
  226. package/lib/webrtc/stats/statsReport.js.map +1 -1
  227. package/lib/webrtc/stats/statsReportEmitter.js +14 -14
  228. package/lib/webrtc/stats/statsReportEmitter.js.map +1 -1
  229. package/lib/webrtc/stats/trackStatsBuilder.js +4 -4
  230. package/lib/webrtc/stats/trackStatsBuilder.js.map +1 -1
  231. package/lib/webrtc/stats/transportStats.js.map +1 -1
  232. package/lib/webrtc/stats/transportStatsBuilder.js.map +1 -1
  233. package/lib/webrtc/stats/valueFormatter.js +11 -11
  234. package/lib/webrtc/stats/valueFormatter.js.map +1 -1
  235. package/lib/xrpl/identity.d.ts +28 -0
  236. package/lib/xrpl/identity.d.ts.map +1 -0
  237. package/lib/xrpl/identity.js +213 -0
  238. package/lib/xrpl/identity.js.map +1 -0
  239. package/lib/xrpl/trust.d.ts +8 -0
  240. package/lib/xrpl/trust.d.ts.map +1 -0
  241. package/lib/xrpl/trust.js +61 -0
  242. package/lib/xrpl/trust.js.map +1 -0
  243. package/lib/xrpl/verification.d.ts +26 -0
  244. package/lib/xrpl/verification.d.ts.map +1 -0
  245. package/lib/xrpl/verification.js +295 -0
  246. package/lib/xrpl/verification.js.map +1 -0
  247. package/package.json +128 -129
  248. package/src/@types/AESEncryptedSecretStoragePayload.ts +29 -29
  249. package/src/@types/IIdentityServerProvider.ts +24 -24
  250. package/src/@types/PushRules.ts +208 -208
  251. package/src/@types/another-json.d.ts +19 -19
  252. package/src/@types/auth.ts +280 -258
  253. package/src/@types/beacon.ts +140 -140
  254. package/src/@types/common.ts +24 -24
  255. package/src/@types/crypto.ts +71 -71
  256. package/src/@types/event.ts +476 -449
  257. package/src/@types/events.ts +119 -119
  258. package/src/@types/extensible_events.ts +147 -147
  259. package/src/@types/local_notifications.ts +19 -19
  260. package/src/@types/location.ts +92 -92
  261. package/src/@types/matrix-sdk-crypto-wasm.d.ts +39 -39
  262. package/src/@types/media.ts +245 -245
  263. package/src/@types/membership.ts +57 -57
  264. package/src/@types/partials.ts +103 -103
  265. package/src/@types/polls.ts +120 -120
  266. package/src/@types/read_receipts.ts +61 -61
  267. package/src/@types/registration.ts +102 -102
  268. package/src/@types/search.ts +119 -119
  269. package/src/@types/signed.ts +25 -25
  270. package/src/@types/spaces.ts +37 -37
  271. package/src/@types/state_events.ts +153 -153
  272. package/src/@types/synapse.ts +40 -40
  273. package/src/@types/sync.ts +27 -27
  274. package/src/@types/threepids.ts +29 -29
  275. package/src/@types/topic.ts +69 -69
  276. package/src/@types/uia.ts +24 -24
  277. package/src/NamespacedValue.ts +121 -121
  278. package/src/ReEmitter.ts +93 -93
  279. package/src/base64.ts +86 -86
  280. package/src/briij.ts +3 -0
  281. package/src/client.ts +90 -10
  282. package/src/common-crypto/README.md +4 -4
  283. package/src/common-crypto/key-passphrase.ts +43 -43
  284. package/src/content-helpers.ts +298 -298
  285. package/src/content-repo.ts +122 -122
  286. package/src/crypto/store/base.ts +388 -388
  287. package/src/crypto/store/indexeddb-crypto-store-backend.ts +655 -655
  288. package/src/crypto/store/indexeddb-crypto-store.ts +555 -555
  289. package/src/crypto/store/localStorage-crypto-store.ts +409 -409
  290. package/src/crypto/store/memory-crypto-store.ts +326 -326
  291. package/src/crypto-api/CryptoEventHandlerMap.ts +42 -42
  292. package/src/crypto-api/key-passphrase.ts +58 -58
  293. package/src/crypto-api/keybackup.ts +114 -114
  294. package/src/crypto-api/recovery-key.ts +69 -69
  295. package/src/digest.ts +34 -34
  296. package/src/extensible_events_v1/ExtensibleEvent.ts +58 -58
  297. package/src/extensible_events_v1/InvalidEventError.ts +24 -24
  298. package/src/extensible_events_v1/MessageEvent.ts +143 -143
  299. package/src/extensible_events_v1/PollEndEvent.ts +97 -97
  300. package/src/extensible_events_v1/PollResponseEvent.ts +148 -148
  301. package/src/extensible_events_v1/PollStartEvent.ts +207 -207
  302. package/src/extensible_events_v1/utilities.ts +35 -35
  303. package/src/feature.ts +88 -88
  304. package/src/http-api/method.ts +25 -25
  305. package/src/http-api/prefix.ts +48 -48
  306. package/src/indexeddb-helpers.ts +50 -50
  307. package/src/indexeddb-worker.ts +24 -24
  308. package/src/matrixrtc/IKeyTransport.ts +63 -63
  309. package/src/matrixrtc/IMembershipManager.ts +120 -120
  310. package/src/matrixrtc/LivekitTransport.ts +46 -46
  311. package/src/matrixrtc/index.ts +24 -24
  312. package/src/matrixrtc/utils.ts +71 -71
  313. package/src/models/ToDeviceMessage.ts +38 -38
  314. package/src/models/device.ts +85 -85
  315. package/src/models/event-status.ts +39 -39
  316. package/src/models/invites-ignorer-types.ts +58 -58
  317. package/src/models/profile-keys.ts +33 -33
  318. package/src/models/room-summary.ts +78 -78
  319. package/src/models/search-result.ts +57 -57
  320. package/src/models/typed-event-emitter.ts +246 -246
  321. package/src/oidc/authorize.ts +279 -279
  322. package/src/oidc/error.ts +33 -33
  323. package/src/oidc/index.ts +33 -33
  324. package/src/oidc/register.ts +163 -163
  325. package/src/oidc/tokenRefresher.ts +184 -184
  326. package/src/oidc/validate.ts +265 -265
  327. package/src/randomstring.ts +103 -103
  328. package/src/realtime-callbacks.ts +191 -191
  329. package/src/receipt-accumulator.ts +189 -189
  330. package/src/rendezvous/RendezvousChannel.ts +48 -48
  331. package/src/rendezvous/RendezvousCode.ts +25 -25
  332. package/src/rendezvous/RendezvousError.ts +26 -26
  333. package/src/rendezvous/RendezvousFailureReason.ts +49 -49
  334. package/src/rendezvous/RendezvousIntent.ts +20 -20
  335. package/src/rendezvous/RendezvousTransport.ts +58 -58
  336. package/src/rendezvous/channels/MSC4108SecureChannel.ts +270 -270
  337. package/src/rendezvous/channels/index.ts +17 -17
  338. package/src/rendezvous/index.ts +25 -25
  339. package/src/rendezvous/transports/index.ts +17 -17
  340. package/src/rust-crypto/CrossSigningIdentity.ts +195 -195
  341. package/src/rust-crypto/OutgoingRequestsManager.ts +170 -170
  342. package/src/rust-crypto/device-converter.ts +128 -128
  343. package/src/rust-crypto/secret-storage.ts +60 -60
  344. package/src/service-types.ts +20 -20
  345. package/src/store/local-storage-events-emitter.ts +46 -46
  346. package/src/sync-accumulator.ts +779 -779
  347. package/src/thread-utils.ts +31 -31
  348. package/src/types.ts +59 -59
  349. package/src/utils/decryptAESSecretStorageItem.ts +54 -54
  350. package/src/utils/encryptAESSecretStorageItem.ts +73 -73
  351. package/src/utils/internal/deriveKeys.ts +63 -63
  352. package/src/utils/roomVersion.ts +35 -35
  353. package/src/version-support.ts +50 -50
  354. package/src/webrtc/audioContext.ts +44 -44
  355. package/src/webrtc/callEventTypes.ts +101 -101
  356. package/src/webrtc/stats/callFeedStatsReporter.ts +91 -91
  357. package/src/webrtc/stats/callStatsReportGatherer.ts +219 -219
  358. package/src/webrtc/stats/callStatsReportSummary.ts +30 -30
  359. package/src/webrtc/stats/connectionStats.ts +47 -47
  360. package/src/webrtc/stats/connectionStatsBuilder.ts +28 -28
  361. package/src/webrtc/stats/connectionStatsReportBuilder.ts +140 -140
  362. package/src/webrtc/stats/groupCallStats.ts +93 -93
  363. package/src/webrtc/stats/media/mediaSsrcHandler.ts +57 -57
  364. package/src/webrtc/stats/media/mediaTrackHandler.ts +70 -70
  365. package/src/webrtc/stats/media/mediaTrackStats.ts +176 -176
  366. package/src/webrtc/stats/media/mediaTrackStatsHandler.ts +90 -90
  367. package/src/webrtc/stats/statsReport.ts +133 -133
  368. package/src/webrtc/stats/statsReportEmitter.ts +49 -49
  369. package/src/webrtc/stats/trackStatsBuilder.ts +207 -207
  370. package/src/webrtc/stats/transportStats.ts +26 -26
  371. package/src/webrtc/stats/transportStatsBuilder.ts +48 -48
  372. package/src/webrtc/stats/valueFormatter.ts +27 -27
  373. package/src/xrpl/identity.ts +245 -0
  374. package/src/xrpl/trust.ts +64 -0
  375. package/src/xrpl/verification.ts +284 -0
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","names":["OidcError","Method","logger","OAuthGrantType","DEVICE_CODE_SCOPE","DeviceAuthorization","urlHasCommonBase","base","urlStr","url","URL","protocol","hostname","endsWith","concat","registerOidcClient","_ref","_asyncToGenerator","delegatedAuthConfig","clientMetadata","registration_endpoint","Error","DynamicRegistrationNotSupported","grantTypes","AuthorizationCode","RefreshToken","some","scope","grant_types_supported","includes","commonBase","clientUri","metadata","client_name","clientName","client_uri","response_types","grant_types","redirect_uris","redirectUris","id_token_signed_response_alg","token_endpoint_auth_method","application_type","applicationType","contacts","logo_uri","logoUri","undefined","policy_uri","policyUri","tos_uri","tosUri","headers","response","fetch","method","Post","body","JSON","stringify","status","DynamicRegistrationFailed","json","clientId","DynamicRegistrationInvalid","error","Object","values","message","_x","_x2","apply","arguments"],"sources":["../../src/oidc/register.ts"],"sourcesContent":["/*\r\nCopyright 2023 The Matrix.org Foundation C.I.C.\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\n\r\nimport { type OidcClientConfig } from \"./index.ts\";\r\nimport { OidcError } from \"./error.ts\";\r\nimport { Method } from \"../http-api/index.ts\";\r\nimport { logger } from \"../logger.ts\";\r\nimport { type NonEmptyArray } from \"../@types/common.ts\";\r\n\r\n/**\r\n * Client metadata passed to registration endpoint\r\n */\r\nexport type OidcRegistrationClientMetadata = {\r\n clientName: OidcRegistrationRequestBody[\"client_name\"];\r\n clientUri: OidcRegistrationRequestBody[\"client_uri\"];\r\n logoUri?: OidcRegistrationRequestBody[\"logo_uri\"];\r\n applicationType: OidcRegistrationRequestBody[\"application_type\"];\r\n redirectUris: OidcRegistrationRequestBody[\"redirect_uris\"];\r\n contacts: OidcRegistrationRequestBody[\"contacts\"];\r\n tosUri: OidcRegistrationRequestBody[\"tos_uri\"];\r\n policyUri: OidcRegistrationRequestBody[\"policy_uri\"];\r\n};\r\n\r\n/**\r\n * Request body for dynamic registration as defined by https://github.com/matrix-org/matrix-spec-proposals/pull/2966\r\n */\r\ninterface OidcRegistrationRequestBody {\r\n client_name?: string;\r\n client_uri: string;\r\n logo_uri?: string;\r\n contacts?: string[];\r\n tos_uri?: string;\r\n policy_uri?: string;\r\n redirect_uris?: NonEmptyArray<string>;\r\n response_types?: NonEmptyArray<string>;\r\n grant_types?: NonEmptyArray<string>;\r\n id_token_signed_response_alg?: string;\r\n token_endpoint_auth_method: string;\r\n application_type: \"web\" | \"native\";\r\n}\r\n\r\n/**\r\n * The OAuth 2.0 grant types that are defined for Matrix in https://spec.matrix.org/v1.17/client-server-api/#grant-types\r\n */\r\nexport enum OAuthGrantType {\r\n /**\r\n * See https://spec.matrix.org/v1.17/client-server-api/#authorization-code-grant\r\n */\r\n AuthorizationCode = \"authorization_code\",\r\n /**\r\n * https://spec.matrix.org/v1.17/client-server-api/#refresh-token-grant\r\n */\r\n RefreshToken = \"refresh_token\",\r\n /**\r\n * The OAuth 2.0 Device Authorization Grant type identifier as per\r\n * https://www.rfc-editor.org/rfc/rfc8628.html#section-7.2 from\r\n * [MSC4341](https://github.com/matrix-org/matrix-spec-proposals/pull/4341).\r\n *\r\n * @experimental Note that this is UNSTABLE and may have breaking changes without notice.\r\n */\r\n DeviceAuthorization = \"urn:ietf:params:oauth:grant-type:device_code\",\r\n}\r\n\r\n/**\r\n * The name \"scope\" is a misnomer here as it is actually a \"grant type\".\r\n *\r\n * @deprecated use `OAuthGrantType.DeviceAuthorization` instead\r\n */\r\nexport const DEVICE_CODE_SCOPE: string = OAuthGrantType.DeviceAuthorization;\r\n\r\n// Check that URIs have a common base, as per the MSC2966 definition\r\nconst urlHasCommonBase = (base: URL, urlStr?: string): boolean => {\r\n if (!urlStr) return false;\r\n const url = new URL(urlStr);\r\n if (url.protocol !== base.protocol) return false;\r\n if (url.hostname !== base.hostname && !url.hostname.endsWith(`.${base.hostname}`)) return false;\r\n return true;\r\n};\r\n\r\n/**\r\n * Attempts dynamic registration against the configured registration endpoint.\r\n * Will ignore any URIs that do not use client_uri as a common base as per the spec.\r\n * @param delegatedAuthConfig - Auth config from {@link discoverAndValidateOIDCIssuerWellKnown}\r\n * @param clientMetadata - The metadata for the client which to register\r\n * @returns Promise<string> resolved with registered clientId\r\n * @throws when registration is not supported, on failed request or invalid response\r\n */\r\nexport const registerOidcClient = async (\r\n delegatedAuthConfig: OidcClientConfig,\r\n clientMetadata: OidcRegistrationClientMetadata,\r\n): Promise<string> => {\r\n if (!delegatedAuthConfig.registration_endpoint) {\r\n throw new Error(OidcError.DynamicRegistrationNotSupported);\r\n }\r\n\r\n const grantTypes: NonEmptyArray<string> = [OAuthGrantType.AuthorizationCode, OAuthGrantType.RefreshToken];\r\n if (grantTypes.some((scope) => !delegatedAuthConfig.grant_types_supported.includes(scope))) {\r\n throw new Error(OidcError.DynamicRegistrationNotSupported);\r\n }\r\n\r\n const commonBase = new URL(clientMetadata.clientUri);\r\n\r\n // https://openid.net/specs/openid-connect-registration-1_0.html\r\n const metadata: OidcRegistrationRequestBody = {\r\n client_name: clientMetadata.clientName,\r\n client_uri: clientMetadata.clientUri,\r\n response_types: [\"code\"],\r\n grant_types: grantTypes,\r\n redirect_uris: clientMetadata.redirectUris,\r\n id_token_signed_response_alg: \"RS256\",\r\n token_endpoint_auth_method: \"none\",\r\n application_type: clientMetadata.applicationType,\r\n contacts: clientMetadata.contacts,\r\n logo_uri: urlHasCommonBase(commonBase, clientMetadata.logoUri) ? clientMetadata.logoUri : undefined,\r\n policy_uri: urlHasCommonBase(commonBase, clientMetadata.policyUri) ? clientMetadata.policyUri : undefined,\r\n tos_uri: urlHasCommonBase(commonBase, clientMetadata.tosUri) ? clientMetadata.tosUri : undefined,\r\n };\r\n\r\n const headers = {\r\n \"Accept\": \"application/json\",\r\n \"Content-Type\": \"application/json\",\r\n };\r\n\r\n try {\r\n const response = await fetch(delegatedAuthConfig.registration_endpoint, {\r\n method: Method.Post,\r\n headers,\r\n body: JSON.stringify(metadata),\r\n });\r\n\r\n if (response.status >= 400) {\r\n throw new Error(OidcError.DynamicRegistrationFailed);\r\n }\r\n\r\n const body = await response.json();\r\n const clientId = body[\"client_id\"];\r\n if (!clientId || typeof clientId !== \"string\") {\r\n throw new Error(OidcError.DynamicRegistrationInvalid);\r\n }\r\n\r\n return clientId;\r\n } catch (error) {\r\n if (Object.values(OidcError).includes((error as Error).message as OidcError)) {\r\n throw error;\r\n } else {\r\n logger.error(\"Dynamic registration request failed\", error);\r\n throw new Error(OidcError.DynamicRegistrationFailed);\r\n }\r\n }\r\n};\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"register.js","names":["OidcError","Method","logger","OAuthGrantType","DEVICE_CODE_SCOPE","DeviceAuthorization","urlHasCommonBase","base","urlStr","url","URL","protocol","hostname","endsWith","concat","registerOidcClient","_ref","_asyncToGenerator","delegatedAuthConfig","clientMetadata","registration_endpoint","Error","DynamicRegistrationNotSupported","grantTypes","AuthorizationCode","RefreshToken","some","scope","grant_types_supported","includes","commonBase","clientUri","metadata","client_name","clientName","client_uri","response_types","grant_types","redirect_uris","redirectUris","id_token_signed_response_alg","token_endpoint_auth_method","application_type","applicationType","contacts","logo_uri","logoUri","undefined","policy_uri","policyUri","tos_uri","tosUri","headers","response","fetch","method","Post","body","JSON","stringify","status","DynamicRegistrationFailed","json","clientId","DynamicRegistrationInvalid","error","Object","values","message","_x","_x2","apply","arguments"],"sources":["../../src/oidc/register.ts"],"sourcesContent":["/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { type OidcClientConfig } from \"./index.ts\";\nimport { OidcError } from \"./error.ts\";\nimport { Method } from \"../http-api/index.ts\";\nimport { logger } from \"../logger.ts\";\nimport { type NonEmptyArray } from \"../@types/common.ts\";\n\n/**\n * Client metadata passed to registration endpoint\n */\nexport type OidcRegistrationClientMetadata = {\n clientName: OidcRegistrationRequestBody[\"client_name\"];\n clientUri: OidcRegistrationRequestBody[\"client_uri\"];\n logoUri?: OidcRegistrationRequestBody[\"logo_uri\"];\n applicationType: OidcRegistrationRequestBody[\"application_type\"];\n redirectUris: OidcRegistrationRequestBody[\"redirect_uris\"];\n contacts: OidcRegistrationRequestBody[\"contacts\"];\n tosUri: OidcRegistrationRequestBody[\"tos_uri\"];\n policyUri: OidcRegistrationRequestBody[\"policy_uri\"];\n};\n\n/**\n * Request body for dynamic registration as defined by https://github.com/matrix-org/matrix-spec-proposals/pull/2966\n */\ninterface OidcRegistrationRequestBody {\n client_name?: string;\n client_uri: string;\n logo_uri?: string;\n contacts?: string[];\n tos_uri?: string;\n policy_uri?: string;\n redirect_uris?: NonEmptyArray<string>;\n response_types?: NonEmptyArray<string>;\n grant_types?: NonEmptyArray<string>;\n id_token_signed_response_alg?: string;\n token_endpoint_auth_method: string;\n application_type: \"web\" | \"native\";\n}\n\n/**\n * The OAuth 2.0 grant types that are defined for Matrix in https://spec.matrix.org/v1.17/client-server-api/#grant-types\n */\nexport enum OAuthGrantType {\n /**\n * See https://spec.matrix.org/v1.17/client-server-api/#authorization-code-grant\n */\n AuthorizationCode = \"authorization_code\",\n /**\n * https://spec.matrix.org/v1.17/client-server-api/#refresh-token-grant\n */\n RefreshToken = \"refresh_token\",\n /**\n * The OAuth 2.0 Device Authorization Grant type identifier as per\n * https://www.rfc-editor.org/rfc/rfc8628.html#section-7.2 from\n * [MSC4341](https://github.com/matrix-org/matrix-spec-proposals/pull/4341).\n *\n * @experimental Note that this is UNSTABLE and may have breaking changes without notice.\n */\n DeviceAuthorization = \"urn:ietf:params:oauth:grant-type:device_code\",\n}\n\n/**\n * The name \"scope\" is a misnomer here as it is actually a \"grant type\".\n *\n * @deprecated use `OAuthGrantType.DeviceAuthorization` instead\n */\nexport const DEVICE_CODE_SCOPE: string = OAuthGrantType.DeviceAuthorization;\n\n// Check that URIs have a common base, as per the MSC2966 definition\nconst urlHasCommonBase = (base: URL, urlStr?: string): boolean => {\n if (!urlStr) return false;\n const url = new URL(urlStr);\n if (url.protocol !== base.protocol) return false;\n if (url.hostname !== base.hostname && !url.hostname.endsWith(`.${base.hostname}`)) return false;\n return true;\n};\n\n/**\n * Attempts dynamic registration against the configured registration endpoint.\n * Will ignore any URIs that do not use client_uri as a common base as per the spec.\n * @param delegatedAuthConfig - Auth config from {@link discoverAndValidateOIDCIssuerWellKnown}\n * @param clientMetadata - The metadata for the client which to register\n * @returns Promise<string> resolved with registered clientId\n * @throws when registration is not supported, on failed request or invalid response\n */\nexport const registerOidcClient = async (\n delegatedAuthConfig: OidcClientConfig,\n clientMetadata: OidcRegistrationClientMetadata,\n): Promise<string> => {\n if (!delegatedAuthConfig.registration_endpoint) {\n throw new Error(OidcError.DynamicRegistrationNotSupported);\n }\n\n const grantTypes: NonEmptyArray<string> = [OAuthGrantType.AuthorizationCode, OAuthGrantType.RefreshToken];\n if (grantTypes.some((scope) => !delegatedAuthConfig.grant_types_supported.includes(scope))) {\n throw new Error(OidcError.DynamicRegistrationNotSupported);\n }\n\n const commonBase = new URL(clientMetadata.clientUri);\n\n // https://openid.net/specs/openid-connect-registration-1_0.html\n const metadata: OidcRegistrationRequestBody = {\n client_name: clientMetadata.clientName,\n client_uri: clientMetadata.clientUri,\n response_types: [\"code\"],\n grant_types: grantTypes,\n redirect_uris: clientMetadata.redirectUris,\n id_token_signed_response_alg: \"RS256\",\n token_endpoint_auth_method: \"none\",\n application_type: clientMetadata.applicationType,\n contacts: clientMetadata.contacts,\n logo_uri: urlHasCommonBase(commonBase, clientMetadata.logoUri) ? clientMetadata.logoUri : undefined,\n policy_uri: urlHasCommonBase(commonBase, clientMetadata.policyUri) ? clientMetadata.policyUri : undefined,\n tos_uri: urlHasCommonBase(commonBase, clientMetadata.tosUri) ? clientMetadata.tosUri : undefined,\n };\n\n const headers = {\n \"Accept\": \"application/json\",\n \"Content-Type\": \"application/json\",\n };\n\n try {\n const response = await fetch(delegatedAuthConfig.registration_endpoint, {\n method: Method.Post,\n headers,\n body: JSON.stringify(metadata),\n });\n\n if (response.status >= 400) {\n throw new Error(OidcError.DynamicRegistrationFailed);\n }\n\n const body = await response.json();\n const clientId = body[\"client_id\"];\n if (!clientId || typeof clientId !== \"string\") {\n throw new Error(OidcError.DynamicRegistrationInvalid);\n }\n\n return clientId;\n } catch (error) {\n if (Object.values(OidcError).includes((error as Error).message as OidcError)) {\n throw error;\n } else {\n logger.error(\"Dynamic registration request failed\", error);\n throw new Error(OidcError.DynamicRegistrationFailed);\n }\n }\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1,19 +1,19 @@
1
1
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- /*
4
- Copyright 2023 The Matrix.org Foundation C.I.C.
5
-
6
- Licensed under the Apache License, Version 2.0 (the "License");
7
- you may not use this file except in compliance with the License.
8
- You may obtain a copy of the License at
9
-
10
- http://www.apache.org/licenses/LICENSE-2.0
11
-
12
- Unless required by applicable law or agreed to in writing, software
13
- distributed under the License is distributed on an "AS IS" BASIS,
14
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- See the License for the specific language governing permissions and
16
- limitations under the License.
3
+ /*
4
+ Copyright 2023 The Matrix.org Foundation C.I.C.
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
17
  */
18
18
 
19
19
  import { OidcClient, WebStorageStateStore, ErrorResponse } from "oidc-client-ts";
@@ -22,34 +22,34 @@ import { generateScope } from "./authorize.js";
22
22
  import { discoverAndValidateOIDCIssuerWellKnown } from "./discovery.js";
23
23
  import { logger } from "../logger.js";
24
24
 
25
- /**
26
- * @experimental
27
- * Class responsible for refreshing OIDC access tokens
28
- *
29
- * Client implementations will likely want to override {@link persistTokens} to persist tokens after successful refresh
30
- *
25
+ /**
26
+ * @experimental
27
+ * Class responsible for refreshing OIDC access tokens
28
+ *
29
+ * Client implementations will likely want to override {@link persistTokens} to persist tokens after successful refresh
30
+ *
31
31
  */
32
32
  export class OidcTokenRefresher {
33
33
  constructor(
34
- /**
35
- * The OIDC issuer as returned by the /auth_issuer API
34
+ /**
35
+ * The OIDC issuer as returned by the /auth_issuer API
36
36
  */
37
37
  issuer,
38
- /**
39
- * id of this client as registered with the OP
38
+ /**
39
+ * id of this client as registered with the OP
40
40
  */
41
41
  clientId,
42
- /**
43
- * redirectUri as registered with OP
42
+ /**
43
+ * redirectUri as registered with OP
44
44
  */
45
45
  redirectUri,
46
- /**
47
- * Device ID of current session
46
+ /**
47
+ * Device ID of current session
48
48
  */
49
49
  deviceId,
50
- /**
51
- * idTokenClaims as returned from authorization grant
52
- * used to validate tokens
50
+ /**
51
+ * idTokenClaims as returned from authorization grant
52
+ * used to validate tokens
53
53
  */
54
54
  idTokenClaims) {
55
55
  this.issuer = issuer;
@@ -57,10 +57,10 @@ export class OidcTokenRefresher {
57
57
  this.redirectUri = redirectUri;
58
58
  this.deviceId = deviceId;
59
59
  this.idTokenClaims = idTokenClaims;
60
- /**
61
- * This is now just a resolved promise and will be removed in a future version.
62
- * Initialisation is done lazily at token refresh time.
63
- * @deprecated Consumers no longer need to wait for this promise.
60
+ /**
61
+ * This is now just a resolved promise and will be removed in a future version.
62
+ * Initialisation is done lazily at token refresh time.
63
+ * @deprecated Consumers no longer need to wait for this promise.
64
64
  */
65
65
  _defineProperty(this, "oidcClientReady", void 0);
66
66
  // If there is a initialisation attempt in progress, we keep track of it here.
@@ -70,10 +70,10 @@ export class OidcTokenRefresher {
70
70
  this.oidcClientReady = Promise.resolve();
71
71
  }
72
72
 
73
- /**
74
- * Ensures that the client is initialised.
75
- * @returns Promise that resolves when initialisation is complete
76
- * @throws if initialisation fails
73
+ /**
74
+ * Ensures that the client is initialised.
75
+ * @returns Promise that resolves when initialisation is complete
76
+ * @throws if initialisation fails
77
77
  */
78
78
  ensureInit() {
79
79
  var _this = this;
@@ -117,11 +117,11 @@ export class OidcTokenRefresher {
117
117
  })();
118
118
  }
119
119
 
120
- /**
121
- * Attempt token refresh using given refresh token
122
- * @param refreshToken - refresh token to use in request with token issuer
123
- * @returns tokens - Promise that resolves with new access and refresh tokens
124
- * @throws when token refresh fails
120
+ /**
121
+ * Attempt token refresh using given refresh token
122
+ * @param refreshToken - refresh token to use in request with token issuer
123
+ * @returns tokens - Promise that resolves with new access and refresh tokens
124
+ * @throws when token refresh fails
125
125
  */
126
126
  doRefreshAccessToken(refreshToken) {
127
127
  var _this3 = this;
@@ -145,13 +145,13 @@ export class OidcTokenRefresher {
145
145
  })();
146
146
  }
147
147
 
148
- /**
149
- * Persist the new tokens, called after tokens are successfully refreshed.
150
- *
151
- * This function is intended to be overriden by the consumer when persistence is necessary.
152
- *
153
- * @param tokens.accessToken - new access token
154
- * @param tokens.refreshToken - OPTIONAL new refresh token
148
+ /**
149
+ * Persist the new tokens, called after tokens are successfully refreshed.
150
+ *
151
+ * This function is intended to be overriden by the consumer when persistence is necessary.
152
+ *
153
+ * @param tokens.accessToken - new access token
154
+ * @param tokens.refreshToken - OPTIONAL new refresh token
155
155
  */
156
156
  persistTokens(tokens) {
157
157
  return _asyncToGenerator(function* () {})();
@@ -1 +1 @@
1
- {"version":3,"file":"tokenRefresher.js","names":["OidcClient","WebStorageStateStore","ErrorResponse","TokenRefreshLogoutError","generateScope","discoverAndValidateOIDCIssuerWellKnown","logger","OidcTokenRefresher","constructor","issuer","clientId","redirectUri","deviceId","idTokenClaims","_defineProperty","oidcClientReady","Promise","resolve","ensureInit","_this","_asyncToGenerator","oidcClient","initPromise","initialiseOidcClient","undefined","_this2","_config$signingKeys","config","scope","metadata","signingKeys","client_id","redirect_uri","authority","stateStore","prefix","store","window","sessionStorage","error","Error","doRefreshAccessToken","refreshToken","_this3","inflightRefreshRequest","getNewTokens","tokens","e","persistTokens","_this4","refreshTokenState","refresh_token","session_state","data","profile","requestStart","Date","now","response","useRefreshToken","state","timeoutInSeconds","accessToken","access_token","expiry","expires_in"],"sources":["../../src/oidc/tokenRefresher.ts"],"sourcesContent":["/*\r\nCopyright 2023 The Matrix.org Foundation C.I.C.\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\n\r\nimport { type IdTokenClaims, OidcClient, WebStorageStateStore, ErrorResponse } from \"oidc-client-ts\";\r\n\r\nimport { type AccessTokens, TokenRefreshLogoutError } from \"../http-api/index.ts\";\r\nimport { generateScope } from \"./authorize.ts\";\r\nimport { discoverAndValidateOIDCIssuerWellKnown } from \"./discovery.ts\";\r\nimport { logger } from \"../logger.ts\";\r\n\r\n/**\r\n * @experimental\r\n * Class responsible for refreshing OIDC access tokens\r\n *\r\n * Client implementations will likely want to override {@link persistTokens} to persist tokens after successful refresh\r\n *\r\n */\r\nexport class OidcTokenRefresher {\r\n /**\r\n * This is now just a resolved promise and will be removed in a future version.\r\n * Initialisation is done lazily at token refresh time.\r\n * @deprecated Consumers no longer need to wait for this promise.\r\n */\r\n public readonly oidcClientReady!: Promise<void>;\r\n\r\n // If there is a initialisation attempt in progress, we keep track of it here.\r\n private initPromise?: Promise<void>;\r\n\r\n private oidcClient!: OidcClient;\r\n private inflightRefreshRequest?: Promise<AccessTokens>;\r\n\r\n public constructor(\r\n /**\r\n * The OIDC issuer as returned by the /auth_issuer API\r\n */\r\n private issuer: string,\r\n /**\r\n * id of this client as registered with the OP\r\n */\r\n private clientId: string,\r\n /**\r\n * redirectUri as registered with OP\r\n */\r\n private redirectUri: string,\r\n /**\r\n * Device ID of current session\r\n */\r\n protected deviceId: string,\r\n /**\r\n * idTokenClaims as returned from authorization grant\r\n * used to validate tokens\r\n */\r\n private readonly idTokenClaims: IdTokenClaims,\r\n ) {\r\n this.oidcClientReady = Promise.resolve();\r\n }\r\n\r\n /**\r\n * Ensures that the client is initialised.\r\n * @returns Promise that resolves when initialisation is complete\r\n * @throws if initialisation fails\r\n */\r\n private async ensureInit(): Promise<void> {\r\n if (!this.oidcClient) {\r\n if (this.initPromise) {\r\n return this.initPromise;\r\n }\r\n\r\n this.initPromise = this.initialiseOidcClient(this.issuer, this.clientId, this.deviceId, this.redirectUri);\r\n try {\r\n await this.initPromise;\r\n } finally {\r\n this.initPromise = undefined;\r\n }\r\n }\r\n }\r\n\r\n private async initialiseOidcClient(\r\n issuer: string,\r\n clientId: string,\r\n deviceId: string,\r\n redirectUri: string,\r\n ): Promise<void> {\r\n try {\r\n const config = await discoverAndValidateOIDCIssuerWellKnown(issuer);\r\n\r\n const scope = generateScope(deviceId);\r\n\r\n this.oidcClient = new OidcClient({\r\n metadata: config,\r\n signingKeys: config.signingKeys ?? undefined,\r\n client_id: clientId,\r\n scope,\r\n redirect_uri: redirectUri,\r\n authority: config.issuer,\r\n stateStore: new WebStorageStateStore({ prefix: \"mx_oidc_\", store: window.sessionStorage }),\r\n });\r\n } catch (error) {\r\n logger.error(\"Failed to initialise OIDC client.\", error);\r\n throw new Error(\"Failed to initialise OIDC client.\");\r\n }\r\n }\r\n\r\n /**\r\n * Attempt token refresh using given refresh token\r\n * @param refreshToken - refresh token to use in request with token issuer\r\n * @returns tokens - Promise that resolves with new access and refresh tokens\r\n * @throws when token refresh fails\r\n */\r\n public async doRefreshAccessToken(refreshToken: string): Promise<AccessTokens> {\r\n await this.ensureInit();\r\n\r\n if (!this.inflightRefreshRequest) {\r\n this.inflightRefreshRequest = this.getNewTokens(refreshToken);\r\n }\r\n try {\r\n const tokens = await this.inflightRefreshRequest;\r\n return tokens;\r\n } catch (e) {\r\n // If we encounter an OIDC error then signal that it should cause a logout by upgrading it to a TokenRefreshLogoutError\r\n if (e instanceof ErrorResponse) {\r\n throw new TokenRefreshLogoutError(e);\r\n }\r\n throw e;\r\n } finally {\r\n this.inflightRefreshRequest = undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Persist the new tokens, called after tokens are successfully refreshed.\r\n *\r\n * This function is intended to be overriden by the consumer when persistence is necessary.\r\n *\r\n * @param tokens.accessToken - new access token\r\n * @param tokens.refreshToken - OPTIONAL new refresh token\r\n */\r\n protected async persistTokens(tokens: { accessToken: string; refreshToken?: string }): Promise<void> {\r\n // NOOP\r\n }\r\n\r\n private async getNewTokens(refreshToken: string): Promise<AccessTokens> {\r\n if (!this.oidcClient) {\r\n throw new Error(\"Cannot get new token before OIDC client is initialised.\");\r\n }\r\n\r\n const refreshTokenState = {\r\n refresh_token: refreshToken,\r\n session_state: \"test\",\r\n data: undefined,\r\n profile: this.idTokenClaims,\r\n };\r\n\r\n const requestStart = Date.now();\r\n const response = await this.oidcClient.useRefreshToken({\r\n state: refreshTokenState,\r\n timeoutInSeconds: 300,\r\n });\r\n\r\n const tokens = {\r\n accessToken: response.access_token,\r\n refreshToken: response.refresh_token,\r\n // We use the request start time to calculate the expiry time as we don't know when the server received our request\r\n expiry: response.expires_in ? new Date(requestStart + response.expires_in * 1000) : undefined,\r\n } satisfies AccessTokens;\r\n\r\n await this.persistTokens(tokens);\r\n\r\n return tokens;\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"tokenRefresher.js","names":["OidcClient","WebStorageStateStore","ErrorResponse","TokenRefreshLogoutError","generateScope","discoverAndValidateOIDCIssuerWellKnown","logger","OidcTokenRefresher","constructor","issuer","clientId","redirectUri","deviceId","idTokenClaims","_defineProperty","oidcClientReady","Promise","resolve","ensureInit","_this","_asyncToGenerator","oidcClient","initPromise","initialiseOidcClient","undefined","_this2","_config$signingKeys","config","scope","metadata","signingKeys","client_id","redirect_uri","authority","stateStore","prefix","store","window","sessionStorage","error","Error","doRefreshAccessToken","refreshToken","_this3","inflightRefreshRequest","getNewTokens","tokens","e","persistTokens","_this4","refreshTokenState","refresh_token","session_state","data","profile","requestStart","Date","now","response","useRefreshToken","state","timeoutInSeconds","accessToken","access_token","expiry","expires_in"],"sources":["../../src/oidc/tokenRefresher.ts"],"sourcesContent":["/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { type IdTokenClaims, OidcClient, WebStorageStateStore, ErrorResponse } from \"oidc-client-ts\";\n\nimport { type AccessTokens, TokenRefreshLogoutError } from \"../http-api/index.ts\";\nimport { generateScope } from \"./authorize.ts\";\nimport { discoverAndValidateOIDCIssuerWellKnown } from \"./discovery.ts\";\nimport { logger } from \"../logger.ts\";\n\n/**\n * @experimental\n * Class responsible for refreshing OIDC access tokens\n *\n * Client implementations will likely want to override {@link persistTokens} to persist tokens after successful refresh\n *\n */\nexport class OidcTokenRefresher {\n /**\n * This is now just a resolved promise and will be removed in a future version.\n * Initialisation is done lazily at token refresh time.\n * @deprecated Consumers no longer need to wait for this promise.\n */\n public readonly oidcClientReady!: Promise<void>;\n\n // If there is a initialisation attempt in progress, we keep track of it here.\n private initPromise?: Promise<void>;\n\n private oidcClient!: OidcClient;\n private inflightRefreshRequest?: Promise<AccessTokens>;\n\n public constructor(\n /**\n * The OIDC issuer as returned by the /auth_issuer API\n */\n private issuer: string,\n /**\n * id of this client as registered with the OP\n */\n private clientId: string,\n /**\n * redirectUri as registered with OP\n */\n private redirectUri: string,\n /**\n * Device ID of current session\n */\n protected deviceId: string,\n /**\n * idTokenClaims as returned from authorization grant\n * used to validate tokens\n */\n private readonly idTokenClaims: IdTokenClaims,\n ) {\n this.oidcClientReady = Promise.resolve();\n }\n\n /**\n * Ensures that the client is initialised.\n * @returns Promise that resolves when initialisation is complete\n * @throws if initialisation fails\n */\n private async ensureInit(): Promise<void> {\n if (!this.oidcClient) {\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = this.initialiseOidcClient(this.issuer, this.clientId, this.deviceId, this.redirectUri);\n try {\n await this.initPromise;\n } finally {\n this.initPromise = undefined;\n }\n }\n }\n\n private async initialiseOidcClient(\n issuer: string,\n clientId: string,\n deviceId: string,\n redirectUri: string,\n ): Promise<void> {\n try {\n const config = await discoverAndValidateOIDCIssuerWellKnown(issuer);\n\n const scope = generateScope(deviceId);\n\n this.oidcClient = new OidcClient({\n metadata: config,\n signingKeys: config.signingKeys ?? undefined,\n client_id: clientId,\n scope,\n redirect_uri: redirectUri,\n authority: config.issuer,\n stateStore: new WebStorageStateStore({ prefix: \"mx_oidc_\", store: window.sessionStorage }),\n });\n } catch (error) {\n logger.error(\"Failed to initialise OIDC client.\", error);\n throw new Error(\"Failed to initialise OIDC client.\");\n }\n }\n\n /**\n * Attempt token refresh using given refresh token\n * @param refreshToken - refresh token to use in request with token issuer\n * @returns tokens - Promise that resolves with new access and refresh tokens\n * @throws when token refresh fails\n */\n public async doRefreshAccessToken(refreshToken: string): Promise<AccessTokens> {\n await this.ensureInit();\n\n if (!this.inflightRefreshRequest) {\n this.inflightRefreshRequest = this.getNewTokens(refreshToken);\n }\n try {\n const tokens = await this.inflightRefreshRequest;\n return tokens;\n } catch (e) {\n // If we encounter an OIDC error then signal that it should cause a logout by upgrading it to a TokenRefreshLogoutError\n if (e instanceof ErrorResponse) {\n throw new TokenRefreshLogoutError(e);\n }\n throw e;\n } finally {\n this.inflightRefreshRequest = undefined;\n }\n }\n\n /**\n * Persist the new tokens, called after tokens are successfully refreshed.\n *\n * This function is intended to be overriden by the consumer when persistence is necessary.\n *\n * @param tokens.accessToken - new access token\n * @param tokens.refreshToken - OPTIONAL new refresh token\n */\n protected async persistTokens(tokens: { accessToken: string; refreshToken?: string }): Promise<void> {\n // NOOP\n }\n\n private async getNewTokens(refreshToken: string): Promise<AccessTokens> {\n if (!this.oidcClient) {\n throw new Error(\"Cannot get new token before OIDC client is initialised.\");\n }\n\n const refreshTokenState = {\n refresh_token: refreshToken,\n session_state: \"test\",\n data: undefined,\n profile: this.idTokenClaims,\n };\n\n const requestStart = Date.now();\n const response = await this.oidcClient.useRefreshToken({\n state: refreshTokenState,\n timeoutInSeconds: 300,\n });\n\n const tokens = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token,\n // We use the request start time to calculate the expiry time as we don't know when the server received our request\n expiry: response.expires_in ? new Date(requestStart + response.expires_in * 1000) : undefined,\n } satisfies AccessTokens;\n\n await this.persistTokens(tokens);\n\n return tokens;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,17 +1,17 @@
1
- /*
2
- Copyright 2023 The Matrix.org Foundation C.I.C.
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
1
+ /*
2
+ Copyright 2023 The Matrix.org Foundation C.I.C.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
15
  */
16
16
 
17
17
  import { jwtDecode } from "jwt-decode";
@@ -19,10 +19,10 @@ import { logger } from "../logger.js";
19
19
  import { OidcError } from "./error.js";
20
20
  import { OAuthGrantType } from "./index.js";
21
21
 
22
- /**
23
- * Metadata from OAuth 2.0 client authentication API as per
24
- * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata
25
- * With validated properties required in type
22
+ /**
23
+ * Metadata from OAuth 2.0 client authentication API as per
24
+ * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata
25
+ * With validated properties required in type
26
26
  */
27
27
 
28
28
  var isRecord = value => !!value && typeof value === "object" && !Array.isArray(value);
@@ -56,13 +56,13 @@ var requiredArrayValue = (wellKnown, key, value) => {
56
56
  return true;
57
57
  };
58
58
 
59
- /**
60
- * Validates OAuth 2.0 auth metadata as defined by
61
- * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata
62
- * is compatible with Element's OAuth/OIDC flow
63
- * @param authMetadata - json object
64
- * @returns valid issuer config
65
- * @throws Error - when issuer config is not found or is invalid
59
+ /**
60
+ * Validates OAuth 2.0 auth metadata as defined by
61
+ * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata
62
+ * is compatible with Element's OAuth/OIDC flow
63
+ * @param authMetadata - json object
64
+ * @returns valid issuer config
65
+ * @throws Error - when issuer config is not found or is invalid
66
66
  */
67
67
  export var validateAuthMetadata = authMetadata => {
68
68
  if (!isRecord(authMetadata)) {
@@ -85,14 +85,14 @@ export var decodeIdToken = token => {
85
85
  }
86
86
  };
87
87
 
88
- /**
89
- * Validate idToken
90
- * https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
91
- * @param idToken - id token from token endpoint
92
- * @param issuer - issuer for the OP as found during discovery
93
- * @param clientId - this client's id as registered with the OP
94
- * @param nonce - nonce used in the authentication request
95
- * @throws when id token is invalid
88
+ /**
89
+ * Validate idToken
90
+ * https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
91
+ * @param idToken - id token from token endpoint
92
+ * @param issuer - issuer for the OP as found during discovery
93
+ * @param clientId - this client's id as registered with the OP
94
+ * @param nonce - nonce used in the authentication request
95
+ * @throws when id token is invalid
96
96
  */
97
97
  export var validateIdToken = (idToken, issuer, clientId, nonce) => {
98
98
  try {
@@ -105,28 +105,28 @@ export var validateIdToken = (idToken, issuer, clientId, nonce) => {
105
105
  if (claims.iss !== issuer) {
106
106
  throw new Error("Invalid issuer");
107
107
  }
108
- /**
109
- * The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience.
110
- * The aud (audience) Claim MAY contain an array with more than one element.
111
- * The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.
112
- * EW: Don't accept tokens with other untrusted audiences
108
+ /**
109
+ * The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience.
110
+ * The aud (audience) Claim MAY contain an array with more than one element.
111
+ * The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.
112
+ * EW: Don't accept tokens with other untrusted audiences
113
113
  * */
114
114
  var sanitisedAuds = typeof claims.aud === "string" ? [claims.aud] : claims.aud;
115
115
  if (!sanitisedAuds.includes(clientId)) {
116
116
  throw new Error("Invalid audience");
117
117
  }
118
118
 
119
- /**
120
- * If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present and its value checked
121
- * to verify that it is the same value as the one that was sent in the Authentication Request.
119
+ /**
120
+ * If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present and its value checked
121
+ * to verify that it is the same value as the one that was sent in the Authentication Request.
122
122
  */
123
123
  if (nonce !== undefined && claims.nonce !== nonce) {
124
124
  throw new Error("Invalid nonce");
125
125
  }
126
126
 
127
- /**
128
- * The current time MUST be before the time represented by the exp Claim.
129
- * exp is an epoch timestamp in seconds
127
+ /**
128
+ * The current time MUST be before the time represented by the exp Claim.
129
+ * exp is an epoch timestamp in seconds
130
130
  * */
131
131
  if (!claims.exp || Date.now() > claims.exp * 1000) {
132
132
  throw new Error("Invalid expiry");
@@ -137,15 +137,15 @@ export var validateIdToken = (idToken, issuer, clientId, nonce) => {
137
137
  }
138
138
  };
139
139
 
140
- /**
141
- * State we ask OidcClient to store when starting oidc authorization flow (in `generateOidcAuthorizationUrl`)
142
- * so that we can access it on return from the OP and complete login
140
+ /**
141
+ * State we ask OidcClient to store when starting oidc authorization flow (in `generateOidcAuthorizationUrl`)
142
+ * so that we can access it on return from the OP and complete login
143
143
  */
144
144
 
145
- /**
146
- * Validate stored user state exists and is valid
147
- * @param userState - userState returned by oidcClient.processSigninResponse
148
- * @throws when userState is invalid
145
+ /**
146
+ * Validate stored user state exists and is valid
147
+ * @param userState - userState returned by oidcClient.processSigninResponse
148
+ * @throws when userState is invalid
149
149
  */
150
150
  export function validateStoredUserState(userState) {
151
151
  if (!isRecord(userState)) {
@@ -158,16 +158,16 @@ export function validateStoredUserState(userState) {
158
158
  }
159
159
  }
160
160
 
161
- /**
162
- * The expected response type from the token endpoint during authorization code flow
163
- * Normalized to always use capitalized 'Bearer' for token_type
164
- *
165
- * See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4,
166
- * https://openid.net/specs/openid-connect-basic-1_0.html#TokenOK.
161
+ /**
162
+ * The expected response type from the token endpoint during authorization code flow
163
+ * Normalized to always use capitalized 'Bearer' for token_type
164
+ *
165
+ * See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4,
166
+ * https://openid.net/specs/openid-connect-basic-1_0.html#TokenOK.
167
167
  */
168
168
 
169
- /**
170
- * Make required properties required in type
169
+ /**
170
+ * Make required properties required in type
171
171
  */
172
172
 
173
173
  var isValidBearerTokenResponse = response => isRecord(response) && requiredStringProperty(response, "token_type") &&
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","names":["jwtDecode","logger","OidcError","OAuthGrantType","isRecord","value","Array","isArray","requiredStringProperty","wellKnown","key","optionalStringProperty","error","concat","optionalStringArrayProperty","every","v","requiredArrayValue","array","includes","validateAuthMetadata","authMetadata","Error","OpSupport","isInvalid","AuthorizationCode","some","isValid","decodeIdToken","token","validateIdToken","idToken","issuer","clientId","nonce","claims","iss","sanitisedAuds","aud","undefined","exp","Date","now","InvalidIdToken","validateStoredUserState","userState","MissingOrInvalidStoredState","isValidBearerTokenResponse","response","toLowerCase","validateBearerTokenResponse","InvalidBearerTokenResponse"],"sources":["../../src/oidc/validate.ts"],"sourcesContent":["/*\r\nCopyright 2023 The Matrix.org Foundation C.I.C.\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\n\r\nimport { jwtDecode } from \"jwt-decode\";\r\nimport { type IdTokenClaims, type OidcMetadata, type SigninResponse } from \"oidc-client-ts\";\r\n\r\nimport { logger } from \"../logger.ts\";\r\nimport { OidcError } from \"./error.ts\";\r\nimport { OAuthGrantType } from \"./index.ts\";\r\n\r\n/**\r\n * Metadata from OAuth 2.0 client authentication API as per\r\n * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata\r\n * With validated properties required in type\r\n */\r\nexport type ValidatedAuthMetadata = Partial<OidcMetadata> &\r\n Pick<\r\n // These values are from [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414#section-2)\r\n // so we can reuse the OidcMetadata definitions from oidc-client-ts\r\n OidcMetadata,\r\n | \"issuer\"\r\n | \"authorization_endpoint\"\r\n | \"token_endpoint\"\r\n | \"revocation_endpoint\"\r\n | \"response_types_supported\"\r\n | \"grant_types_supported\"\r\n | \"code_challenge_methods_supported\"\r\n > & {\r\n // These values aren't part of RFC8414 so we add them here\r\n // Account management fields from stable MSC4191:\r\n account_management_uri?: string;\r\n account_management_actions_supported?: string[];\r\n // Value from [Initiating User Registration via OpenID Connect](https://openid.net/specs/openid-connect-prompt-create-1_0.html):\r\n prompt_values_supported?: string[];\r\n // Experimental MSC4341 value from [RFC8628](https://datatracker.ietf.org/doc/html/rfc8628#section-4):\r\n device_authorization_endpoint?: string;\r\n };\r\n\r\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\r\n !!value && typeof value === \"object\" && !Array.isArray(value);\r\nconst requiredStringProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {\r\n if (!wellKnown[key] || !optionalStringProperty(wellKnown, key)) {\r\n logger.error(`Missing or invalid property: ${key}`);\r\n return false;\r\n }\r\n return true;\r\n};\r\nconst optionalStringProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {\r\n if (!!wellKnown[key] && typeof wellKnown[key] !== \"string\") {\r\n logger.error(`Invalid property: ${key}`);\r\n return false;\r\n }\r\n return true;\r\n};\r\nconst optionalStringArrayProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {\r\n if (\r\n !!wellKnown[key] &&\r\n (!Array.isArray(wellKnown[key]) || !(<unknown[]>wellKnown[key]).every((v) => typeof v === \"string\"))\r\n ) {\r\n logger.error(`Invalid property: ${key}`);\r\n return false;\r\n }\r\n return true;\r\n};\r\nconst requiredArrayValue = (wellKnown: Record<string, unknown>, key: string, value: any): boolean => {\r\n const array = wellKnown[key];\r\n if (!array || !Array.isArray(array) || !array.includes(value)) {\r\n logger.error(`Invalid property: ${key}. ${value} is required.`);\r\n return false;\r\n }\r\n return true;\r\n};\r\n\r\n/**\r\n * Validates OAuth 2.0 auth metadata as defined by\r\n * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata\r\n * is compatible with Element's OAuth/OIDC flow\r\n * @param authMetadata - json object\r\n * @returns valid issuer config\r\n * @throws Error - when issuer config is not found or is invalid\r\n */\r\nexport const validateAuthMetadata = (authMetadata: unknown): ValidatedAuthMetadata => {\r\n if (!isRecord(authMetadata)) {\r\n logger.error(\"Issuer configuration not found or malformed\");\r\n throw new Error(OidcError.OpSupport);\r\n }\r\n\r\n const isInvalid = [\r\n requiredStringProperty(authMetadata, \"issuer\"),\r\n requiredStringProperty(authMetadata, \"authorization_endpoint\"),\r\n requiredStringProperty(authMetadata, \"token_endpoint\"),\r\n requiredStringProperty(authMetadata, \"revocation_endpoint\"),\r\n optionalStringProperty(authMetadata, \"registration_endpoint\"),\r\n optionalStringProperty(authMetadata, \"account_management_uri\"),\r\n optionalStringProperty(authMetadata, \"device_authorization_endpoint\"),\r\n optionalStringArrayProperty(authMetadata, \"account_management_actions_supported\"),\r\n requiredArrayValue(authMetadata, \"response_types_supported\", \"code\"),\r\n requiredArrayValue(authMetadata, \"grant_types_supported\", OAuthGrantType.AuthorizationCode),\r\n requiredArrayValue(authMetadata, \"code_challenge_methods_supported\", \"S256\"),\r\n optionalStringArrayProperty(authMetadata, \"prompt_values_supported\"),\r\n ].some((isValid) => !isValid);\r\n\r\n if (!isInvalid) {\r\n return authMetadata as ValidatedAuthMetadata;\r\n }\r\n\r\n logger.error(\"Issuer configuration not valid\");\r\n throw new Error(OidcError.OpSupport);\r\n};\r\n\r\nexport const decodeIdToken = (token: string): IdTokenClaims => {\r\n try {\r\n return jwtDecode<IdTokenClaims>(token);\r\n } catch (error) {\r\n logger.error(\"Could not decode id_token\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Validate idToken\r\n * https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation\r\n * @param idToken - id token from token endpoint\r\n * @param issuer - issuer for the OP as found during discovery\r\n * @param clientId - this client's id as registered with the OP\r\n * @param nonce - nonce used in the authentication request\r\n * @throws when id token is invalid\r\n */\r\nexport const validateIdToken = (\r\n idToken: string | undefined,\r\n issuer: string,\r\n clientId: string,\r\n nonce: string | undefined,\r\n): void => {\r\n try {\r\n if (!idToken) {\r\n throw new Error(\"No ID token\");\r\n }\r\n const claims = decodeIdToken(idToken);\r\n\r\n // The Issuer Identifier for the OpenID Provider MUST exactly match the value of the iss (issuer) Claim.\r\n if (claims.iss !== issuer) {\r\n throw new Error(\"Invalid issuer\");\r\n }\r\n /**\r\n * The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience.\r\n * The aud (audience) Claim MAY contain an array with more than one element.\r\n * The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.\r\n * EW: Don't accept tokens with other untrusted audiences\r\n * */\r\n const sanitisedAuds = typeof claims.aud === \"string\" ? [claims.aud] : claims.aud;\r\n if (!sanitisedAuds.includes(clientId)) {\r\n throw new Error(\"Invalid audience\");\r\n }\r\n\r\n /**\r\n * If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present and its value checked\r\n * to verify that it is the same value as the one that was sent in the Authentication Request.\r\n */\r\n if (nonce !== undefined && claims.nonce !== nonce) {\r\n throw new Error(\"Invalid nonce\");\r\n }\r\n\r\n /**\r\n * The current time MUST be before the time represented by the exp Claim.\r\n * exp is an epoch timestamp in seconds\r\n * */\r\n if (!claims.exp || Date.now() > claims.exp * 1000) {\r\n throw new Error(\"Invalid expiry\");\r\n }\r\n } catch (error) {\r\n logger.error(\"Invalid ID token\", error);\r\n throw new Error(OidcError.InvalidIdToken);\r\n }\r\n};\r\n\r\n/**\r\n * State we ask OidcClient to store when starting oidc authorization flow (in `generateOidcAuthorizationUrl`)\r\n * so that we can access it on return from the OP and complete login\r\n */\r\nexport type UserState = {\r\n /**\r\n * Remember which server we were trying to login to\r\n */\r\n homeserverUrl: string;\r\n identityServerUrl?: string;\r\n /**\r\n * Used to validate id token\r\n */\r\n nonce: string;\r\n};\r\n/**\r\n * Validate stored user state exists and is valid\r\n * @param userState - userState returned by oidcClient.processSigninResponse\r\n * @throws when userState is invalid\r\n */\r\nexport function validateStoredUserState(userState: unknown): asserts userState is UserState {\r\n if (!isRecord(userState)) {\r\n logger.error(\"Stored user state not found\");\r\n throw new Error(OidcError.MissingOrInvalidStoredState);\r\n }\r\n const isInvalid = [\r\n requiredStringProperty(userState, \"homeserverUrl\"),\r\n requiredStringProperty(userState, \"nonce\"),\r\n optionalStringProperty(userState, \"identityServerUrl\"),\r\n ].some((isValid) => !isValid);\r\n\r\n if (isInvalid) {\r\n throw new Error(OidcError.MissingOrInvalidStoredState);\r\n }\r\n}\r\n\r\n/**\r\n * The expected response type from the token endpoint during authorization code flow\r\n * Normalized to always use capitalized 'Bearer' for token_type\r\n *\r\n * See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4,\r\n * https://openid.net/specs/openid-connect-basic-1_0.html#TokenOK.\r\n */\r\nexport type BearerTokenResponse = {\r\n token_type: \"Bearer\";\r\n access_token: string;\r\n scope: string;\r\n refresh_token?: string;\r\n expires_in?: number;\r\n // from oidc-client-ts\r\n expires_at?: number;\r\n id_token: string;\r\n};\r\n\r\n/**\r\n * Make required properties required in type\r\n */\r\ntype ValidSignInResponse = SigninResponse &\r\n BearerTokenResponse & {\r\n token_type: \"Bearer\" | \"bearer\";\r\n };\r\n\r\nconst isValidBearerTokenResponse = (response: unknown): response is ValidSignInResponse =>\r\n isRecord(response) &&\r\n requiredStringProperty(response, \"token_type\") &&\r\n // token_type is case insensitive, some OPs return `token_type: \"bearer\"`\r\n (response[\"token_type\"] as string).toLowerCase() === \"bearer\" &&\r\n requiredStringProperty(response, \"access_token\") &&\r\n requiredStringProperty(response, \"refresh_token\") &&\r\n (!(\"expires_in\" in response) || typeof response[\"expires_in\"] === \"number\");\r\n\r\nexport function validateBearerTokenResponse(response: unknown): asserts response is ValidSignInResponse {\r\n if (!isValidBearerTokenResponse(response)) {\r\n throw new Error(OidcError.InvalidBearerTokenResponse);\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"validate.js","names":["jwtDecode","logger","OidcError","OAuthGrantType","isRecord","value","Array","isArray","requiredStringProperty","wellKnown","key","optionalStringProperty","error","concat","optionalStringArrayProperty","every","v","requiredArrayValue","array","includes","validateAuthMetadata","authMetadata","Error","OpSupport","isInvalid","AuthorizationCode","some","isValid","decodeIdToken","token","validateIdToken","idToken","issuer","clientId","nonce","claims","iss","sanitisedAuds","aud","undefined","exp","Date","now","InvalidIdToken","validateStoredUserState","userState","MissingOrInvalidStoredState","isValidBearerTokenResponse","response","toLowerCase","validateBearerTokenResponse","InvalidBearerTokenResponse"],"sources":["../../src/oidc/validate.ts"],"sourcesContent":["/*\nCopyright 2023 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport { jwtDecode } from \"jwt-decode\";\nimport { type IdTokenClaims, type OidcMetadata, type SigninResponse } from \"oidc-client-ts\";\n\nimport { logger } from \"../logger.ts\";\nimport { OidcError } from \"./error.ts\";\nimport { OAuthGrantType } from \"./index.ts\";\n\n/**\n * Metadata from OAuth 2.0 client authentication API as per\n * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata\n * With validated properties required in type\n */\nexport type ValidatedAuthMetadata = Partial<OidcMetadata> &\n Pick<\n // These values are from [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414#section-2)\n // so we can reuse the OidcMetadata definitions from oidc-client-ts\n OidcMetadata,\n | \"issuer\"\n | \"authorization_endpoint\"\n | \"token_endpoint\"\n | \"revocation_endpoint\"\n | \"response_types_supported\"\n | \"grant_types_supported\"\n | \"code_challenge_methods_supported\"\n > & {\n // These values aren't part of RFC8414 so we add them here\n // Account management fields from stable MSC4191:\n account_management_uri?: string;\n account_management_actions_supported?: string[];\n // Value from [Initiating User Registration via OpenID Connect](https://openid.net/specs/openid-connect-prompt-create-1_0.html):\n prompt_values_supported?: string[];\n // Experimental MSC4341 value from [RFC8628](https://datatracker.ietf.org/doc/html/rfc8628#section-4):\n device_authorization_endpoint?: string;\n };\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\nconst requiredStringProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {\n if (!wellKnown[key] || !optionalStringProperty(wellKnown, key)) {\n logger.error(`Missing or invalid property: ${key}`);\n return false;\n }\n return true;\n};\nconst optionalStringProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {\n if (!!wellKnown[key] && typeof wellKnown[key] !== \"string\") {\n logger.error(`Invalid property: ${key}`);\n return false;\n }\n return true;\n};\nconst optionalStringArrayProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {\n if (\n !!wellKnown[key] &&\n (!Array.isArray(wellKnown[key]) || !(<unknown[]>wellKnown[key]).every((v) => typeof v === \"string\"))\n ) {\n logger.error(`Invalid property: ${key}`);\n return false;\n }\n return true;\n};\nconst requiredArrayValue = (wellKnown: Record<string, unknown>, key: string, value: any): boolean => {\n const array = wellKnown[key];\n if (!array || !Array.isArray(array) || !array.includes(value)) {\n logger.error(`Invalid property: ${key}. ${value} is required.`);\n return false;\n }\n return true;\n};\n\n/**\n * Validates OAuth 2.0 auth metadata as defined by\n * https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv1auth_metadata\n * is compatible with Element's OAuth/OIDC flow\n * @param authMetadata - json object\n * @returns valid issuer config\n * @throws Error - when issuer config is not found or is invalid\n */\nexport const validateAuthMetadata = (authMetadata: unknown): ValidatedAuthMetadata => {\n if (!isRecord(authMetadata)) {\n logger.error(\"Issuer configuration not found or malformed\");\n throw new Error(OidcError.OpSupport);\n }\n\n const isInvalid = [\n requiredStringProperty(authMetadata, \"issuer\"),\n requiredStringProperty(authMetadata, \"authorization_endpoint\"),\n requiredStringProperty(authMetadata, \"token_endpoint\"),\n requiredStringProperty(authMetadata, \"revocation_endpoint\"),\n optionalStringProperty(authMetadata, \"registration_endpoint\"),\n optionalStringProperty(authMetadata, \"account_management_uri\"),\n optionalStringProperty(authMetadata, \"device_authorization_endpoint\"),\n optionalStringArrayProperty(authMetadata, \"account_management_actions_supported\"),\n requiredArrayValue(authMetadata, \"response_types_supported\", \"code\"),\n requiredArrayValue(authMetadata, \"grant_types_supported\", OAuthGrantType.AuthorizationCode),\n requiredArrayValue(authMetadata, \"code_challenge_methods_supported\", \"S256\"),\n optionalStringArrayProperty(authMetadata, \"prompt_values_supported\"),\n ].some((isValid) => !isValid);\n\n if (!isInvalid) {\n return authMetadata as ValidatedAuthMetadata;\n }\n\n logger.error(\"Issuer configuration not valid\");\n throw new Error(OidcError.OpSupport);\n};\n\nexport const decodeIdToken = (token: string): IdTokenClaims => {\n try {\n return jwtDecode<IdTokenClaims>(token);\n } catch (error) {\n logger.error(\"Could not decode id_token\", error);\n throw error;\n }\n};\n\n/**\n * Validate idToken\n * https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation\n * @param idToken - id token from token endpoint\n * @param issuer - issuer for the OP as found during discovery\n * @param clientId - this client's id as registered with the OP\n * @param nonce - nonce used in the authentication request\n * @throws when id token is invalid\n */\nexport const validateIdToken = (\n idToken: string | undefined,\n issuer: string,\n clientId: string,\n nonce: string | undefined,\n): void => {\n try {\n if (!idToken) {\n throw new Error(\"No ID token\");\n }\n const claims = decodeIdToken(idToken);\n\n // The Issuer Identifier for the OpenID Provider MUST exactly match the value of the iss (issuer) Claim.\n if (claims.iss !== issuer) {\n throw new Error(\"Invalid issuer\");\n }\n /**\n * The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience.\n * The aud (audience) Claim MAY contain an array with more than one element.\n * The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.\n * EW: Don't accept tokens with other untrusted audiences\n * */\n const sanitisedAuds = typeof claims.aud === \"string\" ? [claims.aud] : claims.aud;\n if (!sanitisedAuds.includes(clientId)) {\n throw new Error(\"Invalid audience\");\n }\n\n /**\n * If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present and its value checked\n * to verify that it is the same value as the one that was sent in the Authentication Request.\n */\n if (nonce !== undefined && claims.nonce !== nonce) {\n throw new Error(\"Invalid nonce\");\n }\n\n /**\n * The current time MUST be before the time represented by the exp Claim.\n * exp is an epoch timestamp in seconds\n * */\n if (!claims.exp || Date.now() > claims.exp * 1000) {\n throw new Error(\"Invalid expiry\");\n }\n } catch (error) {\n logger.error(\"Invalid ID token\", error);\n throw new Error(OidcError.InvalidIdToken);\n }\n};\n\n/**\n * State we ask OidcClient to store when starting oidc authorization flow (in `generateOidcAuthorizationUrl`)\n * so that we can access it on return from the OP and complete login\n */\nexport type UserState = {\n /**\n * Remember which server we were trying to login to\n */\n homeserverUrl: string;\n identityServerUrl?: string;\n /**\n * Used to validate id token\n */\n nonce: string;\n};\n/**\n * Validate stored user state exists and is valid\n * @param userState - userState returned by oidcClient.processSigninResponse\n * @throws when userState is invalid\n */\nexport function validateStoredUserState(userState: unknown): asserts userState is UserState {\n if (!isRecord(userState)) {\n logger.error(\"Stored user state not found\");\n throw new Error(OidcError.MissingOrInvalidStoredState);\n }\n const isInvalid = [\n requiredStringProperty(userState, \"homeserverUrl\"),\n requiredStringProperty(userState, \"nonce\"),\n optionalStringProperty(userState, \"identityServerUrl\"),\n ].some((isValid) => !isValid);\n\n if (isInvalid) {\n throw new Error(OidcError.MissingOrInvalidStoredState);\n }\n}\n\n/**\n * The expected response type from the token endpoint during authorization code flow\n * Normalized to always use capitalized 'Bearer' for token_type\n *\n * See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.4,\n * https://openid.net/specs/openid-connect-basic-1_0.html#TokenOK.\n */\nexport type BearerTokenResponse = {\n token_type: \"Bearer\";\n access_token: string;\n scope: string;\n refresh_token?: string;\n expires_in?: number;\n // from oidc-client-ts\n expires_at?: number;\n id_token: string;\n};\n\n/**\n * Make required properties required in type\n */\ntype ValidSignInResponse = SigninResponse &\n BearerTokenResponse & {\n token_type: \"Bearer\" | \"bearer\";\n };\n\nconst isValidBearerTokenResponse = (response: unknown): response is ValidSignInResponse =>\n isRecord(response) &&\n requiredStringProperty(response, \"token_type\") &&\n // token_type is case insensitive, some OPs return `token_type: \"bearer\"`\n (response[\"token_type\"] as string).toLowerCase() === \"bearer\" &&\n requiredStringProperty(response, \"access_token\") &&\n requiredStringProperty(response, \"refresh_token\") &&\n (!(\"expires_in\" in response) || typeof response[\"expires_in\"] === \"number\");\n\nexport function validateBearerTokenResponse(response: unknown): asserts response is ValidSignInResponse {\n if (!isValidBearerTokenResponse(response)) {\n throw new Error(OidcError.InvalidBearerTokenResponse);\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,SAAS,QAAQ,YAAY;AAGtC,SAASC,MAAM,QAAQ,cAAc;AACrC,SAASC,SAAS,QAAQ,YAAY;AACtC,SAASC,cAAc,QAAQ,YAAY;;AAE3C;AACA;AACA;AACA;AACA;;AAwBA,IAAMC,QAAQ,GAAIC,KAAc,IAC5B,CAAC,CAACA,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,CAACC,KAAK,CAACC,OAAO,CAACF,KAAK,CAAC;AACjE,IAAMG,sBAAsB,GAAGA,CAACC,SAAkC,EAAEC,GAAW,KAAc;EACzF,IAAI,CAACD,SAAS,CAACC,GAAG,CAAC,IAAI,CAACC,sBAAsB,CAACF,SAAS,EAAEC,GAAG,CAAC,EAAE;IAC5DT,MAAM,CAACW,KAAK,iCAAAC,MAAA,CAAiCH,GAAG,CAAE,CAAC;IACnD,OAAO,KAAK;EAChB;EACA,OAAO,IAAI;AACf,CAAC;AACD,IAAMC,sBAAsB,GAAGA,CAACF,SAAkC,EAAEC,GAAW,KAAc;EACzF,IAAI,CAAC,CAACD,SAAS,CAACC,GAAG,CAAC,IAAI,OAAOD,SAAS,CAACC,GAAG,CAAC,KAAK,QAAQ,EAAE;IACxDT,MAAM,CAACW,KAAK,sBAAAC,MAAA,CAAsBH,GAAG,CAAE,CAAC;IACxC,OAAO,KAAK;EAChB;EACA,OAAO,IAAI;AACf,CAAC;AACD,IAAMI,2BAA2B,GAAGA,CAACL,SAAkC,EAAEC,GAAW,KAAc;EAC9F,IACI,CAAC,CAACD,SAAS,CAACC,GAAG,CAAC,KACf,CAACJ,KAAK,CAACC,OAAO,CAACE,SAAS,CAACC,GAAG,CAAC,CAAC,IAAI,CAAaD,SAAS,CAACC,GAAG,CAAC,CAAEK,KAAK,CAAEC,CAAC,IAAK,OAAOA,CAAC,KAAK,QAAQ,CAAC,CAAC,EACtG;IACEf,MAAM,CAACW,KAAK,sBAAAC,MAAA,CAAsBH,GAAG,CAAE,CAAC;IACxC,OAAO,KAAK;EAChB;EACA,OAAO,IAAI;AACf,CAAC;AACD,IAAMO,kBAAkB,GAAGA,CAACR,SAAkC,EAAEC,GAAW,EAAEL,KAAU,KAAc;EACjG,IAAMa,KAAK,GAAGT,SAAS,CAACC,GAAG,CAAC;EAC5B,IAAI,CAACQ,KAAK,IAAI,CAACZ,KAAK,CAACC,OAAO,CAACW,KAAK,CAAC,IAAI,CAACA,KAAK,CAACC,QAAQ,CAACd,KAAK,CAAC,EAAE;IAC3DJ,MAAM,CAACW,KAAK,sBAAAC,MAAA,CAAsBH,GAAG,QAAAG,MAAA,CAAKR,KAAK,kBAAe,CAAC;IAC/D,OAAO,KAAK;EAChB;EACA,OAAO,IAAI;AACf,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,IAAMe,oBAAoB,GAAIC,YAAqB,IAA4B;EAClF,IAAI,CAACjB,QAAQ,CAACiB,YAAY,CAAC,EAAE;IACzBpB,MAAM,CAACW,KAAK,CAAC,6CAA6C,CAAC;IAC3D,MAAM,IAAIU,KAAK,CAACpB,SAAS,CAACqB,SAAS,CAAC;EACxC;EAEA,IAAMC,SAAS,GAAG,CACdhB,sBAAsB,CAACa,YAAY,EAAE,QAAQ,CAAC,EAC9Cb,sBAAsB,CAACa,YAAY,EAAE,wBAAwB,CAAC,EAC9Db,sBAAsB,CAACa,YAAY,EAAE,gBAAgB,CAAC,EACtDb,sBAAsB,CAACa,YAAY,EAAE,qBAAqB,CAAC,EAC3DV,sBAAsB,CAACU,YAAY,EAAE,uBAAuB,CAAC,EAC7DV,sBAAsB,CAACU,YAAY,EAAE,wBAAwB,CAAC,EAC9DV,sBAAsB,CAACU,YAAY,EAAE,+BAA+B,CAAC,EACrEP,2BAA2B,CAACO,YAAY,EAAE,sCAAsC,CAAC,EACjFJ,kBAAkB,CAACI,YAAY,EAAE,0BAA0B,EAAE,MAAM,CAAC,EACpEJ,kBAAkB,CAACI,YAAY,EAAE,uBAAuB,EAAElB,cAAc,CAACsB,iBAAiB,CAAC,EAC3FR,kBAAkB,CAACI,YAAY,EAAE,kCAAkC,EAAE,MAAM,CAAC,EAC5EP,2BAA2B,CAACO,YAAY,EAAE,yBAAyB,CAAC,CACvE,CAACK,IAAI,CAAEC,OAAO,IAAK,CAACA,OAAO,CAAC;EAE7B,IAAI,CAACH,SAAS,EAAE;IACZ,OAAOH,YAAY;EACvB;EAEApB,MAAM,CAACW,KAAK,CAAC,gCAAgC,CAAC;EAC9C,MAAM,IAAIU,KAAK,CAACpB,SAAS,CAACqB,SAAS,CAAC;AACxC,CAAC;AAED,OAAO,IAAMK,aAAa,GAAIC,KAAa,IAAoB;EAC3D,IAAI;IACA,OAAO7B,SAAS,CAAgB6B,KAAK,CAAC;EAC1C,CAAC,CAAC,OAAOjB,KAAK,EAAE;IACZX,MAAM,CAACW,KAAK,CAAC,2BAA2B,EAAEA,KAAK,CAAC;IAChD,MAAMA,KAAK;EACf;AACJ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,IAAMkB,eAAe,GAAGA,CAC3BC,OAA2B,EAC3BC,MAAc,EACdC,QAAgB,EAChBC,KAAyB,KAClB;EACP,IAAI;IACA,IAAI,CAACH,OAAO,EAAE;MACV,MAAM,IAAIT,KAAK,CAAC,aAAa,CAAC;IAClC;IACA,IAAMa,MAAM,GAAGP,aAAa,CAACG,OAAO,CAAC;;IAErC;IACA,IAAII,MAAM,CAACC,GAAG,KAAKJ,MAAM,EAAE;MACvB,MAAM,IAAIV,KAAK,CAAC,gBAAgB,CAAC;IACrC;IACA;AACR;AACA;AACA;AACA;AACA;IACQ,IAAMe,aAAa,GAAG,OAAOF,MAAM,CAACG,GAAG,KAAK,QAAQ,GAAG,CAACH,MAAM,CAACG,GAAG,CAAC,GAAGH,MAAM,CAACG,GAAG;IAChF,IAAI,CAACD,aAAa,CAAClB,QAAQ,CAACc,QAAQ,CAAC,EAAE;MACnC,MAAM,IAAIX,KAAK,CAAC,kBAAkB,CAAC;IACvC;;IAEA;AACR;AACA;AACA;IACQ,IAAIY,KAAK,KAAKK,SAAS,IAAIJ,MAAM,CAACD,KAAK,KAAKA,KAAK,EAAE;MAC/C,MAAM,IAAIZ,KAAK,CAAC,eAAe,CAAC;IACpC;;IAEA;AACR;AACA;AACA;IACQ,IAAI,CAACa,MAAM,CAACK,GAAG,IAAIC,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGP,MAAM,CAACK,GAAG,GAAG,IAAI,EAAE;MAC/C,MAAM,IAAIlB,KAAK,CAAC,gBAAgB,CAAC;IACrC;EACJ,CAAC,CAAC,OAAOV,KAAK,EAAE;IACZX,MAAM,CAACW,KAAK,CAAC,kBAAkB,EAAEA,KAAK,CAAC;IACvC,MAAM,IAAIU,KAAK,CAACpB,SAAS,CAACyC,cAAc,CAAC;EAC7C;AACJ,CAAC;;AAED;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CAACC,SAAkB,EAAkC;EACxF,IAAI,CAACzC,QAAQ,CAACyC,SAAS,CAAC,EAAE;IACtB5C,MAAM,CAACW,KAAK,CAAC,6BAA6B,CAAC;IAC3C,MAAM,IAAIU,KAAK,CAACpB,SAAS,CAAC4C,2BAA2B,CAAC;EAC1D;EACA,IAAMtB,SAAS,GAAG,CACdhB,sBAAsB,CAACqC,SAAS,EAAE,eAAe,CAAC,EAClDrC,sBAAsB,CAACqC,SAAS,EAAE,OAAO,CAAC,EAC1ClC,sBAAsB,CAACkC,SAAS,EAAE,mBAAmB,CAAC,CACzD,CAACnB,IAAI,CAAEC,OAAO,IAAK,CAACA,OAAO,CAAC;EAE7B,IAAIH,SAAS,EAAE;IACX,MAAM,IAAIF,KAAK,CAACpB,SAAS,CAAC4C,2BAA2B,CAAC;EAC1D;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;;AAMA,IAAMC,0BAA0B,GAAIC,QAAiB,IACjD5C,QAAQ,CAAC4C,QAAQ,CAAC,IAClBxC,sBAAsB,CAACwC,QAAQ,EAAE,YAAY,CAAC;AAC9C;AACCA,QAAQ,CAAC,YAAY,CAAC,CAAYC,WAAW,CAAC,CAAC,KAAK,QAAQ,IAC7DzC,sBAAsB,CAACwC,QAAQ,EAAE,cAAc,CAAC,IAChDxC,sBAAsB,CAACwC,QAAQ,EAAE,eAAe,CAAC,KAChD,EAAE,YAAY,IAAIA,QAAQ,CAAC,IAAI,OAAOA,QAAQ,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC;AAE/E,OAAO,SAASE,2BAA2BA,CAACF,QAAiB,EAA2C;EACpG,IAAI,CAACD,0BAA0B,CAACC,QAAQ,CAAC,EAAE;IACvC,MAAM,IAAI1B,KAAK,CAACpB,SAAS,CAACiD,0BAA0B,CAAC;EACzD;AACJ","ignoreList":[]}
@@ -1,37 +1,37 @@
1
- /*
2
- Copyright 2018 New Vector Ltd
3
- Copyright 2019 The Matrix.org Foundation C.I.C.
4
-
5
- Licensed under the Apache License, Version 2.0 (the "License");
6
- you may not use this file except in compliance with the License.
7
- You may obtain a copy of the License at
8
-
9
- http://www.apache.org/licenses/LICENSE-2.0
10
-
11
- Unless required by applicable law or agreed to in writing, software
12
- distributed under the License is distributed on an "AS IS" BASIS,
13
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- See the License for the specific language governing permissions and
15
- limitations under the License.
1
+ /*
2
+ Copyright 2018 New Vector Ltd
3
+ Copyright 2019 The Matrix.org Foundation C.I.C.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
16
  */
17
17
 
18
18
  import { encodeUnpaddedBase64Url } from "./base64.js";
19
19
 
20
- /**
21
- * String representing the lowercase latin alphabet for use in {@link secureRandomStringFrom}
22
- * (can be combined with other such exports or other characters by appending strings)
20
+ /**
21
+ * String representing the lowercase latin alphabet for use in {@link secureRandomStringFrom}
22
+ * (can be combined with other such exports or other characters by appending strings)
23
23
  */
24
24
  export var LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
25
25
 
26
- /**
27
- * String representing the uppercase latin alphabet for use in secureRandomStringFrom
28
- * (can be combined with other such exports or other characters by appending strings)
26
+ /**
27
+ * String representing the uppercase latin alphabet for use in secureRandomStringFrom
28
+ * (can be combined with other such exports or other characters by appending strings)
29
29
  */
30
30
  export var UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
31
31
 
32
- /**
33
- * String representing the arabic numerals for use in secureRandomStringFrom
34
- * (can be combined with other such exports or other characters by appending strings)
32
+ /**
33
+ * String representing the arabic numerals for use in secureRandomStringFrom
34
+ * (can be combined with other such exports or other characters by appending strings)
35
35
  */
36
36
  export var DIGITS = "0123456789";
37
37
  export function secureRandomBase64Url(len) {
@@ -40,22 +40,22 @@ export function secureRandomBase64Url(len) {
40
40
  return encodeUnpaddedBase64Url(key);
41
41
  }
42
42
 
43
- /**
44
- * Generates a random string of uppercase and lowercase letters plus digits using a
45
- * cryptographically secure random number generator.
46
- * @param len The length of the string to generate
47
- * @returns Random string of uppercase and lowercase letters plus digits of length `len`
43
+ /**
44
+ * Generates a random string of uppercase and lowercase letters plus digits using a
45
+ * cryptographically secure random number generator.
46
+ * @param len The length of the string to generate
47
+ * @returns Random string of uppercase and lowercase letters plus digits of length `len`
48
48
  */
49
49
  export function secureRandomString(len) {
50
50
  return secureRandomStringFrom(len, UPPERCASE + LOWERCASE + DIGITS);
51
51
  }
52
52
 
53
- /**
54
- * Generate a cryptographically secure random string using characters given.
55
- *
56
- * @param len - The length of the string to generate (must be positive and less than 32768).
57
- * @param chars - The characters to use in the random string (between 2 and 256 characters long).
58
- * @returns Random string of characters of length `len`.
53
+ /**
54
+ * Generate a cryptographically secure random string using characters given.
55
+ *
56
+ * @param len - The length of the string to generate (must be positive and less than 32768).
57
+ * @param chars - The characters to use in the random string (between 2 and 256 characters long).
58
+ * @returns Random string of characters of length `len`.
59
59
  */
60
60
  export function secureRandomStringFrom(len, chars) {
61
61
  // This is intended for latin strings so 256 possibilities should be more than enough and