@strivacity/sdk-core 3.0.3 → 4.0.0-beta.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 (327) hide show
  1. package/README.md +1873 -340
  2. package/dist/assets/oidc.cjs +2 -0
  3. package/dist/assets/oidc.cjs.map +1 -0
  4. package/dist/assets/oidc.mjs +2 -0
  5. package/dist/assets/oidc.mjs.map +1 -0
  6. package/dist/assets/server.cjs +2 -0
  7. package/dist/assets/server.cjs.map +1 -0
  8. package/dist/assets/server.mjs +2 -0
  9. package/dist/assets/server.mjs.map +1 -0
  10. package/dist/flows/base.cjs +2 -0
  11. package/dist/flows/base.cjs.map +1 -0
  12. package/dist/flows/base.d.ts +26 -0
  13. package/dist/flows/base.mjs +2 -0
  14. package/dist/flows/base.mjs.map +1 -0
  15. package/dist/flows/embedded.cjs +2 -0
  16. package/dist/flows/embedded.cjs.map +1 -0
  17. package/dist/flows/embedded.d.ts +9 -0
  18. package/dist/flows/embedded.mjs +2 -0
  19. package/dist/flows/embedded.mjs.map +1 -0
  20. package/dist/flows/index.cjs +1 -0
  21. package/dist/flows/index.d.ts +5 -0
  22. package/dist/flows/index.mjs +1 -0
  23. package/dist/flows/native.cjs +2 -0
  24. package/dist/flows/native.cjs.map +1 -0
  25. package/dist/flows/native.d.ts +9 -0
  26. package/dist/flows/native.mjs +2 -0
  27. package/dist/flows/native.mjs.map +1 -0
  28. package/dist/flows/popup.cjs +2 -0
  29. package/dist/flows/popup.cjs.map +1 -0
  30. package/dist/flows/popup.d.ts +9 -0
  31. package/dist/flows/popup.mjs +2 -0
  32. package/dist/flows/popup.mjs.map +1 -0
  33. package/dist/flows/redirect.cjs +2 -0
  34. package/dist/flows/redirect.cjs.map +1 -0
  35. package/dist/flows/redirect.d.ts +9 -0
  36. package/dist/flows/redirect.mjs +2 -0
  37. package/dist/flows/redirect.mjs.map +1 -0
  38. package/dist/handlers/embedded.cjs +2 -0
  39. package/dist/handlers/embedded.cjs.map +1 -0
  40. package/dist/handlers/embedded.d.ts +37 -0
  41. package/dist/handlers/embedded.mjs +2 -0
  42. package/dist/handlers/embedded.mjs.map +1 -0
  43. package/dist/handlers/index.cjs +1 -0
  44. package/dist/handlers/index.d.ts +2 -0
  45. package/dist/handlers/index.mjs +1 -0
  46. package/dist/handlers/native.cjs +2 -0
  47. package/dist/handlers/native.cjs.map +1 -0
  48. package/dist/handlers/native.d.ts +56 -0
  49. package/dist/handlers/native.mjs +2 -0
  50. package/dist/handlers/native.mjs.map +1 -0
  51. package/dist/handlers/popup.cjs +2 -0
  52. package/dist/handlers/popup.cjs.map +1 -0
  53. package/dist/handlers/popup.d.ts +21 -0
  54. package/dist/handlers/popup.mjs +2 -0
  55. package/dist/handlers/popup.mjs.map +1 -0
  56. package/dist/handlers/redirect.cjs +2 -0
  57. package/dist/handlers/redirect.cjs.map +1 -0
  58. package/dist/handlers/redirect.d.ts +18 -0
  59. package/dist/handlers/redirect.mjs +2 -0
  60. package/dist/handlers/redirect.mjs.map +1 -0
  61. package/dist/index.cjs +2 -2
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.ts +16 -21
  64. package/dist/index.mjs +2 -2
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/server/base.cjs +2 -0
  67. package/dist/server/base.cjs.map +1 -0
  68. package/dist/server/base.d.ts +15 -0
  69. package/dist/server/base.mjs +2 -0
  70. package/dist/server/base.mjs.map +1 -0
  71. package/dist/server/index.cjs +1 -0
  72. package/dist/server/index.d.ts +1 -0
  73. package/dist/server/index.mjs +1 -0
  74. package/dist/storages/cache.cjs +2 -0
  75. package/dist/storages/cache.cjs.map +1 -0
  76. package/dist/storages/cache.d.ts +11 -0
  77. package/dist/storages/cache.mjs +2 -0
  78. package/dist/storages/cache.mjs.map +1 -0
  79. package/dist/storages/index.cjs +1 -0
  80. package/dist/storages/index.d.ts +7 -0
  81. package/dist/storages/index.mjs +1 -0
  82. package/dist/storages/indexeddb.cjs +2 -0
  83. package/dist/storages/indexeddb.cjs.map +1 -0
  84. package/dist/storages/indexeddb.d.ts +10 -0
  85. package/dist/storages/indexeddb.mjs +2 -0
  86. package/dist/storages/indexeddb.mjs.map +1 -0
  87. package/dist/storages/local.cjs +2 -0
  88. package/dist/storages/local.cjs.map +1 -0
  89. package/dist/storages/local.d.ts +7 -0
  90. package/dist/storages/local.mjs +2 -0
  91. package/dist/storages/local.mjs.map +1 -0
  92. package/dist/storages/memory.cjs +2 -0
  93. package/dist/storages/memory.cjs.map +1 -0
  94. package/dist/storages/memory.d.ts +8 -0
  95. package/dist/storages/memory.mjs +2 -0
  96. package/dist/storages/memory.mjs.map +1 -0
  97. package/dist/storages/server.cjs +1 -0
  98. package/dist/storages/server.d.ts +39 -0
  99. package/dist/storages/server.mjs +1 -0
  100. package/dist/storages/session.cjs +2 -0
  101. package/dist/storages/session.cjs.map +1 -0
  102. package/dist/storages/session.d.ts +7 -0
  103. package/dist/storages/session.mjs +2 -0
  104. package/dist/storages/session.mjs.map +1 -0
  105. package/dist/storages/worker.cjs +2 -0
  106. package/dist/storages/worker.cjs.map +1 -0
  107. package/dist/storages/worker.d.ts +46 -0
  108. package/dist/storages/worker.mjs +2 -0
  109. package/dist/storages/worker.mjs.map +1 -0
  110. package/dist/types/common.cjs +0 -0
  111. package/dist/types/common.d.ts +145 -0
  112. package/dist/types/common.mjs +0 -0
  113. package/dist/types/embedded.cjs +0 -0
  114. package/dist/types/embedded.d.ts +103 -0
  115. package/dist/types/embedded.mjs +0 -0
  116. package/dist/types/index.cjs +1 -0
  117. package/dist/types/index.d.ts +7 -0
  118. package/dist/types/index.mjs +1 -0
  119. package/dist/types/native.cjs +0 -0
  120. package/dist/types/native.d.ts +385 -0
  121. package/dist/types/native.mjs +0 -0
  122. package/dist/types/oidc.cjs +2 -0
  123. package/dist/types/oidc.cjs.map +1 -0
  124. package/dist/types/oidc.d.ts +768 -0
  125. package/dist/types/oidc.mjs +2 -0
  126. package/dist/types/oidc.mjs.map +1 -0
  127. package/dist/types/popup.cjs +0 -0
  128. package/dist/types/popup.d.ts +69 -0
  129. package/dist/types/popup.mjs +0 -0
  130. package/dist/types/redirect.cjs +0 -0
  131. package/dist/types/redirect.d.ts +21 -0
  132. package/dist/types/redirect.mjs +0 -0
  133. package/dist/types/server.cjs +0 -0
  134. package/dist/types/server.d.ts +200 -0
  135. package/dist/types/server.mjs +0 -0
  136. package/dist/utils/base64url.cjs +2 -0
  137. package/dist/utils/base64url.cjs.map +1 -0
  138. package/dist/utils/base64url.d.ts +14 -0
  139. package/dist/utils/base64url.mjs +2 -0
  140. package/dist/utils/base64url.mjs.map +1 -0
  141. package/dist/utils/common.cjs +2 -0
  142. package/dist/utils/common.cjs.map +1 -0
  143. package/dist/utils/common.d.ts +23 -0
  144. package/dist/utils/common.mjs +2 -0
  145. package/dist/utils/common.mjs.map +1 -0
  146. package/dist/utils/credentials.cjs +2 -2
  147. package/dist/utils/credentials.cjs.map +1 -1
  148. package/dist/utils/credentials.d.ts +19 -3
  149. package/dist/utils/credentials.mjs +2 -2
  150. package/dist/utils/credentials.mjs.map +1 -1
  151. package/dist/utils/crypto.cjs +2 -2
  152. package/dist/utils/crypto.cjs.map +1 -1
  153. package/dist/utils/crypto.d.ts +16 -26
  154. package/dist/utils/crypto.mjs +2 -2
  155. package/dist/utils/crypto.mjs.map +1 -1
  156. package/dist/utils/dom.cjs +2 -0
  157. package/dist/utils/dom.cjs.map +1 -0
  158. package/dist/utils/dom.d.ts +7 -0
  159. package/dist/utils/dom.mjs +2 -0
  160. package/dist/utils/dom.mjs.map +1 -0
  161. package/dist/utils/errors.cjs +2 -2
  162. package/dist/utils/errors.cjs.map +1 -1
  163. package/dist/utils/errors.d.ts +62 -1
  164. package/dist/utils/errors.mjs +2 -2
  165. package/dist/utils/errors.mjs.map +1 -1
  166. package/dist/utils/httpClient.cjs +2 -0
  167. package/dist/utils/httpClient.cjs.map +1 -0
  168. package/dist/utils/httpClient.d.ts +2 -0
  169. package/dist/utils/httpClient.mjs +2 -0
  170. package/dist/utils/httpClient.mjs.map +1 -0
  171. package/dist/utils/index.cjs +1 -0
  172. package/dist/utils/index.d.ts +12 -0
  173. package/dist/utils/index.mjs +1 -0
  174. package/dist/utils/logging.cjs +2 -0
  175. package/dist/utils/logging.cjs.map +1 -0
  176. package/dist/utils/logging.d.ts +2 -0
  177. package/dist/utils/logging.mjs +2 -0
  178. package/dist/utils/logging.mjs.map +1 -0
  179. package/dist/utils/oidc.cjs +1 -0
  180. package/dist/utils/oidc.d.ts +264 -0
  181. package/dist/utils/oidc.mjs +1 -0
  182. package/dist/utils/server.cjs +1 -0
  183. package/dist/utils/server.d.ts +72 -0
  184. package/dist/utils/server.mjs +1 -0
  185. package/dist/utils/session.cjs +2 -0
  186. package/dist/utils/session.cjs.map +1 -0
  187. package/dist/utils/session.d.ts +29 -0
  188. package/dist/utils/session.mjs +2 -0
  189. package/dist/utils/session.mjs.map +1 -0
  190. package/dist/utils/state.cjs +1 -0
  191. package/dist/utils/state.d.ts +23 -0
  192. package/dist/utils/state.mjs +1 -0
  193. package/package.json +53 -1
  194. package/testing/tests/flows/base.spec.ts +1030 -0
  195. package/testing/tests/flows/embedded.spec.ts +443 -0
  196. package/testing/tests/flows/index.spec.ts +8 -0
  197. package/testing/tests/flows/native.spec.ts +487 -0
  198. package/testing/tests/flows/popup.spec.ts +400 -0
  199. package/testing/tests/flows/redirect.spec.ts +369 -0
  200. package/testing/tests/handlers/embedded.spec.ts +199 -0
  201. package/testing/tests/handlers/index.spec.ts +8 -0
  202. package/testing/tests/handlers/native.spec.ts +283 -0
  203. package/testing/tests/handlers/popup.spec.ts +206 -0
  204. package/testing/tests/handlers/redirect.spec.ts +70 -0
  205. package/testing/tests/index.spec.ts +78 -0
  206. package/testing/tests/server/base.spec.ts +846 -0
  207. package/testing/tests/server/index.spec.ts +15 -0
  208. package/testing/tests/storages/cache.spec.ts +107 -0
  209. package/testing/tests/storages/index.spec.ts +22 -0
  210. package/testing/tests/storages/indexeddb.spec.ts +113 -0
  211. package/testing/tests/storages/local.spec.ts +46 -0
  212. package/testing/tests/storages/memory.spec.ts +51 -0
  213. package/testing/tests/storages/server.spec.ts +435 -0
  214. package/testing/tests/storages/session.spec.ts +46 -0
  215. package/testing/tests/storages/worker.spec.ts +106 -0
  216. package/testing/tests/utils/common.spec.ts +77 -0
  217. package/testing/tests/utils/credentials.spec.ts +195 -0
  218. package/testing/tests/utils/dom.spec.ts +37 -0
  219. package/testing/tests/utils/index.spec.ts +71 -0
  220. package/testing/tests/utils/logging.spec.ts +82 -0
  221. package/testing/tests/utils/oidc.spec.ts +744 -0
  222. package/testing/tests/utils/server.spec.ts +235 -0
  223. package/dist/flows/BaseFlow.cjs +0 -2
  224. package/dist/flows/BaseFlow.cjs.map +0 -1
  225. package/dist/flows/BaseFlow.d.ts +0 -191
  226. package/dist/flows/BaseFlow.mjs +0 -2
  227. package/dist/flows/BaseFlow.mjs.map +0 -1
  228. package/dist/flows/EmbeddedFlow.cjs +0 -2
  229. package/dist/flows/EmbeddedFlow.cjs.map +0 -1
  230. package/dist/flows/EmbeddedFlow.d.ts +0 -26
  231. package/dist/flows/EmbeddedFlow.mjs +0 -2
  232. package/dist/flows/EmbeddedFlow.mjs.map +0 -1
  233. package/dist/flows/NativeFlow.cjs +0 -2
  234. package/dist/flows/NativeFlow.cjs.map +0 -1
  235. package/dist/flows/NativeFlow.d.ts +0 -34
  236. package/dist/flows/NativeFlow.mjs +0 -2
  237. package/dist/flows/NativeFlow.mjs.map +0 -1
  238. package/dist/flows/PopupFlow.cjs +0 -2
  239. package/dist/flows/PopupFlow.cjs.map +0 -1
  240. package/dist/flows/PopupFlow.d.ts +0 -36
  241. package/dist/flows/PopupFlow.mjs +0 -2
  242. package/dist/flows/PopupFlow.mjs.map +0 -1
  243. package/dist/flows/RedirectFlow.cjs +0 -2
  244. package/dist/flows/RedirectFlow.cjs.map +0 -1
  245. package/dist/flows/RedirectFlow.d.ts +0 -38
  246. package/dist/flows/RedirectFlow.mjs +0 -2
  247. package/dist/flows/RedirectFlow.mjs.map +0 -1
  248. package/dist/handlers/BaseFlowHandler.cjs +0 -2
  249. package/dist/handlers/BaseFlowHandler.cjs.map +0 -1
  250. package/dist/handlers/BaseFlowHandler.d.ts +0 -61
  251. package/dist/handlers/BaseFlowHandler.mjs +0 -2
  252. package/dist/handlers/BaseFlowHandler.mjs.map +0 -1
  253. package/dist/handlers/EmbeddedFlowHandler.cjs +0 -2
  254. package/dist/handlers/EmbeddedFlowHandler.cjs.map +0 -1
  255. package/dist/handlers/EmbeddedFlowHandler.d.ts +0 -28
  256. package/dist/handlers/EmbeddedFlowHandler.mjs +0 -2
  257. package/dist/handlers/EmbeddedFlowHandler.mjs.map +0 -1
  258. package/dist/handlers/NativeFlowHandler.cjs +0 -2
  259. package/dist/handlers/NativeFlowHandler.cjs.map +0 -1
  260. package/dist/handlers/NativeFlowHandler.d.ts +0 -31
  261. package/dist/handlers/NativeFlowHandler.mjs +0 -2
  262. package/dist/handlers/NativeFlowHandler.mjs.map +0 -1
  263. package/dist/storages/LocalStorage.cjs +0 -2
  264. package/dist/storages/LocalStorage.cjs.map +0 -1
  265. package/dist/storages/LocalStorage.d.ts +0 -23
  266. package/dist/storages/LocalStorage.mjs +0 -2
  267. package/dist/storages/LocalStorage.mjs.map +0 -1
  268. package/dist/storages/SessionStorage.cjs +0 -2
  269. package/dist/storages/SessionStorage.cjs.map +0 -1
  270. package/dist/storages/SessionStorage.d.ts +0 -23
  271. package/dist/storages/SessionStorage.mjs +0 -2
  272. package/dist/storages/SessionStorage.mjs.map +0 -1
  273. package/dist/types.cjs +0 -2
  274. package/dist/types.cjs.map +0 -1
  275. package/dist/types.d.ts +0 -1263
  276. package/dist/types.mjs +0 -2
  277. package/dist/types.mjs.map +0 -1
  278. package/dist/utils/HttpClient.cjs +0 -2
  279. package/dist/utils/HttpClient.cjs.map +0 -1
  280. package/dist/utils/HttpClient.d.ts +0 -4
  281. package/dist/utils/HttpClient.mjs +0 -2
  282. package/dist/utils/HttpClient.mjs.map +0 -1
  283. package/dist/utils/Logging.cjs +0 -2
  284. package/dist/utils/Logging.cjs.map +0 -1
  285. package/dist/utils/Logging.d.ts +0 -8
  286. package/dist/utils/Logging.mjs +0 -2
  287. package/dist/utils/Logging.mjs.map +0 -1
  288. package/dist/utils/Metadata.cjs +0 -2
  289. package/dist/utils/Metadata.cjs.map +0 -1
  290. package/dist/utils/Metadata.d.ts +0 -98
  291. package/dist/utils/Metadata.mjs +0 -2
  292. package/dist/utils/Metadata.mjs.map +0 -1
  293. package/dist/utils/Session.cjs +0 -2
  294. package/dist/utils/Session.cjs.map +0 -1
  295. package/dist/utils/Session.d.ts +0 -82
  296. package/dist/utils/Session.mjs +0 -2
  297. package/dist/utils/Session.mjs.map +0 -1
  298. package/dist/utils/State.cjs +0 -2
  299. package/dist/utils/State.cjs.map +0 -1
  300. package/dist/utils/State.d.ts +0 -43
  301. package/dist/utils/State.mjs +0 -2
  302. package/dist/utils/State.mjs.map +0 -1
  303. package/dist/utils/base64Url.cjs +0 -2
  304. package/dist/utils/base64Url.cjs.map +0 -1
  305. package/dist/utils/base64Url.d.ts +0 -27
  306. package/dist/utils/base64Url.mjs +0 -2
  307. package/dist/utils/base64Url.mjs.map +0 -1
  308. package/dist/utils/date.cjs +0 -2
  309. package/dist/utils/date.cjs.map +0 -1
  310. package/dist/utils/date.d.ts +0 -6
  311. package/dist/utils/date.mjs +0 -2
  312. package/dist/utils/date.mjs.map +0 -1
  313. package/dist/utils/handlers.cjs +0 -2
  314. package/dist/utils/handlers.cjs.map +0 -1
  315. package/dist/utils/handlers.d.ts +0 -35
  316. package/dist/utils/handlers.mjs +0 -2
  317. package/dist/utils/handlers.mjs.map +0 -1
  318. package/dist/utils/jwt.cjs +0 -2
  319. package/dist/utils/jwt.cjs.map +0 -1
  320. package/dist/utils/jwt.d.ts +0 -34
  321. package/dist/utils/jwt.mjs +0 -2
  322. package/dist/utils/jwt.mjs.map +0 -1
  323. package/dist/utils/object.cjs +0 -2
  324. package/dist/utils/object.cjs.map +0 -1
  325. package/dist/utils/object.d.ts +0 -1
  326. package/dist/utils/object.mjs +0 -2
  327. package/dist/utils/object.mjs.map +0 -1
