@workos-inc/widgets 1.9.0 → 1.10.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 (85) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cjs/admin-portal-audit-log-streaming.client.cjs +167 -0
  3. package/dist/cjs/admin-portal-audit-log-streaming.client.cjs.map +1 -0
  4. package/dist/cjs/admin-portal-audit-log-streaming.client.d.cts +26 -0
  5. package/dist/cjs/admin-portal-domain-verification.client.cjs.map +1 -1
  6. package/dist/cjs/admin-portal-sso-connection.client.cjs +4 -7
  7. package/dist/cjs/admin-portal-sso-connection.client.cjs.map +1 -1
  8. package/dist/cjs/api/api-provider.cjs.map +1 -1
  9. package/dist/cjs/api/api-provider.d.cts +1 -1
  10. package/dist/cjs/api/endpoint.cjs +176 -285
  11. package/dist/cjs/api/endpoint.cjs.map +1 -1
  12. package/dist/cjs/api/endpoint.d.cts +345 -379
  13. package/dist/cjs/directory-sync.client.cjs +16 -3
  14. package/dist/cjs/directory-sync.client.cjs.map +1 -1
  15. package/dist/cjs/experimental/api/fetch.cjs +42 -183
  16. package/dist/cjs/experimental/api/fetch.cjs.map +1 -1
  17. package/dist/cjs/experimental/api/fetch.d.cts +325 -369
  18. package/dist/cjs/experimental/api/react-query.cjs +151 -263
  19. package/dist/cjs/experimental/api/react-query.cjs.map +1 -1
  20. package/dist/cjs/experimental/api/react-query.d.cts +380 -370
  21. package/dist/cjs/experimental/api/swr.cjs +84 -183
  22. package/dist/cjs/experimental/api/swr.cjs.map +1 -1
  23. package/dist/cjs/experimental/api/swr.d.cts +356 -408
  24. package/dist/cjs/index.cjs +11 -0
  25. package/dist/cjs/index.cjs.map +1 -1
  26. package/dist/cjs/index.d.cts +2 -0
  27. package/dist/cjs/lib/add-mfa-dialog.cjs +18 -16
  28. package/dist/cjs/lib/add-mfa-dialog.cjs.map +1 -1
  29. package/dist/cjs/lib/admin-portal-audit-log-streaming.cjs +321 -0
  30. package/dist/cjs/lib/admin-portal-audit-log-streaming.cjs.map +1 -0
  31. package/dist/cjs/lib/admin-portal-audit-log-streaming.d.cts +54 -0
  32. package/dist/cjs/lib/admin-portal-sso-connection.cjs +0 -8
  33. package/dist/cjs/lib/admin-portal-sso-connection.cjs.map +1 -1
  34. package/dist/cjs/lib/admin-portal-sso-connection.d.cts +1 -2
  35. package/dist/cjs/lib/audit-log-stream-icons.cjs +63 -0
  36. package/dist/cjs/lib/audit-log-stream-icons.cjs.map +1 -0
  37. package/dist/cjs/lib/audit-log-stream-icons.d.cts +5 -0
  38. package/dist/cjs/lib/identity-providers.d.cts +2 -2
  39. package/dist/cjs/lib/provider-icon.cjs.map +1 -1
  40. package/dist/cjs/lib/provider-icon.d.cts +2 -2
  41. package/dist/cjs/workos-widgets.client.cjs +13 -1
  42. package/dist/cjs/workos-widgets.client.cjs.map +1 -1
  43. package/dist/esm/admin-portal-audit-log-streaming.client.d.ts +26 -0
  44. package/dist/esm/admin-portal-audit-log-streaming.client.js +153 -0
  45. package/dist/esm/admin-portal-audit-log-streaming.client.js.map +1 -0
  46. package/dist/esm/admin-portal-domain-verification.client.js +2 -2
  47. package/dist/esm/admin-portal-domain-verification.client.js.map +1 -1
  48. package/dist/esm/admin-portal-sso-connection.client.js +6 -9
  49. package/dist/esm/admin-portal-sso-connection.client.js.map +1 -1
  50. package/dist/esm/api/api-provider.d.ts +1 -1
  51. package/dist/esm/api/api-provider.js.map +1 -1
  52. package/dist/esm/api/endpoint.d.ts +345 -379
  53. package/dist/esm/api/endpoint.js +168 -265
  54. package/dist/esm/api/endpoint.js.map +1 -1
  55. package/dist/esm/directory-sync.client.js +16 -3
  56. package/dist/esm/directory-sync.client.js.map +1 -1
  57. package/dist/esm/experimental/api/fetch.d.ts +325 -369
  58. package/dist/esm/experimental/api/fetch.js +38 -163
  59. package/dist/esm/experimental/api/fetch.js.map +1 -1
  60. package/dist/esm/experimental/api/react-query.d.ts +380 -370
  61. package/dist/esm/experimental/api/react-query.js +141 -243
  62. package/dist/esm/experimental/api/react-query.js.map +1 -1
  63. package/dist/esm/experimental/api/swr.d.ts +356 -408
  64. package/dist/esm/experimental/api/swr.js +76 -163
  65. package/dist/esm/experimental/api/swr.js.map +1 -1
  66. package/dist/esm/index.d.ts +2 -0
  67. package/dist/esm/index.js +12 -0
  68. package/dist/esm/index.js.map +1 -1
  69. package/dist/esm/lib/add-mfa-dialog.js +18 -16
  70. package/dist/esm/lib/add-mfa-dialog.js.map +1 -1
  71. package/dist/esm/lib/admin-portal-audit-log-streaming.d.ts +54 -0
  72. package/dist/esm/lib/admin-portal-audit-log-streaming.js +290 -0
  73. package/dist/esm/lib/admin-portal-audit-log-streaming.js.map +1 -0
  74. package/dist/esm/lib/admin-portal-sso-connection.d.ts +1 -2
  75. package/dist/esm/lib/admin-portal-sso-connection.js +0 -8
  76. package/dist/esm/lib/admin-portal-sso-connection.js.map +1 -1
  77. package/dist/esm/lib/audit-log-stream-icons.d.ts +5 -0
  78. package/dist/esm/lib/audit-log-stream-icons.js +39 -0
  79. package/dist/esm/lib/audit-log-stream-icons.js.map +1 -0
  80. package/dist/esm/lib/identity-providers.d.ts +2 -2
  81. package/dist/esm/lib/provider-icon.d.ts +2 -2
  82. package/dist/esm/lib/provider-icon.js.map +1 -1
  83. package/dist/esm/workos-widgets.client.js +13 -1
  84. package/dist/esm/workos-widgets.client.js.map +1 -1
  85. package/package.json +2 -2
@@ -6,6 +6,7 @@ export { UserSecurity, UserSecurityProps } from './user-security.client.js';
6
6
  export { UserSessions, UserSessionsProps } from './user-sessions.client.js';
7
7
  export { UsersManagement, UsersManagementProps } from './users-management.client.js';
8
8
  export { AdminPortalDomainVerification, AdminPortalDomainVerificationProps } from './admin-portal-domain-verification.client.js';
