@open-mercato/enterprise 0.6.6-develop.6367.1.2321ccacd4 → 0.6.6-develop.6373.1.5bece5409d

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.
@@ -16,19 +16,29 @@ import {
16
16
  } from "../../../../lib/mfa-enrollment-notice.js";
17
17
  import { useProviderListComponent } from "../../../../components/mfa-ui-registry.js";
18
18
  import RecoveryCodesListItem from "../../../../components/mfa-provider-list-items/RecoveryCodesListItem.js";
19
+ function ProviderRowItem({ provider, configuredCount, onOpenProvider }) {
20
+ const ListComponent = useProviderListComponent(provider);
21
+ return /* @__PURE__ */ jsx(
22
+ ListComponent,
23
+ {
24
+ provider,
25
+ configuredCount,
26
+ onClick: () => onOpenProvider(provider.type)
27
+ }
28
+ );
29
+ }
19
30
  function ProviderListCell({ row, onOpenProvider }) {
20
31
  if (row.kind === "recovery_codes") {
21
32
  return /* @__PURE__ */ jsx(RecoveryCodesListItem, { onClick: () => onOpenProvider("recovery_codes") });
22
33
  }
23
34
  const provider = row.provider;
24
35
  if (!provider) return null;
25
- const ListComponent = useProviderListComponent(provider);
26
36
  return /* @__PURE__ */ jsx(
27
- ListComponent,
37
+ ProviderRowItem,
28
38
  {
29
39
  provider,
30
40
  configuredCount: row.configuredCount ?? 0,
31
- onClick: () => onOpenProvider(provider.type)
41
+ onOpenProvider
32
42
  }
33
43
  );
34
44
  }
@@ -120,6 +130,8 @@ function SecurityMfaPage() {
120
130
  ] });
121
131
  }
122
132
  export {
133
+ ProviderListCell,
134
+ ProviderRowItem,
123
135
  SecurityMfaPage as default
124
136
  };