@@ -0,0 +1,195 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ import { describe, test, expect, afterEach } from 'vitest';
4
+ import { createWebAuthnCredential, assertWebAuthnCredential } from '../../../src/utils/credentials';
5
+ import { ProtocolError } from '../../../src/utils/errors';
6
+ import { encodeBase64URL } from '../../../src/utils/base64url';
7
+ import { creationOptions, fromBuffer, mockCredentials, requestOptions, toBuffer } from '@strivacity/testing/mocks/credentials';
8
+
9
+ describe('createWebAuthnCredential', () => {
10
+ afterEach(() => {
11
+ delete (navigator as any).credentials;
12
+ });
13
+
14
+ test('decodes the challenge, user id and excludeCredentials ids, and returns the formatted registration response', async () => {
15
+ let capturedPublicKey: any;
16
+
17
+ mockCredentials({
18
+ create: (options) => {
19
+ capturedPublicKey = options.publicKey;
20
+ return Promise.resolve({
21
+ id: 'credential-id',
22
+ rawId: toBuffer('raw-id'),
23
+ type: 'public-key',
24
+ authenticatorAttachment: 'platform',
25
+ response: {
26
+ clientDataJSON: toBuffer('client-data'),
27
+ attestationObject: toBuffer('attestation'),
28
+ getTransports: () => ['internal'],
29
+ },
30
+ getClientExtensionResults: () => ({ foo: 'bar' }),
31
+ });
32
+ },
33
+ });
34
+
35
+ const result = await createWebAuthnCredential(
36
+ creationOptions({ excludeCredentials: [{ id: encodeBase64URL(toBuffer('exclude-1')), type: 'public-key' }] }),
37
+ );
38
+
39
+ expect(fromBuffer(capturedPublicKey.challenge)).toBe('challenge');
40
+ expect(fromBuffer(capturedPublicKey.user.id)).toBe('user-1');
41
+ expect(fromBuffer(capturedPublicKey.excludeCredentials[0].id)).toBe('exclude-1');
42
+
43
+ expect(result).toEqual({
44
+ id: 'credential-id',
45
+ rawId: encodeBase64URL(toBuffer('raw-id')),
46
+ response: {
47
+ clientDataJSON: encodeBase64URL(toBuffer('client-data')),
48
+ attestationObject: encodeBase64URL(toBuffer('attestation')),
49
+ transports: ['internal'],
50
+ },
51
+ authenticatorAttachment: 'platform',
52
+ clientExtensionResults: { foo: 'bar' },
53
+ type: 'public-key',
54
+ });
55
+ });
56
+
57
+ test('defaults excludeCredentials to an empty array when not provided', async () => {
58
+ let capturedPublicKey: any;
59
+
60
+ mockCredentials({
61
+ create: (options) => {
62
+ capturedPublicKey = options.publicKey;
63
+ return Promise.resolve({
64
+ type: 'public-key',
65
+ rawId: toBuffer('raw-id'),
66
+ response: { clientDataJSON: toBuffer(''), attestationObject: toBuffer('') },
67
+ getClientExtensionResults: () => ({}),
68
+ });
69
+ },
70
+ });
71
+
72
+ await createWebAuthnCredential(creationOptions());
73
+
74
+ expect(capturedPublicKey.excludeCredentials).toEqual([]);
75
+ });
76
+
77
+ test('defaults transports to an empty array when the response has no getTransports', async () => {
78
+ mockCredentials({
79
+ create: () =>
80
+ Promise.resolve({
81
+ type: 'public-key',
82
+ rawId: toBuffer('raw-id'),
83
+ response: { clientDataJSON: toBuffer(''), attestationObject: toBuffer('') },
84
+ getClientExtensionResults: () => ({}),
85
+ }),
86
+ });
87
+
88
+ const result = await createWebAuthnCredential(creationOptions());
89
+
90
+ expect(result.response.transports).toEqual([]);
91
+ });
92
+
93
+ test('forwards the provided AbortController signal to navigator.credentials.create', async () => {
94
+ let capturedSignal: AbortSignal | undefined;
95
+ const abortController = new AbortController();
96
+
97
+ mockCredentials({
98
+ create: (options) => {
99
+ capturedSignal = options.signal;
100
+ return Promise.resolve({
101
+ type: 'public-key',
102
+ rawId: toBuffer('raw-id'),
103
+ response: { clientDataJSON: toBuffer(''), attestationObject: toBuffer('') },
104
+ getClientExtensionResults: () => ({}),
105
+ });
106
+ },
107
+ });
108
+
109
+ await createWebAuthnCredential(creationOptions(), abortController);
110
+
111
+ expect(capturedSignal).toBe(abortController.signal);
112
+ });
113
+
114
+ test('throws a ProtocolError when the created credential is not a public-key credential', async () => {
115
+ mockCredentials({ create: () => Promise.resolve({ type: 'other', response: {} }) });
116
+
117
+ await expect(createWebAuthnCredential(creationOptions())).rejects.toThrow(new ProtocolError('Not a public key'));
118
+ });
119
+ });
120
+
121
+ describe('assertWebAuthnCredential', () => {
122
+ afterEach(() => {
123
+ delete (navigator as any).credentials;
124
+ });
125
+
126
+ test('decodes the challenge and allowCredentials ids, and returns credential.toJSON()', async () => {
127
+ let capturedPublicKey: any;
128
+ const toJSONResult = { id: 'credential-id' };
129
+
130
+ mockCredentials({
131
+ get: (options) => {
132
+ capturedPublicKey = options.publicKey;
133
+ return Promise.resolve({ type: 'public-key', toJSON: () => toJSONResult });
134
+ },
135
+ });
136
+
137
+ const result = await assertWebAuthnCredential(requestOptions({ allowCredentials: [{ id: encodeBase64URL(toBuffer('allow-1')), type: 'public-key' }] }));
138
+
139
+ expect(fromBuffer(capturedPublicKey.challenge)).toBe('challenge');
140
+ expect(fromBuffer(capturedPublicKey.allowCredentials[0].id)).toBe('allow-1');
141
+ expect(result).toBe(toJSONResult);
142
+ });
143
+
144
+ test('defaults allowCredentials to an empty array when not provided', async () => {
145
+ let capturedPublicKey: any;
146
+
147
+ mockCredentials({
148
+ get: (options) => {
149
+ capturedPublicKey = options.publicKey;
150
+ return Promise.resolve({ type: 'public-key', toJSON: () => ({}) });
151
+ },
152
+ });
153
+
154
+ await assertWebAuthnCredential(requestOptions());
155
+
156
+ expect(capturedPublicKey.allowCredentials).toEqual([]);
157
+ });
158
+
159
+ test('defaults the mediation requirement to "optional"', async () => {
160
+ let capturedMediation;
161
+
162
+ mockCredentials({
163
+ get: (options) => {
164
+ capturedMediation = options.mediation;
165
+ return Promise.resolve({ type: 'public-key', toJSON: () => ({}) });
166
+ },
167
+ });
168
+
169
+ await assertWebAuthnCredential(requestOptions());
170
+
171
+ expect(capturedMediation).toBe('optional');
172
+ });
173
+
174
+ test('uses the provided mediation requirement', async () => {
175
+ let capturedMediation;
176
+
177
+ mockCredentials({
178
+ get: (options) => {
179
+ capturedMediation = options.mediation;
180
+
181
+ return Promise.resolve({ type: 'public-key', toJSON: () => ({}) });
182
+ },
183
+ });
184
+
185
+ await assertWebAuthnCredential(requestOptions(), 'conditional');
186
+
187
+ expect(capturedMediation).toBe('conditional');
188
+ });
189
+
190
+ test('throws a ProtocolError when the retrieved credential is not a public-key credential', async () => {
191
+ mockCredentials({ get: () => Promise.resolve({ type: 'other', toJSON: () => ({}) }) });
192
+
193
+ await expect(assertWebAuthnCredential(requestOptions())).rejects.toThrow(new ProtocolError('Not a public key'));
194
+ });
195
+ });
@@ -0,0 +1,37 @@
1
+ import { describe, test, expect, vi, afterEach } from 'vitest';
2
+ import { injectScript } from '../../../src/utils/dom';
3
+
4
+ describe('injectScript', () => {
5
+ afterEach(() => {
6
+ vi.unstubAllGlobals();
7
+ document.getElementById('script-id')?.remove();
8
+ });
9
+
10
+ test('appends a script element with the given id, src, async and module type', () => {
11
+ injectScript('script-id', 'https://brandtegrity.io/script.js');
12
+
13
+ const script = document.getElementById('script-id') as HTMLScriptElement;
14
+
15
+ expect(script).not.toBeNull();
16
+ expect(script.src).toBe('https://brandtegrity.io/script.js');
17
+ expect(script.async).toBe(true);
18
+ expect(script.type).toBe('module');
19
+ expect(script.parentElement).toBe(document.body);
20
+ });
21
+
22
+ test('does not inject a second script when an element with the same id already exists', () => {
23
+ injectScript('script-id', 'https://brandtegrity.io/first.js');
24
+ injectScript('script-id', 'https://brandtegrity.io/second.js');
25
+
26
+ const script = document.getElementById('script-id') as HTMLScriptElement;
27
+
28
+ expect(script.src).toBe('https://brandtegrity.io/first.js');
29
+ expect(document.querySelectorAll('#script-id').length).toBe(1);
30
+ });
31
+
32
+ test('is a no-op when document is unavailable', () => {
33
+ vi.stubGlobal('document', undefined);
34
+
35
+ expect(() => injectScript('script-id', 'https://brandtegrity.io/script.js')).not.toThrow();
36
+ });
37
+ });
@@ -0,0 +1,71 @@
1
+ import { test, expect } from 'vitest';
2
+ import * as index from '../../../src/utils';
3
+
4
+ test('should export the correct things', () => {
5
+ const expectedExports = [
6
+ 'encodeBase64URL',
7
+ 'decodeBase64URL',
8
+ 'timestamp',
9
+ 'unflattenObject',
10
+ 'buildCookieString',
11
+ 'createWebAuthnCredential',
12
+ 'assertWebAuthnCredential',
13
+ 'encryptString',
14
+ 'decryptString',
15
+ 'injectScript',
16
+ 'FallbackError',
17
+ 'PopupBlockedError',
18
+ 'PopupClosedError',
19
+ 'UnsupportedFlowError',
20
+ 'SessionExpiredError',
21
+ 'NetworkError',
22
+ 'ServerError',
23
+ 'OidcError',
24
+ 'ProtocolError',
25
+ 'ConfigurationError',
26
+ 'InternalError',
27
+ 'throwTokenEndpointError',
28
+ 'throwHttpError',
29
+ 'createHttpClient',
30
+ 'createDefaultLogging',
31
+ 'getDefaultFlowState',
32
+ 'defaultOptions',
33
+ 'getDiscoveryDocument',
34
+ 'getSDKOptions',
35
+ 'generateCodeVerifier',
36
+ 'generateCodeChallenge',
37
+ 'generateRandomHex',
38
+ 'decodeJwt',
39
+ 'verifyJwt',
40
+ 'generateJwt',
41
+ 'verifyIdToken',
42
+ 'buildAuthorizationUrl',
43
+ 'buildEndSessionUrl',
44
+ 'exchangeCode',
45
+ 'refreshToken',
46
+ 'revokeToken',
47
+ 'fetchFlowEntry',
48
+ 'finalizeLoginSession',
49
+ 'submitLoginForm',
50
+ 'DISALLOWED_PROXY_HEADERS',
51
+ 'RETURN_TO_COOKIE',
52
+ 'BACKCHANNEL_LOGOUT_EVENT',
53
+ 'DEFAULT_COOKIE_MAX_AGE',
54
+ 'getServerSDKOptions',
55
+ 'parseCookieHeader',
56
+ 'serializeCookie',
57
+ 'pushSetCookie',
58
+ 'flushSetCookies',
59
+ 'proxyResponse',
60
+ 'toSafeRedirect',
61
+ 'createSession',
62
+ 'loadSession',
63
+ 'serializeSession',
64
+ 'isSessionExpired',
65
+ 'createState',
66
+ 'parseState',
67
+ 'serializeState',
68
+ ];
69
+
70
+ expect(Object.keys(index)).toEqual(expectedExports);
71
+ });
@@ -0,0 +1,82 @@
1
+ import { describe, test, expect, vi } from 'vitest';
2
+ import { createDefaultLogging } from '../../../src/utils/logging';
3
+
4
+ describe('createDefaultLogging', () => {
5
+ test('logs debug messages via console.log without an xEventId prefix', () => {
6
+ const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
7
+ const logging = createDefaultLogging();
8
+
9
+ logging.debug('hello');
10
+
11
+ expect(logSpy).toHaveBeenCalledWith('hello');
12
+ });
13
+
14
+ test('prefixes debug messages with the xEventId when set', () => {
15
+ const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
16
+ const logging = createDefaultLogging();
17
+ logging.xEventId = 'event-1';
18
+
19
+ logging.debug('hello');
20
+
21
+ expect(logSpy).toHaveBeenCalledWith('(event-1) hello');
22
+ });
23
+
24
+ test('logs info messages via console.info', () => {
25
+ const infoSpy = vi.spyOn(console, 'info').mockImplementation(() => {});
26
+ const logging = createDefaultLogging();
27
+
28
+ logging.info('hello');
29
+
30
+ expect(infoSpy).toHaveBeenCalledWith('hello');
31
+ });
32
+
33
+ test('prefixes info messages with the xEventId when set', () => {
34
+ const infoSpy = vi.spyOn(console, 'info').mockImplementation(() => {});
35
+ const logging = createDefaultLogging();
36
+ logging.xEventId = 'event-1';
37
+
38
+ logging.info('hello');
39
+
40
+ expect(infoSpy).toHaveBeenCalledWith('(event-1) hello');
41
+ });
42
+
43
+ test('logs warn messages via console.warn', () => {
44
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
45
+ const logging = createDefaultLogging();
46
+
47
+ logging.warn('hello');
48
+
49
+ expect(warnSpy).toHaveBeenCalledWith('hello');
50
+ });
51
+
52
+ test('prefixes warn messages with the xEventId when set', () => {
53
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
54
+ const logging = createDefaultLogging();
55
+ logging.xEventId = 'event-1';
56
+
57
+ logging.warn('hello');
58
+
59
+ expect(warnSpy).toHaveBeenCalledWith('(event-1) hello');
60
+ });
61
+
62
+ test('logs error messages via console.error including the error', () => {
63
+ const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
64
+ const logging = createDefaultLogging();
65
+ const error = new Error('boom');
66
+
67
+ logging.error('hello', error);
68
+
69
+ expect(errorSpy).toHaveBeenCalledWith(`hello - ${error}`);
70
+ });
71
+
72
+ test('prefixes error messages with the xEventId when set', () => {
73
+ const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
74
+ const logging = createDefaultLogging();
75
+ logging.xEventId = 'event-1';
76
+ const error = new Error('boom');
77
+
78
+ logging.error('hello', error);
79
+
80
+ expect(errorSpy).toHaveBeenCalledWith(`(event-1) hello - ${error}`);
81
+ });
82
+ });