@workos-inc/widgets 1.0.1 → 1.1.1

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 (460) hide show
  1. package/README.md +65 -0
  2. package/dist/cjs/api/api-provider.d.ts +26 -0
  3. package/dist/cjs/api/api-provider.d.ts.map +1 -0
  4. package/dist/cjs/api/api-provider.js +123 -0
  5. package/dist/cjs/api/api-provider.js.map +1 -0
  6. package/dist/cjs/api/constants.d.ts +2 -0
  7. package/dist/cjs/api/constants.d.ts.map +1 -0
  8. package/dist/cjs/api/constants.js +5 -0
  9. package/dist/cjs/api/constants.js.map +1 -0
  10. package/dist/cjs/api/endpoint.d.ts +957 -0
  11. package/dist/cjs/api/endpoint.d.ts.map +1 -0
  12. package/dist/cjs/api/endpoint.js +856 -0
  13. package/dist/cjs/api/endpoint.js.map +1 -0
  14. package/dist/cjs/api/errors.d.ts +33 -0
  15. package/dist/cjs/api/errors.d.ts.map +1 -0
  16. package/dist/cjs/api/errors.js +40 -0
  17. package/dist/cjs/api/errors.js.map +1 -0
  18. package/dist/cjs/api/index.d.ts +3 -0
  19. package/dist/cjs/api/index.d.ts.map +1 -0
  20. package/dist/cjs/api/index.js +19 -0
  21. package/dist/cjs/api/index.js.map +1 -0
  22. package/dist/cjs/api/utils.d.ts +10 -0
  23. package/dist/cjs/api/utils.d.ts.map +1 -0
  24. package/dist/cjs/api/utils.js +42 -0
  25. package/dist/cjs/api/utils.js.map +1 -0
  26. package/dist/cjs/api/widgets-api-client.d.ts +21 -0
  27. package/dist/cjs/api/widgets-api-client.d.ts.map +1 -0
  28. package/dist/cjs/api/widgets-api-client.js +61 -0
  29. package/dist/cjs/api/widgets-api-client.js.map +1 -0
  30. package/dist/cjs/card-list.d.ts +6 -0
  31. package/dist/cjs/card-list.d.ts.map +1 -0
  32. package/dist/cjs/card-list.js +13 -0
  33. package/dist/cjs/card-list.js.map +1 -0
  34. package/dist/cjs/index.d.ts +3 -0
  35. package/dist/cjs/index.d.ts.map +1 -1
  36. package/dist/cjs/index.js +7 -1
  37. package/dist/cjs/index.js.map +1 -1
  38. package/dist/cjs/lib/add-mfa-dialog.d.ts +9 -0
  39. package/dist/cjs/lib/add-mfa-dialog.d.ts.map +1 -0
  40. package/dist/cjs/lib/add-mfa-dialog.js +135 -0
  41. package/dist/cjs/lib/add-mfa-dialog.js.map +1 -0
  42. package/dist/cjs/lib/api/user.d.ts +13 -57
  43. package/dist/cjs/lib/api/user.d.ts.map +1 -1
  44. package/dist/cjs/lib/api/user.js +44 -314
  45. package/dist/cjs/lib/api/user.js.map +1 -1
  46. package/dist/cjs/lib/change-password-dialog.d.ts +8 -0
  47. package/dist/cjs/lib/change-password-dialog.d.ts.map +1 -0
  48. package/dist/cjs/lib/change-password-dialog.js +97 -0
  49. package/dist/cjs/lib/change-password-dialog.js.map +1 -0
  50. package/dist/cjs/lib/copy-button.d.ts +8 -0
  51. package/dist/cjs/lib/copy-button.d.ts.map +1 -0
  52. package/dist/cjs/lib/copy-button.js +63 -0
  53. package/dist/cjs/lib/copy-button.js.map +1 -0
  54. package/dist/cjs/lib/delete-user-dialog.d.ts +2 -2
  55. package/dist/cjs/lib/delete-user-dialog.d.ts.map +1 -1
  56. package/dist/cjs/lib/delete-user-dialog.js +1 -1
  57. package/dist/cjs/lib/delete-user-dialog.js.map +1 -1
  58. package/dist/cjs/lib/edit-user-profile-dialog.d.ts +10 -0
  59. package/dist/cjs/lib/edit-user-profile-dialog.d.ts.map +1 -0
  60. package/dist/cjs/lib/edit-user-profile-dialog.js +85 -0
  61. package/dist/cjs/lib/edit-user-profile-dialog.js.map +1 -0
  62. package/dist/cjs/lib/edit-user-role-dialog.d.ts +12 -0
  63. package/dist/cjs/lib/edit-user-role-dialog.d.ts.map +1 -0
  64. package/dist/cjs/lib/{edit-user-details-dialog.js → edit-user-role-dialog.js} +11 -7
  65. package/dist/cjs/lib/edit-user-role-dialog.js.map +1 -0
  66. package/dist/cjs/lib/elements.d.ts +1 -0
  67. package/dist/cjs/lib/elements.d.ts.map +1 -1
  68. package/dist/cjs/lib/elements.js +10 -4
  69. package/dist/cjs/lib/elements.js.map +1 -1
  70. package/dist/cjs/lib/elevated-access.d.ts +8 -0
  71. package/dist/cjs/lib/elevated-access.d.ts.map +1 -0
  72. package/dist/cjs/lib/elevated-access.js +130 -0
  73. package/dist/cjs/lib/elevated-access.js.map +1 -0
  74. package/dist/cjs/lib/generic-error.d.ts +4 -0
  75. package/dist/cjs/lib/generic-error.d.ts.map +1 -0
  76. package/dist/cjs/lib/generic-error.js +57 -0
  77. package/dist/cjs/lib/generic-error.js.map +1 -0
  78. package/dist/cjs/lib/icon-panel.d.ts +3 -0
  79. package/dist/cjs/lib/icon-panel.d.ts.map +1 -0
  80. package/dist/cjs/lib/icon-panel.js +16 -0
  81. package/dist/cjs/lib/icon-panel.js.map +1 -0
  82. package/dist/cjs/lib/icons.d.ts +3 -0
  83. package/dist/cjs/lib/icons.d.ts.map +1 -0
  84. package/dist/cjs/lib/icons.js +8 -0
  85. package/dist/cjs/lib/icons.js.map +1 -0
  86. package/dist/cjs/lib/invite-user-dialog.d.ts.map +1 -1
  87. package/dist/cjs/lib/invite-user-dialog.js +7 -5
  88. package/dist/cjs/lib/invite-user-dialog.js.map +1 -1
  89. package/dist/cjs/lib/logout-all-sessions-dialog.d.ts +9 -0
  90. package/dist/cjs/lib/logout-all-sessions-dialog.d.ts.map +1 -0
  91. package/dist/cjs/lib/logout-all-sessions-dialog.js +52 -0
  92. package/dist/cjs/lib/logout-all-sessions-dialog.js.map +1 -0
  93. package/dist/cjs/lib/logout-dialog.d.ts +10 -0
  94. package/dist/cjs/lib/logout-dialog.d.ts.map +1 -0
  95. package/dist/cjs/lib/logout-dialog.js +58 -0
  96. package/dist/cjs/lib/logout-dialog.js.map +1 -0
  97. package/dist/cjs/lib/marker.d.ts +14 -0
  98. package/dist/cjs/lib/marker.d.ts.map +1 -0
  99. package/dist/cjs/lib/marker.js +38 -0
  100. package/dist/cjs/lib/marker.js.map +1 -0
  101. package/dist/cjs/lib/oauth-icons.d.ts +4 -0
  102. package/dist/cjs/lib/oauth-icons.d.ts.map +1 -0
  103. package/dist/cjs/lib/oauth-icons.js +67 -0
  104. package/dist/cjs/lib/oauth-icons.js.map +1 -0
  105. package/dist/cjs/lib/organization-switcher.d.ts +24 -0
  106. package/dist/cjs/lib/organization-switcher.d.ts.map +1 -0
  107. package/dist/cjs/lib/organization-switcher.js +35 -0
  108. package/dist/cjs/lib/organization-switcher.js.map +1 -0
  109. package/dist/cjs/lib/otp-input.d.ts +20 -0
  110. package/dist/cjs/lib/otp-input.d.ts.map +1 -0
  111. package/dist/cjs/lib/otp-input.js +174 -0
  112. package/dist/cjs/lib/otp-input.js.map +1 -0
  113. package/dist/cjs/lib/resend-invite-dialog.d.ts +2 -2
  114. package/dist/cjs/lib/resend-invite-dialog.d.ts.map +1 -1
  115. package/dist/cjs/lib/resend-invite-dialog.js +1 -1
  116. package/dist/cjs/lib/resend-invite-dialog.js.map +1 -1
  117. package/dist/cjs/lib/reset-mfa-dialog.d.ts +9 -0
  118. package/dist/cjs/lib/reset-mfa-dialog.d.ts.map +1 -0
  119. package/dist/cjs/lib/reset-mfa-dialog.js +60 -0
  120. package/dist/cjs/lib/reset-mfa-dialog.js.map +1 -0
  121. package/dist/cjs/lib/revoke-invite-dialog.d.ts +2 -2
  122. package/dist/cjs/lib/revoke-invite-dialog.d.ts.map +1 -1
  123. package/dist/cjs/lib/revoke-invite-dialog.js +1 -1
  124. package/dist/cjs/lib/revoke-invite-dialog.js.map +1 -1
  125. package/dist/cjs/lib/save-button.d.ts +11 -0
  126. package/dist/cjs/lib/save-button.d.ts.map +1 -0
  127. package/dist/cjs/lib/save-button.js +47 -0
  128. package/dist/cjs/lib/save-button.js.map +1 -0
  129. package/dist/cjs/lib/set-password-dialog.d.ts +8 -0
  130. package/dist/cjs/lib/set-password-dialog.d.ts.map +1 -0
  131. package/dist/cjs/lib/set-password-dialog.js +80 -0
  132. package/dist/cjs/lib/set-password-dialog.js.map +1 -0
  133. package/dist/cjs/lib/use-dialog-close.d.ts +2 -0
  134. package/dist/cjs/lib/use-dialog-close.d.ts.map +1 -0
  135. package/dist/cjs/lib/use-dialog-close.js +43 -0
  136. package/dist/cjs/lib/use-dialog-close.js.map +1 -0
  137. package/dist/cjs/lib/use-security-settings.d.ts +11 -0
  138. package/dist/cjs/lib/use-security-settings.d.ts.map +1 -0
  139. package/dist/cjs/lib/use-security-settings.js +39 -0
  140. package/dist/cjs/lib/use-security-settings.js.map +1 -0
  141. package/dist/cjs/lib/user-actions-dropdown.d.ts +2 -2
  142. package/dist/cjs/lib/user-actions-dropdown.d.ts.map +1 -1
  143. package/dist/cjs/lib/user-actions-dropdown.js +8 -4
  144. package/dist/cjs/lib/user-actions-dropdown.js.map +1 -1
  145. package/dist/cjs/lib/user-profile.d.ts +11 -0
  146. package/dist/cjs/lib/user-profile.d.ts.map +1 -0
  147. package/dist/cjs/lib/user-profile.js +36 -0
  148. package/dist/cjs/lib/user-profile.js.map +1 -0
  149. package/dist/cjs/lib/user-security.d.ts +11 -0
  150. package/dist/cjs/lib/user-security.d.ts.map +1 -0
  151. package/dist/cjs/lib/user-security.js +64 -0
  152. package/dist/cjs/lib/user-security.js.map +1 -0
  153. package/dist/cjs/lib/user-sessions.d.ts +12 -0
  154. package/dist/cjs/lib/user-sessions.d.ts.map +1 -0
  155. package/dist/cjs/lib/user-sessions.js +72 -0
  156. package/dist/cjs/lib/user-sessions.js.map +1 -0
  157. package/dist/cjs/lib/users-filter.d.ts +2 -2
  158. package/dist/cjs/lib/users-filter.d.ts.map +1 -1
  159. package/dist/cjs/lib/users-filter.js.map +1 -1
  160. package/dist/cjs/lib/users-management-context.d.ts +0 -9
  161. package/dist/cjs/lib/users-management-context.d.ts.map +1 -1
  162. package/dist/cjs/lib/users-management-context.js +13 -26
  163. package/dist/cjs/lib/users-management-context.js.map +1 -1
  164. package/dist/cjs/lib/users-management-state.d.ts +3 -3
  165. package/dist/cjs/lib/users-management-state.d.ts.map +1 -1
  166. package/dist/cjs/lib/users-management-state.js.map +1 -1
  167. package/dist/cjs/lib/users-management.d.ts +3 -4
  168. package/dist/cjs/lib/users-management.d.ts.map +1 -1
  169. package/dist/cjs/lib/users-management.js +8 -26
  170. package/dist/cjs/lib/users-management.js.map +1 -1
  171. package/dist/cjs/lib/utils.d.ts +10 -2
  172. package/dist/cjs/lib/utils.d.ts.map +1 -1
  173. package/dist/cjs/lib/utils.js +18 -0
  174. package/dist/cjs/lib/utils.js.map +1 -1
  175. package/dist/cjs/organization-switcher.client.d.ts +8 -0
  176. package/dist/cjs/organization-switcher.client.d.ts.map +1 -0
  177. package/dist/cjs/organization-switcher.client.js +37 -0
  178. package/dist/cjs/organization-switcher.client.js.map +1 -0
  179. package/dist/cjs/user-profile.client.d.ts +7 -0
  180. package/dist/cjs/user-profile.client.d.ts.map +1 -0
  181. package/dist/cjs/user-profile.client.js +31 -0
  182. package/dist/cjs/user-profile.client.js.map +1 -0
  183. package/dist/cjs/user-security.client.d.ts +7 -0
  184. package/dist/cjs/user-security.client.d.ts.map +1 -0
  185. package/dist/cjs/user-security.client.js +27 -0
  186. package/dist/cjs/user-security.client.js.map +1 -0
  187. package/dist/cjs/user-sessions.client.d.ts +12 -0
  188. package/dist/cjs/user-sessions.client.d.ts.map +1 -0
  189. package/dist/cjs/user-sessions.client.js +48 -0
  190. package/dist/cjs/user-sessions.client.js.map +1 -0
  191. package/dist/cjs/users-management.client.d.ts +2 -1
  192. package/dist/cjs/users-management.client.d.ts.map +1 -1
  193. package/dist/cjs/users-management.client.js +12 -43
  194. package/dist/cjs/users-management.client.js.map +1 -1
  195. package/dist/esm/api/api-provider.d.ts +26 -0
  196. package/dist/esm/api/api-provider.d.ts.map +1 -0
  197. package/dist/esm/api/api-provider.js +94 -0
  198. package/dist/esm/api/api-provider.js.map +1 -0
  199. package/dist/esm/api/constants.d.ts +2 -0
  200. package/dist/esm/api/constants.d.ts.map +1 -0
  201. package/dist/esm/api/constants.js +2 -0
  202. package/dist/esm/api/constants.js.map +1 -0
  203. package/dist/esm/api/endpoint.d.ts +957 -0
  204. package/dist/esm/api/endpoint.d.ts.map +1 -0
  205. package/dist/esm/api/endpoint.js +774 -0
  206. package/dist/esm/api/endpoint.js.map +1 -0
  207. package/dist/esm/api/errors.d.ts +33 -0
  208. package/dist/esm/api/errors.d.ts.map +1 -0
  209. package/dist/esm/api/errors.js +34 -0
  210. package/dist/esm/api/errors.js.map +1 -0
  211. package/dist/esm/api/index.d.ts +3 -0
  212. package/dist/esm/api/index.d.ts.map +1 -0
  213. package/dist/esm/api/index.js +3 -0
  214. package/dist/esm/api/index.js.map +1 -0
  215. package/dist/esm/api/utils.d.ts +10 -0
  216. package/dist/esm/api/utils.d.ts.map +1 -0
  217. package/dist/esm/api/utils.js +36 -0
  218. package/dist/esm/api/utils.js.map +1 -0
  219. package/dist/esm/api/widgets-api-client.d.ts +21 -0
  220. package/dist/esm/api/widgets-api-client.d.ts.map +1 -0
  221. package/dist/esm/api/widgets-api-client.js +56 -0
  222. package/dist/esm/api/widgets-api-client.js.map +1 -0
  223. package/dist/esm/card-list.d.ts +6 -0
  224. package/dist/esm/card-list.d.ts.map +1 -0
  225. package/dist/esm/card-list.js +9 -0
  226. package/dist/esm/card-list.js.map +1 -0
  227. package/dist/esm/index.d.ts +3 -0
  228. package/dist/esm/index.d.ts.map +1 -1
  229. package/dist/esm/index.js +3 -0
  230. package/dist/esm/index.js.map +1 -1
  231. package/dist/esm/lib/add-mfa-dialog.d.ts +9 -0
  232. package/dist/esm/lib/add-mfa-dialog.d.ts.map +1 -0
  233. package/dist/esm/lib/add-mfa-dialog.js +109 -0
  234. package/dist/esm/lib/add-mfa-dialog.js.map +1 -0
  235. package/dist/esm/lib/api/user.d.ts +13 -57
  236. package/dist/esm/lib/api/user.d.ts.map +1 -1
  237. package/dist/esm/lib/api/user.js +44 -313
  238. package/dist/esm/lib/api/user.js.map +1 -1
  239. package/dist/esm/lib/change-password-dialog.d.ts +8 -0
  240. package/dist/esm/lib/change-password-dialog.d.ts.map +1 -0
  241. package/dist/esm/lib/change-password-dialog.js +71 -0
  242. package/dist/esm/lib/change-password-dialog.js.map +1 -0
  243. package/dist/esm/lib/copy-button.d.ts +8 -0
  244. package/dist/esm/lib/copy-button.d.ts.map +1 -0
  245. package/dist/esm/lib/copy-button.js +37 -0
  246. package/dist/esm/lib/copy-button.js.map +1 -0
  247. package/dist/esm/lib/delete-user-dialog.d.ts +2 -2
  248. package/dist/esm/lib/delete-user-dialog.d.ts.map +1 -1
  249. package/dist/esm/lib/delete-user-dialog.js +1 -1
  250. package/dist/esm/lib/delete-user-dialog.js.map +1 -1
  251. package/dist/esm/lib/edit-user-profile-dialog.d.ts +10 -0
  252. package/dist/esm/lib/edit-user-profile-dialog.d.ts.map +1 -0
  253. package/dist/esm/lib/edit-user-profile-dialog.js +59 -0
  254. package/dist/esm/lib/edit-user-profile-dialog.js.map +1 -0
  255. package/dist/esm/lib/edit-user-role-dialog.d.ts +12 -0
  256. package/dist/esm/lib/edit-user-role-dialog.d.ts.map +1 -0
  257. package/dist/esm/lib/{edit-user-details-dialog.js → edit-user-role-dialog.js} +10 -6
  258. package/dist/esm/lib/edit-user-role-dialog.js.map +1 -0
  259. package/dist/esm/lib/elements.d.ts +1 -0
  260. package/dist/esm/lib/elements.d.ts.map +1 -1
  261. package/dist/esm/lib/elements.js +9 -3
  262. package/dist/esm/lib/elements.js.map +1 -1
  263. package/dist/esm/lib/elevated-access.d.ts +8 -0
  264. package/dist/esm/lib/elevated-access.d.ts.map +1 -0
  265. package/dist/esm/lib/elevated-access.js +104 -0
  266. package/dist/esm/lib/elevated-access.js.map +1 -0
  267. package/dist/esm/lib/generic-error.d.ts +4 -0
  268. package/dist/esm/lib/generic-error.d.ts.map +1 -0
  269. package/dist/esm/lib/generic-error.js +31 -0
  270. package/dist/esm/lib/generic-error.js.map +1 -0
  271. package/dist/esm/lib/icon-panel.d.ts +3 -0
  272. package/dist/esm/lib/icon-panel.d.ts.map +1 -0
  273. package/dist/esm/lib/icon-panel.js +13 -0
  274. package/dist/esm/lib/icon-panel.js.map +1 -0
  275. package/dist/esm/lib/icons.d.ts +3 -0
  276. package/dist/esm/lib/icons.d.ts.map +1 -0
  277. package/dist/esm/lib/icons.js +5 -0
  278. package/dist/esm/lib/icons.js.map +1 -0
  279. package/dist/esm/lib/invite-user-dialog.d.ts.map +1 -1
  280. package/dist/esm/lib/invite-user-dialog.js +7 -5
  281. package/dist/esm/lib/invite-user-dialog.js.map +1 -1
  282. package/dist/esm/lib/logout-all-sessions-dialog.d.ts +9 -0
  283. package/dist/esm/lib/logout-all-sessions-dialog.d.ts.map +1 -0
  284. package/dist/esm/lib/logout-all-sessions-dialog.js +26 -0
  285. package/dist/esm/lib/logout-all-sessions-dialog.js.map +1 -0
  286. package/dist/esm/lib/logout-dialog.d.ts +10 -0
  287. package/dist/esm/lib/logout-dialog.d.ts.map +1 -0
  288. package/dist/esm/lib/logout-dialog.js +32 -0
  289. package/dist/esm/lib/logout-dialog.js.map +1 -0
  290. package/dist/esm/lib/marker.d.ts +14 -0
  291. package/dist/esm/lib/marker.d.ts.map +1 -0
  292. package/dist/esm/lib/marker.js +9 -0
  293. package/dist/esm/lib/marker.js.map +1 -0
  294. package/dist/esm/lib/oauth-icons.d.ts +4 -0
  295. package/dist/esm/lib/oauth-icons.d.ts.map +1 -0
  296. package/dist/esm/lib/oauth-icons.js +39 -0
  297. package/dist/esm/lib/oauth-icons.js.map +1 -0
  298. package/dist/esm/lib/organization-switcher.d.ts +24 -0
  299. package/dist/esm/lib/organization-switcher.d.ts.map +1 -0
  300. package/dist/esm/lib/organization-switcher.js +29 -0
  301. package/dist/esm/lib/organization-switcher.js.map +1 -0
  302. package/dist/esm/lib/otp-input.d.ts +20 -0
  303. package/dist/esm/lib/otp-input.d.ts.map +1 -0
  304. package/dist/esm/lib/otp-input.js +148 -0
  305. package/dist/esm/lib/otp-input.js.map +1 -0
  306. package/dist/esm/lib/resend-invite-dialog.d.ts +2 -2
  307. package/dist/esm/lib/resend-invite-dialog.d.ts.map +1 -1
  308. package/dist/esm/lib/resend-invite-dialog.js +1 -1
  309. package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
  310. package/dist/esm/lib/reset-mfa-dialog.d.ts +9 -0
  311. package/dist/esm/lib/reset-mfa-dialog.d.ts.map +1 -0
  312. package/dist/esm/lib/reset-mfa-dialog.js +34 -0
  313. package/dist/esm/lib/reset-mfa-dialog.js.map +1 -0
  314. package/dist/esm/lib/revoke-invite-dialog.d.ts +2 -2
  315. package/dist/esm/lib/revoke-invite-dialog.d.ts.map +1 -1
  316. package/dist/esm/lib/revoke-invite-dialog.js +1 -1
  317. package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
  318. package/dist/esm/lib/save-button.d.ts +11 -0
  319. package/dist/esm/lib/save-button.d.ts.map +1 -0
  320. package/dist/esm/lib/save-button.js +44 -0
  321. package/dist/esm/lib/save-button.js.map +1 -0
  322. package/dist/esm/lib/set-password-dialog.d.ts +8 -0
  323. package/dist/esm/lib/set-password-dialog.d.ts.map +1 -0
  324. package/dist/esm/lib/set-password-dialog.js +54 -0
  325. package/dist/esm/lib/set-password-dialog.js.map +1 -0
  326. package/dist/esm/lib/use-dialog-close.d.ts +2 -0
  327. package/dist/esm/lib/use-dialog-close.d.ts.map +1 -0
  328. package/dist/esm/lib/use-dialog-close.js +17 -0
  329. package/dist/esm/lib/use-dialog-close.js.map +1 -0
  330. package/dist/esm/lib/use-security-settings.d.ts +11 -0
  331. package/dist/esm/lib/use-security-settings.d.ts.map +1 -0
  332. package/dist/esm/lib/use-security-settings.js +36 -0
  333. package/dist/esm/lib/use-security-settings.js.map +1 -0
  334. package/dist/esm/lib/user-actions-dropdown.d.ts +2 -2
  335. package/dist/esm/lib/user-actions-dropdown.d.ts.map +1 -1
  336. package/dist/esm/lib/user-actions-dropdown.js +8 -4
  337. package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
  338. package/dist/esm/lib/user-profile.d.ts +11 -0
  339. package/dist/esm/lib/user-profile.d.ts.map +1 -0
  340. package/dist/esm/lib/user-profile.js +27 -0
  341. package/dist/esm/lib/user-profile.js.map +1 -0
  342. package/dist/esm/lib/user-security.d.ts +11 -0
  343. package/dist/esm/lib/user-security.d.ts.map +1 -0
  344. package/dist/esm/lib/user-security.js +32 -0
  345. package/dist/esm/lib/user-security.js.map +1 -0
  346. package/dist/esm/lib/user-sessions.d.ts +12 -0
  347. package/dist/esm/lib/user-sessions.d.ts.map +1 -0
  348. package/dist/esm/lib/user-sessions.js +40 -0
  349. package/dist/esm/lib/user-sessions.js.map +1 -0
  350. package/dist/esm/lib/users-filter.d.ts +2 -2
  351. package/dist/esm/lib/users-filter.d.ts.map +1 -1
  352. package/dist/esm/lib/users-filter.js.map +1 -1
  353. package/dist/esm/lib/users-management-context.d.ts +0 -9
  354. package/dist/esm/lib/users-management-context.d.ts.map +1 -1
  355. package/dist/esm/lib/users-management-context.js +13 -25
  356. package/dist/esm/lib/users-management-context.js.map +1 -1
  357. package/dist/esm/lib/users-management-state.d.ts +3 -3
  358. package/dist/esm/lib/users-management-state.d.ts.map +1 -1
  359. package/dist/esm/lib/users-management-state.js.map +1 -1
  360. package/dist/esm/lib/users-management.d.ts +3 -4
  361. package/dist/esm/lib/users-management.d.ts.map +1 -1
  362. package/dist/esm/lib/users-management.js +9 -27
  363. package/dist/esm/lib/users-management.js.map +1 -1
  364. package/dist/esm/lib/users-search.d.ts +1 -1
  365. package/dist/esm/lib/users-search.d.ts.map +1 -1
  366. package/dist/esm/lib/utils.d.ts +10 -2
  367. package/dist/esm/lib/utils.d.ts.map +1 -1
  368. package/dist/esm/lib/utils.js +16 -0
  369. package/dist/esm/lib/utils.js.map +1 -1
  370. package/dist/esm/organization-switcher.client.d.ts +8 -0
  371. package/dist/esm/organization-switcher.client.d.ts.map +1 -0
  372. package/dist/esm/organization-switcher.client.js +33 -0
  373. package/dist/esm/organization-switcher.client.js.map +1 -0
  374. package/dist/esm/user-profile.client.d.ts +7 -0
  375. package/dist/esm/user-profile.client.d.ts.map +1 -0
  376. package/dist/esm/user-profile.client.js +27 -0
  377. package/dist/esm/user-profile.client.js.map +1 -0
  378. package/dist/esm/user-security.client.d.ts +7 -0
  379. package/dist/esm/user-security.client.d.ts.map +1 -0
  380. package/dist/esm/user-security.client.js +23 -0
  381. package/dist/esm/user-security.client.js.map +1 -0
  382. package/dist/esm/user-sessions.client.d.ts +12 -0
  383. package/dist/esm/user-sessions.client.d.ts.map +1 -0
  384. package/dist/esm/user-sessions.client.js +44 -0
  385. package/dist/esm/user-sessions.client.js.map +1 -0
  386. package/dist/esm/users-management.client.d.ts +2 -1
  387. package/dist/esm/users-management.client.d.ts.map +1 -1
  388. package/dist/esm/users-management.client.js +12 -20
  389. package/dist/esm/users-management.client.js.map +1 -1
  390. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  391. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  392. package/package.json +18 -4
  393. package/src/api/api-provider.tsx +141 -0
  394. package/src/api/constants.ts +1 -0
  395. package/src/api/endpoint.ts +3057 -0
  396. package/src/api/errors.ts +48 -0
  397. package/src/api/index.ts +2 -0
  398. package/src/api/utils.ts +42 -0
  399. package/src/api/widgets-api-client.ts +86 -0
  400. package/src/card-list.tsx +26 -0
  401. package/src/index.ts +3 -0
  402. package/src/lib/add-mfa-dialog.tsx +379 -0
  403. package/src/lib/api/user.ts +54 -458
  404. package/src/lib/card-list.css +3 -0
  405. package/src/lib/change-password-dialog.tsx +290 -0
  406. package/src/lib/copy-button.tsx +53 -0
  407. package/src/lib/delete-user-dialog.tsx +9 -6
  408. package/src/lib/edit-user-profile-dialog.tsx +181 -0
  409. package/src/lib/{edit-user-details-dialog.tsx → edit-user-role-dialog.tsx} +12 -9
  410. package/src/lib/elements.tsx +34 -1
  411. package/src/lib/elevated-access.tsx +261 -0
  412. package/src/lib/generic-error.tsx +70 -0
  413. package/src/lib/icon-panel.tsx +26 -0
  414. package/src/lib/icons.tsx +21 -0
  415. package/src/lib/invite-user-dialog.tsx +15 -10
  416. package/src/lib/logout-all-sessions-dialog.tsx +82 -0
  417. package/src/lib/logout-dialog.tsx +85 -0
  418. package/src/lib/marker.css +81 -0
  419. package/src/lib/marker.tsx +39 -0
  420. package/src/lib/oauth-icons.tsx +138 -0
  421. package/src/lib/organization-switcher.tsx +156 -0
  422. package/src/lib/otp-input.tsx +276 -0
  423. package/src/lib/resend-invite-dialog.tsx +9 -6
  424. package/src/lib/reset-mfa-dialog.tsx +104 -0
  425. package/src/lib/revoke-invite-dialog.tsx +9 -6
  426. package/src/lib/save-button.css +60 -0
  427. package/src/lib/save-button.tsx +113 -0
  428. package/src/lib/set-password-dialog.tsx +204 -0
  429. package/src/lib/use-dialog-close.tsx +19 -0
  430. package/src/lib/use-security-settings.tsx +49 -0
  431. package/src/lib/user-actions-dropdown.tsx +10 -6
  432. package/src/lib/user-profile.tsx +247 -0
  433. package/src/lib/user-security.tsx +187 -0
  434. package/src/lib/user-sessions.tsx +204 -0
  435. package/src/lib/users-filter.tsx +2 -2
  436. package/src/lib/users-management-context.tsx +21 -36
  437. package/src/lib/users-management-state.ts +3 -3
  438. package/src/lib/users-management.tsx +21 -77
  439. package/src/lib/utils.ts +30 -2
  440. package/src/organization-switcher.client.tsx +77 -0
  441. package/src/styles.css +44 -0
  442. package/src/user-profile.client.tsx +51 -0
  443. package/src/user-security.client.tsx +51 -0
  444. package/src/user-sessions.client.tsx +96 -0
  445. package/src/users-management.client.tsx +28 -39
  446. package/dist/cjs/lib/api/role.d.ts +0 -9
  447. package/dist/cjs/lib/api/role.d.ts.map +0 -1
  448. package/dist/cjs/lib/api/role.js +0 -115
  449. package/dist/cjs/lib/api/role.js.map +0 -1
  450. package/dist/cjs/lib/edit-user-details-dialog.d.ts +0 -12
  451. package/dist/cjs/lib/edit-user-details-dialog.d.ts.map +0 -1
  452. package/dist/cjs/lib/edit-user-details-dialog.js.map +0 -1
  453. package/dist/esm/lib/api/role.d.ts +0 -9
  454. package/dist/esm/lib/api/role.d.ts.map +0 -1
  455. package/dist/esm/lib/api/role.js +0 -110
  456. package/dist/esm/lib/api/role.js.map +0 -1
  457. package/dist/esm/lib/edit-user-details-dialog.d.ts +0 -12
  458. package/dist/esm/lib/edit-user-details-dialog.d.ts.map +0 -1
  459. package/dist/esm/lib/edit-user-details-dialog.js.map +0 -1
  460. package/src/lib/api/role.ts +0 -147