125
137
  //# sourceMappingURL=page.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/security/backend/profile/security/mfa/page.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation.js'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { EmptyState } from '@open-mercato/ui/backend/EmptyState'\nimport { LoadingMessage } from '@open-mercato/ui/backend/detail'\n\nimport MfaEnrollmentNotice from '../../../../components/MfaEnrollmentNotice'\nimport { useMfaStatus } from '../../../../components/hooks/useMfaStatus'\nimport { FormHeader } from '@open-mercato/ui/backend/forms/FormHeader'\nimport {\n removeMfaEnrollmentNoticeQueryFromHref,\n resolveMfaEnrollmentNotice,\n} from '../../../../lib/mfa-enrollment-notice'\nimport type { MfaProvider } from '../../../../types'\nimport { useProviderListComponent } from '../../../../components/mfa-ui-registry'\nimport RecoveryCodesListItem from '../../../../components/mfa-provider-list-items/RecoveryCodesListItem'\n\ntype MfaProviderRow = {\n kind: 'provider' | 'recovery_codes'\n provider?: MfaProvider\n configuredCount?: number\n}\n\ntype ProviderListCellProps = {\n row: MfaProviderRow\n onOpenProvider: (providerType: string) => void\n}\n\nfunction ProviderListCell({ row, onOpenProvider }: ProviderListCellProps) {\n if (row.kind === 'recovery_codes') {\n return <RecoveryCodesListItem onClick={() => onOpenProvider('recovery_codes')} />\n }\n\n const provider = row.provider\n if (!provider) return null\n const ListComponent = useProviderListComponent(provider)\n\n return (\n <ListComponent\n provider={provider}\n configuredCount={row.configuredCount ?? 0}\n onClick={() => onOpenProvider(provider.type)}\n />\n )\n}\n\nexport default function SecurityMfaPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { loading, methods, providers } = useMfaStatus()\n const [showEnrollmentNotice, setShowEnrollmentNotice] = React.useState(false)\n const [showOverdueEnrollmentNotice, setShowOverdueEnrollmentNotice] = React.useState(false)\n\n React.useEffect(() => {\n const noticeState = resolveMfaEnrollmentNotice(searchParams)\n if (!noticeState.visible) return\n\n setShowEnrollmentNotice(true)\n setShowOverdueEnrollmentNotice(noticeState.overdue)\n\n if (typeof window === 'undefined') return\n const nextUrl = removeMfaEnrollmentNoticeQueryFromHref(window.location.href)\n if (!nextUrl) return\n window.history.replaceState(window.history.state, '', nextUrl)\n }, [searchParams])\n\n const providerRows = React.useMemo<MfaProviderRow[]>(() => {\n const configuredCountByType = new Map<string, number>()\n for (const method of methods) {\n const currentCount = configuredCountByType.get(method.type) ?? 0\n configuredCountByType.set(method.type, currentCount + 1)\n }\n\n const providerRows: MfaProviderRow[] = providers.map((provider) => ({\n kind: 'provider' as const,\n provider,\n configuredCount: configuredCountByType.get(provider.type) ?? 0,\n }))\n providerRows.push({ kind: 'recovery_codes' })\n return providerRows\n }, [methods, providers])\n\n const handleOpenProvider = React.useCallback((providerType: string) => {\n if (providerType === 'recovery_codes') {\n router.push('/backend/profile/security/mfa/recovery-codes')\n return\n }\n router.push(`/backend/profile/security/mfa/${encodeURIComponent(providerType)}`)\n }, [router])\n\n const columns = React.useMemo<ColumnDef<MfaProviderRow>[]>(() => [\n {\n accessorKey: 'provider.type',\n header: t('security.profile.mfa.providers.tableColumn', 'Methods'),\n meta: {\n truncate: false,\n maxWidth: '100%',\n },\n cell: ({ row }) => (\n <ProviderListCell row={row.original} onOpenProvider={handleOpenProvider} />\n ),\n },\n ], [handleOpenProvider, t])\n\n if (loading) {\n return <LoadingMessage label={t('security.profile.mfa.loading', 'Loading MFA settings...')} />\n }\n\n return (\n <Page>\n <MfaEnrollmentNotice\n visible={showEnrollmentNotice}\n overdue={showOverdueEnrollmentNotice}\n onDismiss={() => setShowEnrollmentNotice(false)}\n />\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/profile/security\"\n backLabel={t('security.profile.backToList', 'Back to security settings')}\n title={t('security.profile.mfa.title', 'Multi-factor authentication')}\n subtitle={t('security.profile.mfa.description', 'Manage your MFA methods and recovery codes.')}\n />\n <PageBody>\n <DataTable\n columns={columns}\n data={providerRows}\n emptyState={(\n <EmptyState\n title={t('security.profile.mfa.providers.empty', 'No MFA providers are currently available.')}\n />\n )}\n embedded\n />\n </PageBody>\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation.js'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { EmptyState } from '@open-mercato/ui/backend/EmptyState'\nimport { LoadingMessage } from '@open-mercato/ui/backend/detail'\n\nimport MfaEnrollmentNotice from '../../../../components/MfaEnrollmentNotice'\nimport { useMfaStatus } from '../../../../components/hooks/useMfaStatus'\nimport { FormHeader } from '@open-mercato/ui/backend/forms/FormHeader'\nimport {\n removeMfaEnrollmentNoticeQueryFromHref,\n resolveMfaEnrollmentNotice,\n} from '../../../../lib/mfa-enrollment-notice'\nimport type { MfaProvider } from '../../../../types'\nimport { useProviderListComponent } from '../../../../components/mfa-ui-registry'\nimport RecoveryCodesListItem from '../../../../components/mfa-provider-list-items/RecoveryCodesListItem'\n\ntype MfaProviderRow = {\n kind: 'provider' | 'recovery_codes'\n provider?: MfaProvider\n configuredCount?: number\n}\n\ntype ProviderListCellProps = {\n row: MfaProviderRow\n onOpenProvider: (providerType: string) => void\n}\n\ntype ProviderRowItemProps = {\n provider: MfaProvider\n configuredCount: number\n onOpenProvider: (providerType: string) => void\n}\n\n// Always receives a provider so useProviderListComponent runs unconditionally,\n// keeping the hook count stable. The recovery_codes / missing-provider branches\n// live in the parent (ProviderListCell), which now calls no hooks at all.\nexport function ProviderRowItem({ provider, configuredCount, onOpenProvider }: ProviderRowItemProps) {\n const ListComponent = useProviderListComponent(provider)\n\n return (\n <ListComponent\n provider={provider}\n configuredCount={configuredCount}\n onClick={() => onOpenProvider(provider.type)}\n />\n )\n}\n\nexport function ProviderListCell({ row, onOpenProvider }: ProviderListCellProps) {\n if (row.kind === 'recovery_codes') {\n return <RecoveryCodesListItem onClick={() => onOpenProvider('recovery_codes')} />\n }\n\n const provider = row.provider\n if (!provider) return null\n\n return (\n <ProviderRowItem\n provider={provider}\n configuredCount={row.configuredCount ?? 0}\n onOpenProvider={onOpenProvider}\n />\n )\n}\n\nexport default function SecurityMfaPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { loading, methods, providers } = useMfaStatus()\n const [showEnrollmentNotice, setShowEnrollmentNotice] = React.useState(false)\n const [showOverdueEnrollmentNotice, setShowOverdueEnrollmentNotice] = React.useState(false)\n\n React.useEffect(() => {\n const noticeState = resolveMfaEnrollmentNotice(searchParams)\n if (!noticeState.visible) return\n\n setShowEnrollmentNotice(true)\n setShowOverdueEnrollmentNotice(noticeState.overdue)\n\n if (typeof window === 'undefined') return\n const nextUrl = removeMfaEnrollmentNoticeQueryFromHref(window.location.href)\n if (!nextUrl) return\n window.history.replaceState(window.history.state, '', nextUrl)\n }, [searchParams])\n\n const providerRows = React.useMemo<MfaProviderRow[]>(() => {\n const configuredCountByType = new Map<string, number>()\n for (const method of methods) {\n const currentCount = configuredCountByType.get(method.type) ?? 0\n configuredCountByType.set(method.type, currentCount + 1)\n }\n\n const providerRows: MfaProviderRow[] = providers.map((provider) => ({\n kind: 'provider' as const,\n provider,\n configuredCount: configuredCountByType.get(provider.type) ?? 0,\n }))\n providerRows.push({ kind: 'recovery_codes' })\n return providerRows\n }, [methods, providers])\n\n const handleOpenProvider = React.useCallback((providerType: string) => {\n if (providerType === 'recovery_codes') {\n router.push('/backend/profile/security/mfa/recovery-codes')\n return\n }\n router.push(`/backend/profile/security/mfa/${encodeURIComponent(providerType)}`)\n }, [router])\n\n const columns = React.useMemo<ColumnDef<MfaProviderRow>[]>(() => [\n {\n accessorKey: 'provider.type',\n header: t('security.profile.mfa.providers.tableColumn', 'Methods'),\n meta: {\n truncate: false,\n maxWidth: '100%',\n },\n cell: ({ row }) => (\n <ProviderListCell row={row.original} onOpenProvider={handleOpenProvider} />\n ),\n },\n ], [handleOpenProvider, t])\n\n if (loading) {\n return <LoadingMessage label={t('security.profile.mfa.loading', 'Loading MFA settings...')} />\n }\n\n return (\n <Page>\n <MfaEnrollmentNotice\n visible={showEnrollmentNotice}\n overdue={showOverdueEnrollmentNotice}\n onDismiss={() => setShowEnrollmentNotice(false)}\n />\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/profile/security\"\n backLabel={t('security.profile.backToList', 'Back to security settings')}\n title={t('security.profile.mfa.title', 'Multi-factor authentication')}\n subtitle={t('security.profile.mfa.description', 'Manage your MFA methods and recovery codes.')}\n />\n <PageBody>\n <DataTable\n columns={columns}\n data={providerRows}\n emptyState={(\n <EmptyState\n title={t('security.profile.mfa.providers.empty', 'No MFA providers are currently available.')}\n />\n )}\n embedded\n />\n </PageBody>\n </Page>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["providerRows"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/enterprise",