9
+ export { AdminPortalAuditLogStreaming, AdminPortalAuditLogStreamingProps } from './admin-portal-audit-log-streaming.client.js';
9
10
  export { ApiKeys, ApiKeysProps } from './api-keys.client.js';
10
11
  export { Pipes, PipesProps } from './pipes.client.js';
11
12
  export { DirectorySync, DirectorySyncProps } from './directory-sync.client.js';
@@ -17,6 +18,7 @@ export { UserSecurityLoading } from './lib/user-security.js';
17
18
  export { UserSessionsLoading } from './lib/user-sessions.js';
18
19
  export { UsersManagementLoading } from './lib/users-management.js';
19
20
  export { AdminPortalDomainVerificationLoading } from './lib/admin-portal-domain-verification.js';
21
+ export { AdminPortalAuditLogStreamingError, AdminPortalAuditLogStreamingLoading, AdminPortalAuditLogStreamingButton as AdminPortalAuditLogStreamingOpenButton, AdminPortalAuditLogStreaming as AdminPortalAuditLogStreamingPresentational, AdminPortalAuditLogStreamingStatusProps } from './lib/admin-portal-audit-log-streaming.js';
20
22
  export { ApiKeysLoading } from './lib/api-keys/api-keys.js';
21
23
  export { PipesLoading } from './lib/pipes.js';
22
24
  export { DirectorySyncLoading } from './lib/directory-sync.js';
package/dist/esm/index.js CHANGED
@@ -29,6 +29,13 @@ import {
29
29
  AdminPortalDomainVerification,
30
30
  AdminPortalDomainVerificationLoading
31
31
  } from "./admin-portal-domain-verification.client.js";
32
+ import {
33
+ AdminPortalAuditLogStreaming,
34
+ AdminPortalAuditLogStreamingLoading,
35
+ AdminPortalAuditLogStreamingError,
36
+ AdminPortalAuditLogStreamingPresentational,
37
+ AdminPortalAuditLogStreamingButton
38
+ } from "./admin-portal-audit-log-streaming.client.js";
32
39
  import {
33
40
  ApiKeys,
34
41
  ApiKeysLoading
@@ -40,6 +47,11 @@ import {
40
47
  } from "./directory-sync.client.js";
41
48
  import { IntlContext } from "./lib/i18n/intl-context.js";
42
49
  export {
50
+ AdminPortalAuditLogStreaming,
51
+ AdminPortalAuditLogStreamingError,
52
+ AdminPortalAuditLogStreamingLoading,
53
+ AdminPortalAuditLogStreamingButton as AdminPortalAuditLogStreamingOpenButton,
54
+ AdminPortalAuditLogStreamingPresentational,
43
55
  AdminPortalDomainVerification,
44
56
  AdminPortalDomainVerificationLoading,
45
57
  AdminPortalSsoConnection,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n WorkOsWidgets,\n type WorkOsWidgetsProps,\n} from \"./workos-widgets.client.js\";\nexport {\n OrganizationSwitcher,\n OrganizationSwitcherLoading,\n type OrganizationSwitcherProps,\n} from \"./organization-switcher.client.js\";\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n type AdminPortalSsoConnectionProps,\n} from \"./admin-portal-sso-connection.client.js\";\nexport {\n UserProfile,\n UserProfileLoading,\n type UserProfileProps,\n} from \"./user-profile.client.js\";\nexport {\n UserSecurity,\n UserSecurityLoading,\n type UserSecurityProps,\n} from \"./user-security.client.js\";\nexport {\n UserSessions,\n UserSessionsLoading,\n type UserSessionsProps,\n} from \"./user-sessions.client.js\";\nexport {\n UsersManagement,\n UsersManagementLoading,\n type UsersManagementProps,\n} from \"./users-management.client.js\";\nexport {\n AdminPortalDomainVerification,\n AdminPortalDomainVerificationLoading,\n type AdminPortalDomainVerificationProps,\n} from \"./admin-portal-domain-verification.client.js\";\nexport {\n ApiKeys,\n ApiKeysLoading,\n type ApiKeysProps,\n} from \"./api-keys.client.js\";\nexport { Pipes, PipesLoading, type PipesProps } from \"./pipes.client.js\";\nexport {\n DirectorySync,\n DirectorySyncLoading,\n type DirectorySyncProps,\n} from \"./directory-sync.client.js\";\nexport { IntlContext as internal_IntlContext } from \"./lib/i18n/intl-context.js\";\n"],"mappings":"AAAA;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,OAAO,oBAAqC;AACrD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAwB,mBAA4B;","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export {\n WorkOsWidgets,\n type WorkOsWidgetsProps,\n} from \"./workos-widgets.client.js\";\nexport {\n OrganizationSwitcher,\n OrganizationSwitcherLoading,\n type OrganizationSwitcherProps,\n} from \"./organization-switcher.client.js\";\nexport {\n AdminPortalSsoConnection,\n AdminPortalSsoConnectionLoading,\n type AdminPortalSsoConnectionProps,\n} from \"./admin-portal-sso-connection.client.js\";\nexport {\n UserProfile,\n UserProfileLoading,\n type UserProfileProps,\n} from \"./user-profile.client.js\";\nexport {\n UserSecurity,\n UserSecurityLoading,\n type UserSecurityProps,\n} from \"./user-security.client.js\";\nexport {\n UserSessions,\n UserSessionsLoading,\n type UserSessionsProps,\n} from \"./user-sessions.client.js\";\nexport {\n UsersManagement,\n UsersManagementLoading,\n type UsersManagementProps,\n} from \"./users-management.client.js\";\nexport {\n AdminPortalDomainVerification,\n AdminPortalDomainVerificationLoading,\n type AdminPortalDomainVerificationProps,\n} from \"./admin-portal-domain-verification.client.js\";\nexport {\n AdminPortalAuditLogStreaming,\n AdminPortalAuditLogStreamingLoading,\n AdminPortalAuditLogStreamingError,\n type AdminPortalAuditLogStreamingProps,\n AdminPortalAuditLogStreamingPresentational,\n AdminPortalAuditLogStreamingButton as AdminPortalAuditLogStreamingOpenButton,\n type AdminPortalAuditLogStreamingStatusProps,\n} from \"./admin-portal-audit-log-streaming.client.js\";\nexport {\n ApiKeys,\n ApiKeysLoading,\n type ApiKeysProps,\n} from \"./api-keys.client.js\";\nexport { Pipes, PipesLoading, type PipesProps } from \"./pipes.client.js\";\nexport {\n DirectorySync,\n DirectorySyncLoading,\n type DirectorySyncProps,\n} from \"./directory-sync.client.js\";\nexport { IntlContext as internal_IntlContext } from \"./lib/i18n/intl-context.js\";\n"],"mappings":"AAAA;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACsC;AAAA,OAEjC;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,OAAO,oBAAqC;AACrD;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAwB,mBAA4B;","names":[]}