@@ -0,0 +1,48 @@
1
+ type QueryType = "query" | "mutation";
2
+
3
+ export class FetchError extends Error {
4
+ queryType: QueryType;
5
+ recordType?: string;
6
+ context: unknown;
7
+ constructor(args: {
8
+ message: string;
9
+ queryType: QueryType;
10
+ recordType?: string;
11
+ context?: unknown;
12
+ }) {
13
+ super(args.message);
14
+ this.name = "FetchError";
15
+ this.queryType = args.queryType;
16
+ this.recordType = args.recordType;
17
+ this.context = args.context;
18
+ }
19
+ }
20
+
21
+ export class ApiError extends Error {
22
+ status: number;
23
+ queryType: QueryType;
24
+ recordType?: string;
25
+ context: unknown;
26
+ constructor(args: {
27
+ message: string;
28
+ queryType: QueryType;
29
+ recordType?: string;
30
+ status: number;
31
+ context?: unknown;
32
+ }) {
33
+ super(args.message);
34
+ this.name = "ApiError";
35
+ this.status = args.status;
36
+ this.queryType = args.queryType;
37
+ this.recordType = args.recordType;
38
+ }
39
+ }
40
+
41
+ export class NoAuthTokenError extends Error {
42
+ context: unknown;
43
+ constructor(args?: { context?: unknown }) {
44
+ super("No auth token provided");
45
+ this.name = "NoAuthTokenError";
46
+ this.context = args?.context;
47
+ }
48
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./endpoint";
2
+ export * from "./api-provider";
@@ -0,0 +1,42 @@
1
+ import { WIDGETS_API_VERSION } from "./constants";
2
+
3
+ export function getAuthHeaders(authToken: string): HeadersInit {
4
+ return {
5
+ Authorization: `Bearer ${authToken}`,
6
+ "WorkOS-Widgets-Version": WIDGETS_API_VERSION,
7
+ };
8
+ }
9
+
10
+ export function isObjectLike(value: unknown): value is Record<string, unknown> {
11
+ return typeof value === "object" && value !== null;
12
+ }
13
+
14
+ export function isErrorLike(
15
+ value: unknown,
16
+ ): value is Record<string, unknown> & { message: string } {
17
+ return isObjectLike(value) && typeof value.message === "string";
18
+ }
19
+
20
+ export async function parseErrorResponse(
21
+ response: Response,
22
+ ): Promise<{ message: string; status: number }> {
23
+ try {
24
+ const json = await response.json();
25
+ if (!isObjectLike(json) || typeof json.message !== "string") {
26
+ return {
27
+ status: response.status,
28
+ message: response.statusText,
29
+ };
30
+ }
31
+ return {
32
+ ...json,
33
+ status: response.status,
34
+ message: json.message || response.statusText,
35
+ };
36
+ } catch {
37
+ return {
38
+ status: response.status,
39
+ message: response.statusText,
40
+ };
41
+ }
42
+ }
@@ -0,0 +1,86 @@
1
+ import { QueryKey } from "@tanstack/react-query";
2
+ import { useApi } from "./api-provider";
3
+ import { ApiError, FetchError } from "./errors";
4
+ import { getAuthHeaders, parseErrorResponse } from "./utils";
5
+
6
+ type WidgetsApiClient<T> = (data: {
7
+ url: string;
8
+ method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
9
+ params?: Record<string, any>;
10
+ headers?: Record<string, any>;
11
+ data?: BodyType<unknown>;
12
+ signal?: AbortSignal;
13
+ }) => Promise<T>;
14
+
15
+ export const useWidgetsApiClient = <T>(): WidgetsApiClient<T> => {
16
+ const { authToken, baseUrl, elevatedAccess } = useApi();
17
+
18
+ return async ({ url: pathname, method, params, data }) => {
19
+ const url = new URL(baseUrl);
20
+ url.pathname = pathname;
21
+
22
+ if (params) {
23
+ const cleanParams = Object.fromEntries(
24
+ Object.entries(params).filter(([_, value]) => value !== undefined),
25
+ );
26
+ url.search = new URLSearchParams(cleanParams).toString();
27
+ }
28
+
29
+ const queryType = method.toLowerCase() === "get" ? "query" : "mutation";
30
+ const headers = {
31
+ ...getAuthHeaders(await Promise.resolve(authToken)),
32
+ ...(elevatedAccess && queryType === "mutation"
33
+ ? { "x-elevated-access-token": elevatedAccess.token }
34
+ : {}),
35
+ "Content-Type": "application/json",
36
+ };
37
+
38
+ const response = await fetch(url, {
39
+ method,
40
+ cache: "no-store",
41
+ headers,
42
+ ...(data ? { body: JSON.stringify(data) } : {}),
43
+ }).catch((error) => {
44
+ throw new FetchError({
45
+ message: `Failed to ${method} ${url.toString()}`,
46
+ queryType,
47
+ context: { error },
48
+ });
49
+ });
50
+
51
+ if (!response.ok) {
52
+ const { message, status } = await parseErrorResponse(response);
53
+
54
+ throw new ApiError({
55
+ message,
56
+ status,
57
+ queryType: method.toLowerCase() === "get" ? "query" : "mutation",
58
+ });
59
+ }
60
+
61
+ return response.json();
62
+ };
63
+ };
64
+
65
+ export type ErrorType<ErrorData> = ErrorData;
66
+
67
+ export type BodyType<BodyData> = BodyData & { headers?: any };
68
+
69
+ export const useWidgetsApiQueryOptions = <
70
+ QueryOptions extends { queryKey: QK },
71
+ QK extends QueryKey,
72
+ >(
73
+ queryOptions: QueryOptions,
74
+ ) => {
75
+ const { authTokenQueryKey, baseUrl } = useApi();
76
+ const queryKey = [
77
+ // initial query key needs to go first to allow invalidation of the query name to work
78
+ ...queryOptions.queryKey,
79
+ { authTokenQueryKey, baseUrl },
80
+ ] as unknown as QK;
81
+
82
+ return {
83
+ ...queryOptions,
84
+ queryKey: queryKey as QK,
85
+ };
86
+ };
@@ -0,0 +1,26 @@
1
+ import { Box, Card, CardProps, Inset } from "@radix-ui/themes";
2
+
3
+ export function Root({ children, ...props }: CardProps) {
4
+ return (
5
+ <Card size="2" {...props} className="woswidgets-card-list">
6
+ <Inset side="all" clip="padding-box">
7
+ {children}
8
+ </Inset>
9
+ </Card>
10
+ );
11
+ }
12
+
13
+ export function Item({ children }: { children: React.ReactNode }) {
14
+ return (
15
+ <Inset
16
+ side="x"
17
+ px="current"
18
+ className="woswidgets-card-list-item"
19
+ clip="padding-box"
20
+ >
21
+ <Box px="4" py="4">
22
+ {children}
23
+ </Box>
24
+ </Inset>
25
+ );
26
+ }
package/src/index.ts CHANGED
@@ -2,4 +2,7 @@ export {
2
2
  WorkOsWidgets,
3
3
  type WorkOsWidgetsProps,
4
4
  } from "./workos-widgets.client";
5
+ export { UserProfile } from "./user-profile.client";
6
+ export { UserSecurity } from "./user-security.client";
7
+ export { UserSessions } from "./user-sessions.client";
5
8
  export { UsersManagement } from "./users-management.client";
@@ -0,0 +1,379 @@
1
+ "use client";
2
+
3
+ import {
4
+ Box,
5
+ Code,
6
+ Dialog,
7
+ Flex,
8
+ Grid,
9
+ Link,
10
+ Separator,
11
+ Text,
12
+ VisuallyHidden,
13
+ } from "@radix-ui/themes";
14
+ import * as React from "react";
15
+ import { type ReactNode } from "react";
16
+ import * as Otp from "./otp-input";
17
+ import { DialogContent, PrimaryButton, SecondaryButton } from "./elements";
18
+ import {
19
+ CreateTotpFactorResponse,
20
+ CreateTotpFactorResponseAuthenticationFactorAllOfTotpAnyOf,
21
+ useCreateTotpFactor,
22
+ useElevatedAccessToken,
23
+ useVerifyTotpFactor,
24
+ } from "../api";
25
+ import * as Form from "@radix-ui/react-form";
26
+ import { Marker } from "./marker";
27
+ import { CopyButton } from "./copy-button";
28
+ import { useSecuritySettings } from "./use-security-settings";
29
+ import { ElevatedAccess } from "./elevated-access";
30
+ import { SaveButton } from "./save-button";
31
+ import { useDialogClose } from "./use-dialog-close";
32
+
33
+ interface AddMfaDialogProps extends Dialog.RootProps {
34
+ children?: ReactNode;
35
+ onSuccess?: () => void;
36
+ }
37
+
38
+ export function AddMfaDialog({
39
+ children,
40
+ onSuccess,
41
+ ...props
42
+ }: AddMfaDialogProps) {
43
+ const [open, setOpen] = React.useState(false);
44
+ const [manuallyTriggered, setManuallyTriggered] = React.useState(false);
45
+ const { elevatedAccess } = useElevatedAccessToken();
46
+ const createAuthFactor = useCreateTotpFactor();
47
+
48
+ const handleVerified = async () => {
49
+ await createAuthFactor.mutateAsync(undefined);
50
+ };
51
+
52
+ const onTriggerClick = (event: React.MouseEvent<HTMLButtonElement>) => {
53
+ if (elevatedAccess && !createAuthFactor.data) {
54
+ event.preventDefault();
55
+ setManuallyTriggered(true);
56
+ createAuthFactor.mutate(undefined, {
57
+ onSuccess: () => {
58
+ setOpen(true);
59
+ },
60
+ });
61
+ } else {
62
+ setManuallyTriggered(false);
63
+ }
64
+ };
65
+
66
+ const handleClose = React.useCallback(() => {
67
+ setOpen(false);
68
+ }, []);
69
+
70
+ return (
71
+ <Dialog.Root
72
+ {...props}
73
+ open={props.open || open}
74
+ onOpenChange={props.onOpenChange || setOpen}
75
+ >
76
+ <Dialog.Trigger
77
+ onClick={onTriggerClick}
78
+ // @ts-ignore I've to find a way to pass the loading state to the trigger
79
+ loading={manuallyTriggered && createAuthFactor.isPending}
80
+ >
81
+ {children}
82
+ </Dialog.Trigger>
83
+
84
+ <DialogContent maxWidth="480px">
85
+ <ElevatedAccess onVerified={handleVerified}>
86
+ <Content onClose={handleClose} totpFactor={createAuthFactor.data} />
87
+ </ElevatedAccess>
88
+ </DialogContent>
89
+ </Dialog.Root>
90
+ );
91
+ }
92
+
93
+ interface ContentProps {
94
+ totpFactor?: CreateTotpFactorResponse;
95
+ onClose?: () => void;
96
+ }
97
+
98
+ function Content({ onClose, totpFactor }: ContentProps) {
99
+ const securitySettings = useSecuritySettings();
100
+
101
+ const [customError, setCustomError] = React.useState<string | null>(null);
102
+ const totp = hasQrCode(totpFactor)
103
+ ? totpFactor.authenticationFactor.totp
104
+ : undefined;
105
+
106
+ const verifyTotp = useVerifyTotpFactor({
107
+ mutation: {
108
+ onSuccess: ({ success }) => {
109
+ if (!success) {
110
+ setCustomError("Invalid passcode");
111
+ }
112
+ },
113
+ },
114
+ });
115
+
116
+ const serverError = verifyTotp.error || customError;
117
+ const isSuccess = verifyTotp.isSuccess && !serverError;
118
+
119
+ const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
120
+ event.preventDefault();
121
+ setCustomError(null);
122
+
123
+ const formData = new FormData(event.currentTarget);
124
+ const otpCode = formData.get("otp-code")?.toString();
125
+
126
+ verifyTotp.mutate({
127
+ data: {
128
+ authenticationChallengeId: totpFactor?.authenticationChallenge.id ?? "",
129
+ code: otpCode ?? "",
130
+ },
131
+ });
132
+ };
133
+
134
+ useDialogClose(isSuccess, () => {
135
+ securitySettings.update("Mfa", true);
136
+ });
137
+
138
+ return (
139
+ <>
140
+ <Dialog.Title mb="5">Set up an authenticator app</Dialog.Title>
141
+
142
+ <Form.Root onSubmit={handleSubmit}>
143
+ <Grid columns="auto 1fr" rows="repeat(4, auto)" gapX="3" gapY="1">
144
+ <Grid
145
+ rows="subgrid"
146
+ gridRow="span 4"
147
+ style={{ placeItems: "center" }}
148
+ >
149
+ <Marker>1</Marker>
150
+ <Separator
151
+ orientation="vertical"
152
+ size="4"
153
+ style={{ width: "2px" }}
154
+ />
155
+ <Marker>2</Marker>
156
+ <div />
157
+ </Grid>
158
+
159
+ <Grid rows="subgrid" gridRow="span 4">
160
+ <Text as="p" size="3" weight="bold">
161
+ Scan the QR code
162
+ </Text>
163
+ <Flex direction="column" gap="1">
164
+ <Text as="p" size="2">
165
+ Use an authenticator app like{" "}
166
+ <Link
167
+ href="https://1password.com/"
168
+ rel="noopener noreferrer"
169
+ target="_blank"
170
+ >
171
+ 1Password
172
+ </Link>
173
+ ,{" "}
174
+ <Link
175
+ href="https://apps.apple.com/us/app/google-authenticator/id388497605"
176
+ rel="noopener noreferrer"
177
+ target="_blank"
178
+ >
179
+ Google Authenticator
180
+ </Link>
181
+ ,{" "}
182
+ <Link
183
+ href="https://authy.com/"
184
+ rel="noopener noreferrer"
185
+ target="_blank"
186
+ >
187
+ Authy
188
+ </Link>
189
+ , or{" "}
190
+ <Link
191
+ href="https://www.microsoft.com/en-gb/security/mobile-authenticator-app"
192
+ rel="noopener noreferrer"
193
+ target="_blank"
194
+ >
195
+ Microsoft Authenticator
196
+ </Link>{" "}
197
+ to scan the QR code below.
198
+ </Text>
199
+ <Flex align="center" gap="5" my="5">
200
+ <Grid
201
+ position="relative"
202
+ width="160px"
203
+ height="160px"
204
+ p="2"
205
+ style={{
206
+ border: "1px solid var(--gray-7)",
207
+ borderRadius: "var(--radius-4)",
208
+ background: "var(--gray-2)",
209
+ overflow: "hidden",
210
+ }}
211
+ >
212
+ {totp?.qr_code && (
213
+ <Box asChild width="100%" height="auto">
214
+ <img
215
+ alt="Scan this QR code to enroll"
216
+ aria-describedby="secret-note"
217
+ height="160"
218
+ src={totp.qr_code}
219
+ style={{ userSelect: "none", background: "white" }}
220
+ width="160"
221
+ />
222
+ </Box>
223
+ )}
224
+ </Grid>
225
+
226
+ <Flex direction="column" gap="1" align="start">
227
+ <Text color="gray" id="secret-note" size="2">
228
+ Can‘t scan the code?{" "}
229
+ </Text>
230
+
231
+ <SecretDialog setupKey={totp?.secret ?? ""}>
232
+ <SecondaryButton
233
+ size="1"
234
+ disabled={verifyTotp.isPending || isSuccess}
235
+ >
236
+ View setup key
237
+ </SecondaryButton>
238
+ </SecretDialog>
239
+ </Flex>
240
+ </Flex>
241
+ </Flex>
242
+ <Text as="p" size="3" weight="bold">
243
+ Get verification passcode
244
+ </Text>
245
+ <Flex direction="column" gap="4">
246
+ <Text as="p" size="2">
247
+ Enter the 6-digit passcode from your authenticator app.
248
+ </Text>
249
+
250
+ <Flex direction="column" gap="2">
251
+ <Otp.Root
252
+ autoSubmit
253
+ gap="3"
254
+ justify="start"
255
+ name="otp-code"
256
+ rows="48px"
257
+ columns="repeat(6, 48px)"
258
+ readOnly={verifyTotp.isPending || isSuccess}
259
+ >
260
+ <Otp.Input required autoFocus autoComplete="off" />
261
+ <Otp.Input required />
262
+ <Otp.Input required />
263
+ <Otp.Input required />
264
+ <Otp.Input required />
265
+ <Otp.Input required />
266
+ </Otp.Root>
267
+
268
+ {serverError && (
269
+ <Text size="2" color="red">
270
+ {getMutationErrorMessage(serverError)}
271
+ </Text>
272
+ )}
273
+ </Flex>
274
+ </Flex>
275
+ </Grid>
276
+ </Grid>
277
+
278
+ <Flex mt="5" gap="3" justify="end">
279
+ <Dialog.Close>
280
+ <SecondaryButton disabled={verifyTotp.isPending || isSuccess}>
281
+ Cancel
282
+ </SecondaryButton>
283
+ </Dialog.Close>
284
+
285
+ <SaveButton
286
+ asChild
287
+ loading={verifyTotp.isPending}
288
+ done={isSuccess}
289
+ onDone={onClose}
290
+ >
291
+ <PrimaryButton type="submit">Confirm</PrimaryButton>
292
+ </SaveButton>
293
+ </Flex>
294
+ </Form.Root>
295
+
296
+ {/* mirror errors in a live region */}
297
+ <VisuallyHidden asChild>
298
+ <section aria-live="polite">
299
+ {getMutationErrorMessage(serverError)}
300
+ </section>
301
+ </VisuallyHidden>
302
+ </>
303
+ );
304
+ }
305
+
306
+ interface SecretDialogProps extends React.PropsWithChildren {
307
+ setupKey: string;
308
+ }
309
+
310
+ function SecretDialog({ children, setupKey }: SecretDialogProps) {
311
+ return (
312
+ <Dialog.Root>
313
+ <Dialog.Trigger>{children}</Dialog.Trigger>
314
+ <Dialog.Content
315
+ maxWidth="90vw"
316
+ size={{ initial: "3", sm: "4" }}
317
+ minWidth="300px"
318
+ width="fit-content"
319
+ >
320
+ <Dialog.Title size="2" weight="regular">
321
+ Your setup key
322
+ </Dialog.Title>
323
+ <Dialog.Description>
324
+ <Text size="6">
325
+ <Code variant="ghost" style={{ letterSpacing: "0.15rem" }}>
326
+ {setupKey}
327
+ </Code>
328
+ </Text>
329
+ </Dialog.Description>
330
+
331
+ <Flex align="center" gap="3" justify="end" mt="5">
332
+ <Dialog.Close>
333
+ <CopyButton asChild value={setupKey}>
334
+ <PrimaryButton>Copy and close</PrimaryButton>
335
+ </CopyButton>
336
+ </Dialog.Close>
337
+ </Flex>
338
+ </Dialog.Content>
339
+ </Dialog.Root>
340
+ );
341
+ }
342
+
343
+ function getMutationErrorMessage(error: unknown) {
344
+ let message = "Something went wrong, please try again";
345
+
346
+ if (typeof error === "string") {
347
+ message = error;
348
+ }
349
+
350
+ if (error instanceof Error) {
351
+ message = error.message;
352
+ }
353
+
354
+ if (
355
+ typeof error === "object" &&
356
+ error !== null &&
357
+ "message" in error &&
358
+ typeof error.message === "string"
359
+ ) {
360
+ message = error.message;
361
+ }
362
+
363
+ if (message === "Invalid passcode") {
364
+ message = "Invalid passcode, please try again";
365
+ }
366
+
367
+ return message;
368
+ }
369
+
370
+ function hasQrCode(
371
+ response?: CreateTotpFactorResponse,
372
+ ): response is CreateTotpFactorResponse & {
373
+ authenticationFactor: {
374
+ totp: NonNullable<CreateTotpFactorResponseAuthenticationFactorAllOfTotpAnyOf>;
375
+ };
376
+ } {
377
+ const totp = response?.authenticationFactor.totp;
378
+ return totp != null && "qr_code" in totp;
379
+ }