3
- "version": "0.6.6-develop.6367.1.2321ccacd4",
3
+ "version": "0.6.6-develop.6373.1.5bece5409d",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -65,8 +65,8 @@
65
65
  }
66
66
  },
67
67
  "dependencies": {
68
- "@open-mercato/core": "0.6.6-develop.6367.1.2321ccacd4",
69
- "@open-mercato/ui": "0.6.6-develop.6367.1.2321ccacd4",
68
+ "@open-mercato/core": "0.6.6-develop.6373.1.5bece5409d",
69
+ "@open-mercato/ui": "0.6.6-develop.6373.1.5bece5409d",
70
70
  "@simplewebauthn/browser": "^13.3.0",
71
71
  "@simplewebauthn/server": "^13.3.1",
72
72
  "@simplewebauthn/types": "^12.0.0",
@@ -76,12 +76,12 @@
76
76
  "qrcode": "^1.5.4"
77
77
  },
78
78
  "peerDependencies": {
79
- "@open-mercato/shared": "0.6.6-develop.6367.1.2321ccacd4",
79
+ "@open-mercato/shared": "0.6.6-develop.6373.1.5bece5409d",
80
80
  "react": "^19.0.0",
81
81
  "react-dom": "^19.0.0"
82
82
  },
83
83
  "devDependencies": {
84
- "@open-mercato/shared": "0.6.6-develop.6367.1.2321ccacd4",
84
+ "@open-mercato/shared": "0.6.6-develop.6373.1.5bece5409d",
85
85
  "@types/jest": "^30.0.0",
86
86
  "@types/react": "^19.2.17",
87
87
  "@types/react-dom": "^19.2.3",
@@ -31,20 +31,40 @@ type ProviderListCellProps = {
31
31
  onOpenProvider: (providerType: string) => void
32
32
  }
33
33
 
34
- function ProviderListCell({ row, onOpenProvider }: ProviderListCellProps) {
34
+ type ProviderRowItemProps = {
35
+ provider: MfaProvider
36
+ configuredCount: number
37
+ onOpenProvider: (providerType: string) => void
38
+ }
39
+
40
+ // Always receives a provider so useProviderListComponent runs unconditionally,
41
+ // keeping the hook count stable. The recovery_codes / missing-provider branches
42
+ // live in the parent (ProviderListCell), which now calls no hooks at all.
43
+ export function ProviderRowItem({ provider, configuredCount, onOpenProvider }: ProviderRowItemProps) {
44
+ const ListComponent = useProviderListComponent(provider)
45
+
46
+ return (
47
+ <ListComponent
48
+ provider={provider}
49
+ configuredCount={configuredCount}
50
+ onClick={() => onOpenProvider(provider.type)}
51
+ />
52
+ )
53
+ }
54
+
55
+ export function ProviderListCell({ row, onOpenProvider }: ProviderListCellProps) {
35
56
  if (row.kind === 'recovery_codes') {
36
57
  return <RecoveryCodesListItem onClick={() => onOpenProvider('recovery_codes')} />
37
58
  }
38
59
 
39
60
  const provider = row.provider
40
61
  if (!provider) return null
41
- const ListComponent = useProviderListComponent(provider)
42
62
 
43
63
  return (
44
- <ListComponent
64
+ <ProviderRowItem
45
65
  provider={provider}
46
66
  configuredCount={row.configuredCount ?? 0}
47
- onClick={() => onOpenProvider(provider.type)}
67
+ onOpenProvider={onOpenProvider}
48
68
  />
49
69
  )
50
70
  }