@@ -79,7 +79,7 @@ function Content({ onClose, totpFactor }) {
79
79
  const securitySettings = useSecuritySettings();
80
80
  const translate = useTranslation();
81
81
  const [customError, setCustomError] = React.useState(null);
82
- const totp = hasQrCode(totpFactor) ? totpFactor.authenticationFactor.totp : void 0;
82
+ const totp = totpFactor?.authenticationFactor.totp != null && "qr_code" in totpFactor.authenticationFactor.totp ? totpFactor.authenticationFactor.totp : void 0;
83
83
  const verifyTotp = useVerifyTotpFactor({
84
84
  mutation: {
85
85
  onSuccess: ({ success }) => {
@@ -208,7 +208,7 @@ function Content({ onClose, totpFactor }) {
208
208
  background: "var(--gray-2)",
209
209
  overflow: "hidden"
210
210
  },
211
- children: totp?.qr_code && /* @__PURE__ */ jsx(Box, { asChild: true, width: "100%", height: "auto", children: /* @__PURE__ */ jsx(
211
+ children: !!totp?.qr_code && /* @__PURE__ */ jsx(Box, { asChild: true, width: "100%", height: "auto", children: /* @__PURE__ */ jsx(
212
212
  "img",
213
213
  {
214
214
  alt: translate({
@@ -234,22 +234,28 @@ function Content({ onClose, totpFactor }) {
234
234
  description: "Question asking if user is unable to scan the QR code"
235
235
  }
236
236
  ) }),
237
- /* @__PURE__ */ jsx(SecretDialog, { setupKey: totp?.secret ?? "", children: /* @__PURE__ */ jsx(
238
- Button,
237
+ /* @__PURE__ */ jsx(
238
+ SecretDialog,
239
239
  {
240
- variant: "secondary",
241
- size: "1",
242
- disabled: verifyTotp.isPending || isSuccess,
240
+ setupKey: totp && "secret" in totp ? totp.secret : "",
243
241
  children: /* @__PURE__ */ jsx(
244
- Translation,
242
+ Button,
245
243
  {
246
- defaultMessage: "View setup key",
247
- id: "q3eZjH",
248
- description: "Button text to view the manual setup key"
244
+ variant: "secondary",
245
+ size: "1",
246
+ disabled: verifyTotp.isPending || isSuccess,
247
+ children: /* @__PURE__ */ jsx(
248
+ Translation,
249
+ {
250
+ defaultMessage: "View setup key",
251
+ id: "q3eZjH",
252
+ description: "Button text to view the manual setup key"
253
+ }
254
+ )
249
255
  }
250
256
  )
251
257
  }
252
- ) })
258
+ )
253
259
  ] })
254
260
  ] })
255
261
  ] }),
@@ -383,10 +389,6 @@ function getMutationErrorMessage(error) {
383
389
  }
384
390
  return message;
385
391
  }
386
- function hasQrCode(response) {
387
- const totp = response?.authenticationFactor.totp;
388
- return totp != null && "qr_code" in totp;
389
- }
390
392
  export {
391
393
  AddMfaDialog
392
394
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/add-mfa-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Box,\n Code,\n Flex,\n Grid,\n Link,\n Separator,\n Text,\n VisuallyHidden,\n} from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { type ReactNode } from \"react\";\nimport * as Otp from \"./otp-input.js\";\nimport { Dialog, Button } from \"./elements.js\";\nimport {\n CreateTotpFactorResponse,\n CreateTotpFactorResponseAuthenticationFactorAllOfTotpAnyOf,\n useCreateTotpFactor,\n useVerifyTotpFactor,\n} from \"../api/endpoint.js\";\nimport { useElevatedAccessToken } from \"../api/api-provider.js\";\nimport { Form } from \"radix-ui\";\nimport { Marker } from \"./marker.js\";\nimport { CopyButton } from \"./copy-button.js\";\nimport { useSecuritySettings } from \"./use-security-settings.js\";\nimport { ElevatedAccess } from \"./elevated-access.js\";\nimport { SaveButton } from \"./save-button.js\";\nimport { useDialogClose } from \"./use-dialog-close.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\n\ninterface AddMfaDialogProps extends Dialog.RootProps {\n children?: ReactNode;\n onSuccess?: () => void;\n}\n\nexport function AddMfaDialog({\n children,\n onSuccess,\n ...props\n}: AddMfaDialogProps) {\n const [open, setOpen] = React.useState(false);\n const [manuallyTriggered, setManuallyTriggered] = React.useState(false);\n const { elevatedAccess } = useElevatedAccessToken();\n const createAuthFactor = useCreateTotpFactor();\n\n const handleVerified = async () => {\n await createAuthFactor.mutateAsync(undefined);\n };\n\n const onTriggerClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (elevatedAccess && !createAuthFactor.data) {\n event.preventDefault();\n setManuallyTriggered(true);\n createAuthFactor.mutate(undefined, {\n onSuccess: () => {\n setOpen(true);\n },\n });\n } else {\n setManuallyTriggered(false);\n }\n };\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n return (\n <Dialog.Root\n {...props}\n open={props.open || open}\n onOpenChange={props.onOpenChange || setOpen}\n >\n <Dialog.Trigger\n onClick={onTriggerClick}\n // @ts-ignore I've to find a way to pass the loading state to the trigger\n loading={manuallyTriggered && createAuthFactor.isPending}\n >\n {children}\n </Dialog.Trigger>\n\n <Dialog.Content maxWidth=\"480px\">\n <ElevatedAccess onVerified={handleVerified}>\n <Content onClose={handleClose} totpFactor={createAuthFactor.data} />\n </ElevatedAccess>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\ninterface ContentProps {\n totpFactor?: CreateTotpFactorResponse;\n onClose?: () => void;\n}\n\nfunction Content({ onClose, totpFactor }: ContentProps) {\n const securitySettings = useSecuritySettings();\n const translate = useTranslation();\n\n const [customError, setCustomError] = React.useState<string | null>(null);\n const totp = hasQrCode(totpFactor)\n ? totpFactor.authenticationFactor.totp\n : undefined;\n\n const verifyTotp = useVerifyTotpFactor({\n mutation: {\n onSuccess: ({ success }) => {\n if (!success) {\n setCustomError(\"Invalid passcode\");\n }\n },\n },\n });\n\n const serverError = verifyTotp.error || customError;\n const isSuccess = verifyTotp.isSuccess && !serverError;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setCustomError(null);\n\n const formData = new FormData(event.currentTarget);\n const otpCode = formData.get(\"otp-code\")?.toString();\n\n verifyTotp.mutate({\n data: {\n authenticationChallengeId: totpFactor?.authenticationChallenge.id ?? \"\",\n code: otpCode ?? \"\",\n },\n });\n };\n\n useDialogClose(isSuccess, () => {\n securitySettings.update(\"Mfa\", true);\n });\n\n return (\n <>\n <Dialog.Title mb=\"5\">\n <Translation\n defaultMessage=\"Set up an authenticator app\"\n id=\"Eu+kuO\"\n description=\"Title for setting up two-factor authentication\"\n />\n </Dialog.Title>\n\n <Form.Root onSubmit={handleSubmit}>\n <Grid columns=\"auto 1fr\" rows=\"repeat(4, auto)\" gapX=\"3\" gapY=\"1\">\n <Grid\n rows=\"subgrid\"\n gridRow=\"span 4\"\n style={{ placeItems: \"center\" }}\n >\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>1</Marker>\n <Separator\n orientation=\"vertical\"\n size=\"4\"\n style={{ width: \"2px\" }}\n />\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>2</Marker>\n <div />\n </Grid>\n\n <Grid rows=\"subgrid\" gridRow=\"span 4\">\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Scan the QR code\"\n id=\"fTSp5u\"\n description=\"Heading for the QR code scanning step in MFA setup\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"1\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Use an authenticator app like {onep}, {google}, {authy}, or {microsoft} to scan the QR code below.\"\n id=\"8xwdwI\"\n description=\"Instructions for scanning the QR code with authenticator apps\"\n values={{\n onep: (\n <Link\n href=\"https://1password.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n 1Password\n </Link>\n ),\n google: (\n <Link\n href=\"https://apps.apple.com/us/app/google-authenticator/id388497605\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Google Authenticator\n </Link>\n ),\n authy: (\n <Link\n href=\"https://authy.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Authy\n </Link>\n ),\n microsoft: (\n <Link\n href=\"https://www.microsoft.com/en-gb/security/mobile-authenticator-app\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Microsoft Authenticator\n </Link>\n ),\n }}\n />\n </Text>\n <Flex align=\"center\" gap=\"5\" my=\"5\">\n <Grid\n position=\"relative\"\n width=\"160px\"\n height=\"160px\"\n p=\"2\"\n style={{\n border: \"1px solid var(--gray-7)\",\n borderRadius: \"var(--radius-4)\",\n background: \"var(--gray-2)\",\n overflow: \"hidden\",\n }}\n >\n {totp?.qr_code && (\n <Box asChild width=\"100%\" height=\"auto\">\n <img\n alt={translate({\n defaultMessage: \"Scan this QR code to enroll\",\n description: \"Alt text for QR code image\",\n id: \"wpbqFJ\",\n })}\n aria-describedby=\"secret-note\"\n height=\"160\"\n src={totp.qr_code}\n style={{ userSelect: \"none\", background: \"white\" }}\n width=\"160\"\n />\n </Box>\n )}\n </Grid>\n\n <Flex direction=\"column\" gap=\"1\" align=\"start\">\n <Text color=\"gray\" id=\"secret-note\" size=\"2\">\n <Translation\n defaultMessage=\"Can't scan the code?\"\n id=\"6/cdcS\"\n description=\"Question asking if user is unable to scan the QR code\"\n />\n </Text>\n\n <SecretDialog setupKey={totp?.secret ?? \"\"}>\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"View setup key\"\n id=\"q3eZjH\"\n description=\"Button text to view the manual setup key\"\n />\n </Button>\n </SecretDialog>\n </Flex>\n </Flex>\n </Flex>\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Get verification passcode\"\n id=\"1kRd2b\"\n description=\"Heading for entering the verification code step\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"4\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Enter the 6-digit passcode from your authenticator app.\"\n id=\"4/66bS\"\n description=\"Instructions for entering the verification passcode\"\n />\n </Text>\n\n <Flex direction=\"column\" gap=\"2\">\n <Otp.Root\n autoSubmit\n gap=\"3\"\n justify=\"start\"\n name=\"otp-code\"\n rows=\"48px\"\n columns=\"repeat(6, 48px)\"\n readOnly={verifyTotp.isPending || isSuccess}\n >\n <Otp.Input required autoFocus autoComplete=\"off\" />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n </Otp.Root>\n\n {serverError && (\n <Text size=\"2\" color=\"red\">\n {getMutationErrorMessage(serverError)}\n </Text>\n )}\n </Flex>\n </Flex>\n </Grid>\n </Grid>\n\n <Flex mt=\"5\" gap=\"3\" justify=\"end\">\n <Dialog.Close>\n <Button\n variant=\"secondary\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"Cancel\"\n id=\"84pAvU\"\n description=\"Button text to cancel MFA setup\"\n />\n </Button>\n </Dialog.Close>\n\n <SaveButton\n type=\"submit\"\n loading={verifyTotp.isPending}\n done={isSuccess}\n onDone={onClose}\n >\n <Translation\n defaultMessage=\"Confirm\"\n id=\"WHthZi\"\n description=\"Button text to confirm MFA setup\"\n />\n </SaveButton>\n </Flex>\n </Form.Root>\n\n {/* mirror errors in a live region */}\n <VisuallyHidden asChild>\n <section aria-live=\"polite\">\n {getMutationErrorMessage(serverError)}\n </section>\n </VisuallyHidden>\n </>\n );\n}\n\ninterface SecretDialogProps extends React.PropsWithChildren {\n setupKey: string;\n}\n\nfunction SecretDialog({ children, setupKey }: SecretDialogProps) {\n return (\n <Dialog.Root>\n <Dialog.Trigger>{children}</Dialog.Trigger>\n <Dialog.Content\n maxWidth=\"90vw\"\n size={{ initial: \"3\", sm: \"4\" }}\n minWidth=\"300px\"\n width=\"fit-content\"\n >\n <Dialog.Title size=\"2\" weight=\"regular\">\n <Translation\n defaultMessage=\"Your setup key\"\n id=\"LleqNP\"\n description=\"Title for dialog showing the manual setup key\"\n />\n </Dialog.Title>\n <Dialog.Description>\n <Text size=\"6\">\n <Code variant=\"ghost\" style={{ letterSpacing: \"0.15rem\" }}>\n {setupKey}\n </Code>\n </Text>\n </Dialog.Description>\n\n <Flex align=\"center\" gap=\"3\" justify=\"end\" mt=\"5\">\n <Dialog.Close>\n <CopyButton value={setupKey}>\n <Translation\n defaultMessage=\"Copy and close\"\n id=\"EyjGir\"\n description=\"Button text to copy setup key and close dialog\"\n />\n </CopyButton>\n </Dialog.Close>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n let message = \"Something went wrong, please try again\";\n\n if (typeof error === \"string\") {\n message = error;\n }\n\n if (error instanceof Error) {\n message = error.message;\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n message = error.message;\n }\n\n if (message === \"Invalid passcode\") {\n message = \"Invalid passcode, please try again\";\n }\n\n return message;\n}\n\nfunction hasQrCode(\n response?: CreateTotpFactorResponse,\n): response is CreateTotpFactorResponse & {\n authenticationFactor: {\n totp: NonNullable<CreateTotpFactorResponseAuthenticationFactorAllOfTotpAnyOf>;\n };\n} {\n const totp = response?.authenticationFactor.totp;\n return totp != null && \"qr_code\" in totp;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/add-mfa-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Box,\n Code,\n Flex,\n Grid,\n Link,\n Separator,\n Text,\n VisuallyHidden,\n} from \"@radix-ui/themes\";\nimport * as React from \"react\";\nimport { type ReactNode } from \"react\";\nimport * as Otp from \"./otp-input.js\";\nimport { Dialog, Button } from \"./elements.js\";\nimport {\n CreateTotpFactorResponse,\n useCreateTotpFactor,\n useVerifyTotpFactor,\n} from \"../api/endpoint.js\";\nimport { useElevatedAccessToken } from \"../api/api-provider.js\";\nimport { Form } from \"radix-ui\";\nimport { Marker } from \"./marker.js\";\nimport { CopyButton } from \"./copy-button.js\";\nimport { useSecuritySettings } from \"./use-security-settings.js\";\nimport { ElevatedAccess } from \"./elevated-access.js\";\nimport { SaveButton } from \"./save-button.js\";\nimport { useDialogClose } from \"./use-dialog-close.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\n\ninterface AddMfaDialogProps extends Dialog.RootProps {\n children?: ReactNode;\n onSuccess?: () => void;\n}\n\nexport function AddMfaDialog({\n children,\n onSuccess,\n ...props\n}: AddMfaDialogProps) {\n const [open, setOpen] = React.useState(false);\n const [manuallyTriggered, setManuallyTriggered] = React.useState(false);\n const { elevatedAccess } = useElevatedAccessToken();\n const createAuthFactor = useCreateTotpFactor();\n\n const handleVerified = async () => {\n await createAuthFactor.mutateAsync(undefined);\n };\n\n const onTriggerClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n if (elevatedAccess && !createAuthFactor.data) {\n event.preventDefault();\n setManuallyTriggered(true);\n createAuthFactor.mutate(undefined, {\n onSuccess: () => {\n setOpen(true);\n },\n });\n } else {\n setManuallyTriggered(false);\n }\n };\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n return (\n <Dialog.Root\n {...props}\n open={props.open || open}\n onOpenChange={props.onOpenChange || setOpen}\n >\n <Dialog.Trigger\n onClick={onTriggerClick}\n // @ts-ignore I've to find a way to pass the loading state to the trigger\n loading={manuallyTriggered && createAuthFactor.isPending}\n >\n {children}\n </Dialog.Trigger>\n\n <Dialog.Content maxWidth=\"480px\">\n <ElevatedAccess onVerified={handleVerified}>\n <Content onClose={handleClose} totpFactor={createAuthFactor.data} />\n </ElevatedAccess>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\ninterface ContentProps {\n totpFactor?: CreateTotpFactorResponse;\n onClose?: () => void;\n}\n\nfunction Content({ onClose, totpFactor }: ContentProps) {\n const securitySettings = useSecuritySettings();\n const translate = useTranslation();\n\n const [customError, setCustomError] = React.useState<string | null>(null);\n const totp =\n totpFactor?.authenticationFactor.totp != null &&\n \"qr_code\" in totpFactor.authenticationFactor.totp\n ? totpFactor.authenticationFactor.totp\n : undefined;\n\n const verifyTotp = useVerifyTotpFactor({\n mutation: {\n onSuccess: ({ success }) => {\n if (!success) {\n setCustomError(\"Invalid passcode\");\n }\n },\n },\n });\n\n const serverError = verifyTotp.error || customError;\n const isSuccess = verifyTotp.isSuccess && !serverError;\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setCustomError(null);\n\n const formData = new FormData(event.currentTarget);\n const otpCode = formData.get(\"otp-code\")?.toString();\n\n verifyTotp.mutate({\n data: {\n authenticationChallengeId: totpFactor?.authenticationChallenge.id ?? \"\",\n code: otpCode ?? \"\",\n },\n });\n };\n\n useDialogClose(isSuccess, () => {\n securitySettings.update(\"Mfa\", true);\n });\n\n return (\n <>\n <Dialog.Title mb=\"5\">\n <Translation\n defaultMessage=\"Set up an authenticator app\"\n id=\"Eu+kuO\"\n description=\"Title for setting up two-factor authentication\"\n />\n </Dialog.Title>\n\n <Form.Root onSubmit={handleSubmit}>\n <Grid columns=\"auto 1fr\" rows=\"repeat(4, auto)\" gapX=\"3\" gapY=\"1\">\n <Grid\n rows=\"subgrid\"\n gridRow=\"span 4\"\n style={{ placeItems: \"center\" }}\n >\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>1</Marker>\n <Separator\n orientation=\"vertical\"\n size=\"4\"\n style={{ width: \"2px\" }}\n />\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Marker>2</Marker>\n <div />\n </Grid>\n\n <Grid rows=\"subgrid\" gridRow=\"span 4\">\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Scan the QR code\"\n id=\"fTSp5u\"\n description=\"Heading for the QR code scanning step in MFA setup\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"1\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Use an authenticator app like {onep}, {google}, {authy}, or {microsoft} to scan the QR code below.\"\n id=\"8xwdwI\"\n description=\"Instructions for scanning the QR code with authenticator apps\"\n values={{\n onep: (\n <Link\n href=\"https://1password.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n 1Password\n </Link>\n ),\n google: (\n <Link\n href=\"https://apps.apple.com/us/app/google-authenticator/id388497605\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Google Authenticator\n </Link>\n ),\n authy: (\n <Link\n href=\"https://authy.com/\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Authy\n </Link>\n ),\n microsoft: (\n <Link\n href=\"https://www.microsoft.com/en-gb/security/mobile-authenticator-app\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n // eslint-disable-next-line formatjs/no-literal-string-in-jsx\n >\n Microsoft Authenticator\n </Link>\n ),\n }}\n />\n </Text>\n <Flex align=\"center\" gap=\"5\" my=\"5\">\n <Grid\n position=\"relative\"\n width=\"160px\"\n height=\"160px\"\n p=\"2\"\n style={{\n border: \"1px solid var(--gray-7)\",\n borderRadius: \"var(--radius-4)\",\n background: \"var(--gray-2)\",\n overflow: \"hidden\",\n }}\n >\n {!!totp?.qr_code && (\n <Box asChild width=\"100%\" height=\"auto\">\n <img\n alt={translate({\n defaultMessage: \"Scan this QR code to enroll\",\n description: \"Alt text for QR code image\",\n id: \"wpbqFJ\",\n })}\n aria-describedby=\"secret-note\"\n height=\"160\"\n src={totp.qr_code}\n style={{ userSelect: \"none\", background: \"white\" }}\n width=\"160\"\n />\n </Box>\n )}\n </Grid>\n\n <Flex direction=\"column\" gap=\"1\" align=\"start\">\n <Text color=\"gray\" id=\"secret-note\" size=\"2\">\n <Translation\n defaultMessage=\"Can't scan the code?\"\n id=\"6/cdcS\"\n description=\"Question asking if user is unable to scan the QR code\"\n />\n </Text>\n\n <SecretDialog\n setupKey={totp && \"secret\" in totp ? totp.secret : \"\"}\n >\n <Button\n variant=\"secondary\"\n size=\"1\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"View setup key\"\n id=\"q3eZjH\"\n description=\"Button text to view the manual setup key\"\n />\n </Button>\n </SecretDialog>\n </Flex>\n </Flex>\n </Flex>\n <Text as=\"p\" size=\"3\" weight=\"bold\">\n <Translation\n defaultMessage=\"Get verification passcode\"\n id=\"1kRd2b\"\n description=\"Heading for entering the verification code step\"\n />\n </Text>\n <Flex direction=\"column\" gap=\"4\">\n <Text as=\"p\" size=\"2\">\n <Translation\n defaultMessage=\"Enter the 6-digit passcode from your authenticator app.\"\n id=\"4/66bS\"\n description=\"Instructions for entering the verification passcode\"\n />\n </Text>\n\n <Flex direction=\"column\" gap=\"2\">\n <Otp.Root\n autoSubmit\n gap=\"3\"\n justify=\"start\"\n name=\"otp-code\"\n rows=\"48px\"\n columns=\"repeat(6, 48px)\"\n readOnly={verifyTotp.isPending || isSuccess}\n >\n <Otp.Input required autoFocus autoComplete=\"off\" />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n <Otp.Input required />\n </Otp.Root>\n\n {serverError && (\n <Text size=\"2\" color=\"red\">\n {getMutationErrorMessage(serverError)}\n </Text>\n )}\n </Flex>\n </Flex>\n </Grid>\n </Grid>\n\n <Flex mt=\"5\" gap=\"3\" justify=\"end\">\n <Dialog.Close>\n <Button\n variant=\"secondary\"\n disabled={verifyTotp.isPending || isSuccess}\n >\n <Translation\n defaultMessage=\"Cancel\"\n id=\"84pAvU\"\n description=\"Button text to cancel MFA setup\"\n />\n </Button>\n </Dialog.Close>\n\n <SaveButton\n type=\"submit\"\n loading={verifyTotp.isPending}\n done={isSuccess}\n onDone={onClose}\n >\n <Translation\n defaultMessage=\"Confirm\"\n id=\"WHthZi\"\n description=\"Button text to confirm MFA setup\"\n />\n </SaveButton>\n </Flex>\n </Form.Root>\n\n {/* mirror errors in a live region */}\n <VisuallyHidden asChild>\n <section aria-live=\"polite\">\n {getMutationErrorMessage(serverError)}\n </section>\n </VisuallyHidden>\n </>\n );\n}\n\ninterface SecretDialogProps extends React.PropsWithChildren {\n setupKey: string;\n}\n\nfunction SecretDialog({ children, setupKey }: SecretDialogProps) {\n return (\n <Dialog.Root>\n <Dialog.Trigger>{children}</Dialog.Trigger>\n <Dialog.Content\n maxWidth=\"90vw\"\n size={{ initial: \"3\", sm: \"4\" }}\n minWidth=\"300px\"\n width=\"fit-content\"\n >\n <Dialog.Title size=\"2\" weight=\"regular\">\n <Translation\n defaultMessage=\"Your setup key\"\n id=\"LleqNP\"\n description=\"Title for dialog showing the manual setup key\"\n />\n </Dialog.Title>\n <Dialog.Description>\n <Text size=\"6\">\n <Code variant=\"ghost\" style={{ letterSpacing: \"0.15rem\" }}>\n {setupKey}\n </Code>\n </Text>\n </Dialog.Description>\n\n <Flex align=\"center\" gap=\"3\" justify=\"end\" mt=\"5\">\n <Dialog.Close>\n <CopyButton value={setupKey}>\n <Translation\n defaultMessage=\"Copy and close\"\n id=\"EyjGir\"\n description=\"Button text to copy setup key and close dialog\"\n />\n </CopyButton>\n </Dialog.Close>\n </Flex>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\nfunction getMutationErrorMessage(error: unknown) {\n let message = \"Something went wrong, please try again\";\n\n if (typeof error === \"string\") {\n message = error;\n }\n\n if (error instanceof Error) {\n message = error.message;\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n message = error.message;\n }\n\n if (message === \"Invalid passcode\") {\n message = \"Invalid passcode, please try again\";\n }\n\n return message;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,54 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { WidgetRootDomProps } from './utils.js';
4
+ import { AuditLogStreamType } from '../api/endpoint.js';
5
+ import './elements.js';
6
+ import '@radix-ui/themes';
7
+ import '@radix-ui/themes/props';
8
+ import '../dialog-C15qCLN3.js';
9
+ import '@radix-ui/themes/components/dialog';
10
+ import '../alert-dialog-BlG3_awx.js';
11
+ import '@radix-ui/themes/components/alert-dialog';
12
+ import '../dropdown-menu-BQ5LtvdR.js';
13
+ import '@radix-ui/themes/components/dropdown-menu';
14
+ import '../select-KR89Qnvm.js';
15
+ import '@radix-ui/themes/components/select';
16
+ import '@tanstack/react-query';
17
+ import '../api/widgets-api-client.js';
18
+
19
+ interface NotConfiguredProps {
20
+ connectionStatus: "NotConfigured";
21
+ }
22
+ interface InactiveProps {
23
+ connectionStatus: "Inactive";
24
+ destinationType: AuditLogStreamType;
25
+ }
26
+ interface ActiveProps {
27
+ connectionStatus: "Active";
28
+ destinationType: AuditLogStreamType;
29
+ lastSyncedEventId?: string | null;
30
+ }
31
+ interface ErrorProps {
32
+ connectionStatus: "Error";
33
+ destinationType: AuditLogStreamType;
34
+ lastSyncedEventId?: string | null;
35
+ }
36
+ type AdminPortalAuditLogStreamingStatusProps = NotConfiguredProps | InactiveProps | ActiveProps | ErrorProps;
37
+ type AdminPortalAuditLogStreamingProps = WidgetRootDomProps & AdminPortalAuditLogStreamingStatusProps & {
38
+ adminPortalOpenButton: React.ReactNode;
39
+ };
40
+ declare function AdminPortalAuditLogStreamingButton({ isPending, href, initConfig, }: {
41
+ isPending: boolean;
42
+ href: string | null;
43
+ initConfig: () => void;
44
+ }): react_jsx_runtime.JSX.Element;
45
+ declare const AdminPortalAuditLogStreaming: React.FC<AdminPortalAuditLogStreamingProps>;
46
+ interface AdminPortalAuditLogStreamingLoadingProps extends WidgetRootDomProps {
47
+ }
48
+ declare const AdminPortalAuditLogStreamingLoading: React.FC<AdminPortalAuditLogStreamingLoadingProps>;
49
+ interface AdminPortalAuditLogStreamingErrorProps extends WidgetRootDomProps {
50
+ error: unknown;
51
+ }
52
+ declare const AdminPortalAuditLogStreamingError: React.FC<AdminPortalAuditLogStreamingErrorProps>;
53
+
54
+ export { AdminPortalAuditLogStreaming, AdminPortalAuditLogStreamingButton, AdminPortalAuditLogStreamingError, type AdminPortalAuditLogStreamingErrorProps, AdminPortalAuditLogStreamingLoading, type AdminPortalAuditLogStreamingLoadingProps, type AdminPortalAuditLogStreamingProps, type AdminPortalAuditLogStreamingStatusProps };
@@ -0,0 +1,290 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Box, Card, Flex, Text } from "@radix-ui/themes";
5
+ import * as CardList from "./card-list.js";
6
+ import { Button, Skeleton } from "./elements.js";
7
+ import {
8
+ ExternalLinkIcon,
9
+ Cross2Icon,
10
+ InfoCircledIcon
11
+ } from "@radix-ui/react-icons";
12
+ import { ProviderIcon } from "./provider-icon.js";
13
+ import { IconPanel } from "./icon-panel.js";
14
+ import { GenericHttpsIcon } from "./audit-log-stream-icons.js";
15
+ import { Status } from "./status.js";
16
+ import {
17
+ getDomProps
18
+ } from "./utils.js";
19
+ import { Translation } from "./i18n/translation.js";
20
+ import { useTranslation } from "./i18n/use-translation.js";
21
+ import { getErrorMessage } from "./generic-error.js";
22
+ const AdminPortalAuditLogStreamingContext = React.createContext(null);
23
+ function useAdminPortalAuditLogStreamingContext() {
24
+ const context = React.useContext(AdminPortalAuditLogStreamingContext);
25
+ if (!context) {
26
+ throw new Error(
27
+ "useAdminPortalAuditLogStreamingContext must be used within a AdminPortalAuditLogStreamingContext provider"
28
+ );
29
+ }
30
+ return context;
31
+ }
32
+ function getDestinationName(type) {
33
+ switch (type) {
34
+ case "Datadog":
35
+ return "Datadog";
36
+ case "Splunk":
37
+ return "Splunk";
38
+ case "S3":
39
+ return "AWS S3";
40
+ case "GoogleCloudStorage":
41
+ return "Google Cloud Storage";
42
+ case "AzureSentinel":
43
+ return "Azure Sentinel";
44
+ case "GenericHttps":
45
+ return "Generic HTTPS";
46
+ default:
47
+ return type;
48
+ }
49
+ }
50
+ function getDestinationIcon(type) {
51
+ switch (type) {
52
+ case "Datadog":
53
+ return "datadog";
54
+ case "Splunk":
55
+ return "splunk";
56
+ case "S3":
57
+ return "aws";
58
+ case "GoogleCloudStorage":
59
+ return "google-cloud";
60
+ case "AzureSentinel":
61
+ return "azure";
62
+ default:
63
+ return void 0;
64
+ }
65
+ }
66
+ function getWidgetRootDomProps(state, domProps) {
67
+ return getDomProps({
68
+ ...domProps,
69
+ isWidgetRoot: true,
70
+ widgetId: "admin-portal-audit-log-streaming",
71
+ widgetState: state
72
+ });
73
+ }
74
+ const CROCKFORD_BASE32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
75
+ function decodeUlidTimestamp(ulid) {
76
+ if (!ulid || ulid.length < 10) return null;
77
+ let timestamp = 0;
78
+ for (let i = 0; i < 10; i++) {
79
+ const charIndex = CROCKFORD_BASE32.indexOf(ulid.charAt(i).toUpperCase());
80
+ if (charIndex === -1) return null;
81
+ timestamp = timestamp * 32 + charIndex;
82
+ }
83
+ return new Date(timestamp);
84
+ }
85
+ function getRelativeTimeString(currentDate, pastDate) {
86
+ const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
87
+ const diff = pastDate.getTime() - currentDate.getTime();
88
+ const diffSeconds = Math.round(diff / 1e3);
89
+ const diffMinutes = Math.round(diffSeconds / 60);
90
+ const diffHours = Math.round(diffMinutes / 60);
91
+ const diffDays = Math.round(diffHours / 24);
92
+ const diffMonths = Math.round(diffDays / 30);
93
+ const diffYears = Math.round(diffMonths / 12);
94
+ if (Math.abs(diffSeconds) < 60) return "now";
95
+ if (Math.abs(diffMinutes) < 60) return rtf.format(diffMinutes, "minute");
96
+ if (Math.abs(diffHours) < 24) return rtf.format(diffHours, "hour");
97
+ if (Math.abs(diffDays) < 30) return rtf.format(diffDays, "day");
98
+ if (Math.abs(diffMonths) < 12) return rtf.format(diffMonths, "month");
99
+ return rtf.format(diffYears, "year");
100
+ }
101
+ function AdminPortalAuditLogStreamingButton({
102
+ isPending,
103
+ href,
104
+ initConfig
105
+ }) {
106
+ const { connectionStatus } = useAdminPortalAuditLogStreamingContext();
107
+ const label = (() => {
108
+ switch (connectionStatus) {
109
+ case "NotConfigured":
110
+ return /* @__PURE__ */ jsx(
111
+ Translation,
112
+ {
113
+ defaultMessage: "Set up Log Streams",
114
+ id: "s3Wu7U",
115
+ description: "Button label to start log stream setup"
116
+ }
117
+ );
118
+ case "Inactive":
119
+ return /* @__PURE__ */ jsx(
120
+ Translation,
121
+ {
122
+ defaultMessage: "Continue setup",
123
+ id: "/oM/HY",
124
+ description: "Button label to continue incomplete log stream setup"
125
+ }
126
+ );
127
+ case "Active":
128
+ case "Error":
129
+ return /* @__PURE__ */ jsx(
130
+ Translation,
131
+ {
132
+ defaultMessage: "Manage",
133
+ id: "+k5uUi",
134
+ description: "Button label to manage log stream settings"
135
+ }
136
+ );
137
+ }
138
+ })();
139
+ if (href) {
140
+ return /* @__PURE__ */ jsx(Button, { variant: "secondary", asChild: true, children: /* @__PURE__ */ jsxs("a", { href, target: "_blank", rel: "noopener noreferrer", children: [
141
+ label,
142
+ " ",
143
+ /* @__PURE__ */ jsx(ExternalLinkIcon, { "aria-hidden": true })
144
+ ] }) });
145
+ }
146
+ return /* @__PURE__ */ jsxs(
147
+ Button,
148
+ {
149
+ variant: "secondary",
150
+ loading: isPending,
151
+ disabled: isPending,
152
+ onClick: initConfig,
153
+ children: [
154
+ label,
155
+ " ",
156
+ /* @__PURE__ */ jsx(ExternalLinkIcon, { "aria-hidden": true })
157
+ ]
158
+ }
159
+ );
160
+ }
161
+ const AdminPortalAuditLogStreaming = (props) => {
162
+ const { connectionStatus, adminPortalOpenButton, className } = props;
163
+ const destinationType = connectionStatus !== "NotConfigured" ? props.destinationType : null;
164
+ const lastSyncedEventId = connectionStatus === "Active" || connectionStatus === "Error" ? props.lastSyncedEventId : void 0;
165
+ const lastSyncedAt = lastSyncedEventId ? decodeUlidTimestamp(lastSyncedEventId) : null;
166
+ const icon = destinationType ? getDestinationIcon(destinationType) : null;
167
+ return /* @__PURE__ */ jsx(AdminPortalAuditLogStreamingContext.Provider, { value: { connectionStatus }, children: /* @__PURE__ */ jsxs(CardList.Root, { ...getWidgetRootDomProps("resolved", { className }), children: [
168
+ /* @__PURE__ */ jsx(CardList.Item, { children: /* @__PURE__ */ jsxs(Flex, { direction: "row", justify: "between", align: "center", gap: "2", children: [
169
+ /* @__PURE__ */ jsx(Flex, { gap: "4", align: "center", children: connectionStatus === "NotConfigured" ? /* @__PURE__ */ jsx(Text, { size: "2", color: "gray", children: /* @__PURE__ */ jsx(
170
+ Translation,
171
+ {
172
+ defaultMessage: "You haven't set up Log Streams yet.",
173
+ id: "n4mruE",
174
+ description: "Empty state message when log streaming is not configured"
175
+ }
176
+ ) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
177
+ /* @__PURE__ */ jsx(IconPanel, { color: "panel", children: icon ? /* @__PURE__ */ jsx(ProviderIcon, { provider: icon, size: "2" }) : /* @__PURE__ */ jsx(GenericHttpsIcon, {}) }),
178
+ lastSyncedAt ? /* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
179
+ /* @__PURE__ */ jsx(Text, { size: "2", weight: "bold", children: getDestinationName(destinationType) }),
180
+ /* @__PURE__ */ jsx(Text, { size: "2", color: "gray", children: /* @__PURE__ */ jsx(
181
+ Translation,
182
+ {
183
+ defaultMessage: "Last sync {relativeTime}",
184
+ id: "fT9f0p",
185
+ description: "Label showing when the last log stream sync occurred",
186
+ values: {
187
+ relativeTime: getRelativeTimeString(
188
+ /* @__PURE__ */ new Date(),
189
+ lastSyncedAt
190
+ )
191
+ }
192
+ }
193
+ ) })
194
+ ] }) : /* @__PURE__ */ jsx(Text, { size: "2", weight: "bold", children: getDestinationName(destinationType) })
195
+ ] }) }),
196
+ /* @__PURE__ */ jsx(Flex, { gap: "5", align: "center", children: connectionStatus === "NotConfigured" ? adminPortalOpenButton : /* @__PURE__ */ jsxs(Fragment, { children: [
197
+ connectionStatus === "Inactive" && /* @__PURE__ */ jsx(Status, { state: "waiting", children: /* @__PURE__ */ jsx(
198
+ Translation,
199
+ {
200
+ defaultMessage: "Setup in progress",
201
+ id: "M6iKLG",
202
+ description: "Status when log stream setup is incomplete"
203
+ }
204
+ ) }),
205
+ connectionStatus === "Active" && /* @__PURE__ */ jsx(Status, { state: "success", children: /* @__PURE__ */ jsx(
206
+ Translation,
207
+ {
208
+ defaultMessage: "Streaming",
209
+ id: "25L0J+",
210
+ description: "Status when log stream is active"
211
+ }
212
+ ) }),
213
+ connectionStatus === "Error" && /* @__PURE__ */ jsx(Status, { state: "error", children: /* @__PURE__ */ jsx(
214
+ Translation,
215
+ {
216
+ defaultMessage: "Not streaming",
217
+ id: "7fAKZo",
218
+ description: "Status when log stream has an error"
219
+ }
220
+ ) }),
221
+ adminPortalOpenButton
222
+ ] }) })
223
+ ] }) }),
224
+ connectionStatus === "Error" && /* @__PURE__ */ jsx(CardList.Item, { children: /* @__PURE__ */ jsxs(Flex, { align: "start", gap: "2", children: [
225
+ /* @__PURE__ */ jsx(Box, { asChild: true, mt: "2px", flexShrink: "0", children: /* @__PURE__ */ jsx(InfoCircledIcon, { color: "gray" }) }),
226
+ /* @__PURE__ */ jsx(Text, { size: "2", color: "gray", children: /* @__PURE__ */ jsx(
227
+ Translation,
228
+ {
229
+ defaultMessage: "The credentials provided are incorrect or missing. Please review and update your log stream configuration.",
230
+ id: "23tmgn",
231
+ description: "Error message shown when audit log stream has a configuration or delivery error"
232
+ }
233
+ ) })
234
+ ] }) })
235
+ ] }) });
236
+ };
237
+ const AdminPortalAuditLogStreamingLoading = (props) => {
238
+ return /* @__PURE__ */ jsx(Card, { size: "2", ...getWidgetRootDomProps("loading", props), children: /* @__PURE__ */ jsxs(Flex, { direction: "row", justify: "between", align: "center", gap: "2", children: [
239
+ /* @__PURE__ */ jsxs(Flex, { gap: "4", align: "center", children: [
240
+ /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(IconPanel, { color: "panel", children: /* @__PURE__ */ jsx(ProviderIcon, { provider: "datadog", size: "2" }) }) }),
241
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "1", my: "-4px", children: [
242
+ /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Text, { size: "1", children: "Datadog" }) }),
243
+ /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Text, { size: "1", children: "Last sync 10 minutes ago" }) })
244
+ ] })
245
+ ] }),
246
+ /* @__PURE__ */ jsxs(Flex, { gap: "5", align: "center", children: [
247
+ /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsx(Status, { state: "success", children: "Streaming" }) }),
248
+ /* @__PURE__ */ jsx(Skeleton, { children: /* @__PURE__ */ jsxs(Button, { variant: "secondary", children: [
249
+ "Manage ",
250
+ /* @__PURE__ */ jsx(ExternalLinkIcon, { "aria-hidden": true })
251
+ ] }) })
252
+ ] })
253
+ ] }) });
254
+ };
255
+ const AdminPortalAuditLogStreamingError = ({ error, ...domProps }) => {
256
+ React.useEffect(() => {
257
+ console.error(error);
258
+ }, [error]);
259
+ const translate = useTranslation();
260
+ const { heading, message } = getErrorMessage(error, translate);
261
+ return /* @__PURE__ */ jsx(Card, { size: "2", ...getWidgetRootDomProps("error", domProps), children: /* @__PURE__ */ jsx(Flex, { direction: "row", justify: "between", align: "center", gap: "2", children: /* @__PURE__ */ jsxs(Flex, { gap: "4", align: "center", children: [
262
+ /* @__PURE__ */ jsx(
263
+ Flex,
264
+ {
265
+ align: "center",
266
+ justify: "center",
267
+ width: "24px",
268
+ height: "24px",
269
+ style: {
270
+ borderRadius: "9999px",
271
+ backgroundColor: "var(--red-a4)",
272
+ color: "var(--red-a11)",
273
+ flexShrink: 0
274
+ },
275
+ children: /* @__PURE__ */ jsx(Cross2Icon, { width: "18px", height: "18px" })
276
+ }
277
+ ),
278
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
279
+ /* @__PURE__ */ jsx(Text, { size: "2", weight: "bold", children: heading }),
280
+ /* @__PURE__ */ jsx(Text, { size: "2", color: "gray", children: message })
281
+ ] })
282
+ ] }) }) });
283
+ };
284
+ export {
285
+ AdminPortalAuditLogStreaming,
286
+ AdminPortalAuditLogStreamingButton,
287
+ AdminPortalAuditLogStreamingError,
288
+ AdminPortalAuditLogStreamingLoading
289
+ };
290
+ //# sourceMappingURL=admin-portal-audit-log-streaming.js.map