@open-mercato/core 0.5.1-develop.2975.ccbadc8198 → 0.5.1-develop.2996.ce62fd491c

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 (82) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/sidebar_variant/index.js +25 -0
  3. package/dist/generated/entities/sidebar_variant/index.js.map +7 -0
  4. package/dist/generated/entities.ids.generated.js +1 -0
  5. package/dist/generated/entities.ids.generated.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +13 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/helpers/integration/authUi.js +1 -1
  9. package/dist/helpers/integration/authUi.js.map +2 -2
  10. package/dist/modules/audit_logs/services/actionLogService.js +4 -5
  11. package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
  12. package/dist/modules/auth/api/sidebar/preferences/route.js +224 -35
  13. package/dist/modules/auth/api/sidebar/preferences/route.js.map +3 -3
  14. package/dist/modules/auth/api/sidebar/variants/[id]/route.js +161 -0
  15. package/dist/modules/auth/api/sidebar/variants/[id]/route.js.map +7 -0
  16. package/dist/modules/auth/api/sidebar/variants/route.js +142 -0
  17. package/dist/modules/auth/api/sidebar/variants/route.js.map +7 -0
  18. package/dist/modules/auth/backend/sidebar-customization/page.js +16 -0
  19. package/dist/modules/auth/backend/sidebar-customization/page.js.map +7 -0
  20. package/dist/modules/auth/backend/sidebar-customization/page.meta.js +28 -0
  21. package/dist/modules/auth/backend/sidebar-customization/page.meta.js.map +7 -0
  22. package/dist/modules/auth/data/entities.js +45 -4
  23. package/dist/modules/auth/data/entities.js.map +2 -2
  24. package/dist/modules/auth/data/validators.js +63 -1
  25. package/dist/modules/auth/data/validators.js.map +2 -2
  26. package/dist/modules/auth/migrations/Migration20260427081815.js +15 -0
  27. package/dist/modules/auth/migrations/Migration20260427081815.js.map +7 -0
  28. package/dist/modules/auth/migrations/Migration20260427124900.js +15 -0
  29. package/dist/modules/auth/migrations/Migration20260427124900.js.map +7 -0
  30. package/dist/modules/auth/migrations/Migration20260427143311.js +72 -0
  31. package/dist/modules/auth/migrations/Migration20260427143311.js.map +7 -0
  32. package/dist/modules/auth/services/sidebarPreferencesService.js +176 -16
  33. package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
  34. package/dist/modules/customers/backend/customers/companies/[id]/page.js +3 -1
  35. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  36. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +4 -2
  37. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  38. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +8 -3
  39. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  40. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -2
  41. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  42. package/dist/modules/customers/components/formConfig.js +3 -3
  43. package/dist/modules/customers/components/formConfig.js.map +2 -2
  44. package/dist/modules/customers/lib/displayName.js +12 -0
  45. package/dist/modules/customers/lib/displayName.js.map +2 -2
  46. package/dist/modules/entities/cli.js +5 -6
  47. package/dist/modules/entities/cli.js.map +2 -2
  48. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +124 -0
  49. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +7 -0
  50. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.js +11 -0
  51. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.js.map +7 -0
  52. package/generated/entities/sidebar_variant/index.ts +11 -0
  53. package/generated/entities.ids.generated.ts +1 -0
  54. package/generated/entity-fields-registry.ts +13 -0
  55. package/package.json +6 -6
  56. package/src/helpers/integration/authUi.ts +1 -1
  57. package/src/modules/audit_logs/services/actionLogService.ts +5 -6
  58. package/src/modules/auth/api/sidebar/preferences/route.ts +266 -34
  59. package/src/modules/auth/api/sidebar/variants/[id]/route.ts +183 -0
  60. package/src/modules/auth/api/sidebar/variants/route.ts +157 -0
  61. package/src/modules/auth/backend/sidebar-customization/page.meta.ts +34 -0
  62. package/src/modules/auth/backend/sidebar-customization/page.tsx +17 -0
  63. package/src/modules/auth/data/entities.ts +48 -2
  64. package/src/modules/auth/data/validators.ts +70 -0
  65. package/src/modules/auth/migrations/.snapshot-open-mercato.json +790 -71
  66. package/src/modules/auth/migrations/Migration20260427081815.ts +16 -0
  67. package/src/modules/auth/migrations/Migration20260427124900.ts +19 -0
  68. package/src/modules/auth/migrations/Migration20260427143311.ts +83 -0
  69. package/src/modules/auth/services/sidebarPreferencesService.ts +243 -18
  70. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +5 -4
  71. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +6 -5
  72. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +13 -9
  73. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +3 -2
  74. package/src/modules/customers/components/formConfig.tsx +3 -3
  75. package/src/modules/customers/lib/displayName.ts +21 -0
  76. package/src/modules/entities/cli.ts +5 -6
  77. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.ts +9 -0
  78. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +168 -0
  79. package/src/modules/portal/i18n/de.json +20 -0
  80. package/src/modules/portal/i18n/en.json +20 -0
  81. package/src/modules/portal/i18n/es.json +20 -0
  82. package/src/modules/portal/i18n/pl.json +20 -0
@@ -16,7 +16,10 @@ import {
16
16
  TenantDataEncryptionError,
17
17
  TenantDataEncryptionErrorCode
18
18
  } from "@open-mercato/shared/lib/encryption/aes";
19
- import { TenantDataEncryptionService } from "@open-mercato/shared/lib/encryption/tenantDataEncryptionService";
19
+ import {
20
+ TenantDataEncryptionService,
21
+ parseDecryptedFieldValue
22
+ } from "@open-mercato/shared/lib/encryption/tenantDataEncryptionService";
20
23
  import { resolveEntityIdFromMetadata } from "@open-mercato/shared/lib/encryption/entityIds";
21
24
  import { Organization } from "../directory/data/entities.js";
22
25
  import crypto from "node:crypto";
@@ -503,11 +506,7 @@ const rotateEncryptionKey = {
503
506
  if (typeof value !== "string" || !isEncryptedPayload(value)) continue;
504
507
  const decrypted = decryptWithOldKey(value, oldDek);
505
508
  if (decrypted === null) continue;
506
- try {
507
- payload[rule.field] = JSON.parse(decrypted);
508
- } catch {
509
- payload[rule.field] = decrypted;
510
- }
509
+ payload[rule.field] = parseDecryptedFieldValue(decrypted);
511
510
  }
512
511
  }
513
512
  const encrypted = await encryptionService.encryptEntityPayload(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/entities/cli.ts"],
4
- "sourcesContent": ["import { getCliModules, getDefaultEncryptionMaps, type Module, type ModuleCli } from '@open-mercato/shared/modules/registry'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { CacheStrategy } from '@open-mercato/cache/types'\nimport { CustomEntity, CustomFieldDef, EncryptionMap } from './data/entities'\nimport {\n installCustomEntitiesFromModules,\n getAggregatedCustomEntityConfigs,\n} from './lib/install-from-ce'\nimport readline from 'node:readline/promises'\nimport { stdin as input, stdout as output } from 'node:process'\nimport { isTenantDataEncryptionEnabled } from '@open-mercato/shared/lib/encryption/toggles'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport { createKmsService, type KmsService, type TenantDek } from '@open-mercato/shared/lib/encryption/kms'\nimport {\n decryptWithAesGcm,\n decryptWithAesGcmStrict,\n TenantDataEncryptionError,\n TenantDataEncryptionErrorCode,\n} from '@open-mercato/shared/lib/encryption/aes'\nimport { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'\nimport { resolveEntityIdFromMetadata } from '@open-mercato/shared/lib/encryption/entityIds'\nimport { Organization } from '../directory/data/entities'\nimport crypto from 'node:crypto'\n\nfunction parseArgs(rest: string[]) {\n const args: Record<string, string | boolean> = {}\n for (let i = 0; i < rest.length; i++) {\n const a = rest[i]\n if (!a) continue\n if (a.startsWith('--')) {\n const [k, v] = a.replace(/^--/, '').split('=')\n if (v !== undefined) args[k] = v\n else if (rest[i + 1] && !rest[i + 1]!.startsWith('--')) { args[k] = rest[i + 1]!; i++ }\n else args[k] = true\n }\n }\n return args\n}\n\nconst seedDefs: ModuleCli = {\n command: 'install',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string)\n const globalOnly = Boolean(args.global)\n const dry = Boolean(args['dry-run'] || args.dry)\n const force = Boolean(args.force)\n const includeGlobal = args['no-global'] ? false : true\n\n if (globalOnly && includeGlobal === false) {\n console.error('Cannot combine --global with --no-global.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n let cache: CacheStrategy | null = null\n try { cache = resolve('cache') as CacheStrategy } catch {}\n\n const tenantIds = tenantIdArg\n ? [tenantIdArg]\n : (globalOnly ? [] : undefined)\n\n const logger = (message: string) => {\n const prefix = dry ? '[dry-run] ' : ''\n console.log(`${prefix}${message}`)\n }\n\n const result = await installCustomEntitiesFromModules(em, cache, {\n tenantIds,\n includeGlobal,\n dryRun: dry,\n force,\n logger,\n })\n const label = dry ? 'Dry-run' : 'Sync'\n console.log(`\u2705 ${label} complete: processed=${result.processed}, updated=${result.synchronized}, fieldsChanged=${result.fieldChanges}, skipped=${result.skipped}`)\n },\n}\n\n// Reinstall: remove existing definitions for target scope and re-seed from modules\nconst reinstallDefs: ModuleCli = {\n command: 'reinstall',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string)\n const globalOnly = Boolean(args.global)\n const dry = Boolean(args['dry-run'] || args.dry)\n const includeGlobal = globalOnly ? true : (args['no-global'] ? false : true)\n\n if (globalOnly && includeGlobal === false) {\n console.error('Cannot combine --global with --no-global.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n let cache: CacheStrategy | null = null\n try { cache = resolve('cache') as CacheStrategy } catch {}\n\n const tenantIds = tenantIdArg\n ? [tenantIdArg]\n : (globalOnly ? [] : undefined)\n\n const aggregates = getAggregatedCustomEntityConfigs()\n const relevant = aggregates.filter((entry) => (globalOnly ? entry.spec?.global === true : true))\n if (!relevant.length) {\n console.log('No custom entities or fields discovered. Nothing to reinstall.')\n return\n }\n const entityIds = Array.from(new Set(relevant.map((entry) => entry.entityId)))\n if (!entityIds.length) {\n console.log('No entity ids discovered. Nothing to reinstall.')\n return\n }\n\n const logger = (message: string) => {\n const prefix = dry ? '[dry-run] ' : ''\n console.log(`${prefix}${message}`)\n }\n\n if (dry) {\n console.log('Dry-run: would remove existing custom entity definitions before reinstall.')\n } else {\n const fieldWhere: any = { entityId: { $in: entityIds } }\n if (tenantIds !== undefined) {\n if (tenantIds.length === 0) fieldWhere.tenantId = null\n else fieldWhere.tenantId = { $in: tenantIds }\n }\n const removedFields = await em.nativeDelete(CustomFieldDef, fieldWhere)\n\n const entityWhere: any = { entityId: { $in: entityIds } }\n if (tenantIds !== undefined) {\n if (tenantIds.length === 0) entityWhere.tenantId = null\n else entityWhere.tenantId = { $in: tenantIds }\n }\n const removedEntities = await em.nativeDelete(CustomEntity, entityWhere)\n\n if (cache && entityIds.length) {\n try {\n await cache.deleteByTags(entityIds.map((id) => `custom-entity:${id}`))\n } catch {}\n }\n console.log(`Cleared definitions: fields=${removedFields}, entities=${removedEntities}`)\n }\n\n const result = await installCustomEntitiesFromModules(em, cache, {\n tenantIds,\n includeGlobal,\n dryRun: dry,\n force: true,\n logger,\n })\n const label = dry ? 'Dry-run' : 'Reinstall'\n console.log(`\u2705 ${label} complete: processed=${result.processed}, updated=${result.synchronized}, fieldsChanged=${result.fieldChanges}, skipped=${result.skipped}`)\n },\n}\n\n// Interactive: add a single custom field definition\nconst addField: ModuleCli = {\n command: 'add-field',\n async run(rest) {\n const args = parseArgs(rest)\n const rl = readline.createInterface({ input, output })\n const ask = async (q: string, d?: string) => {\n const a = (await rl.question(d ? `${q} [${d}]: ` : `${q}: `)).trim()\n return a || (d ?? '')\n }\n const askBool = async (q: string, d = false) => {\n const a = (await ask(q, d ? 'y' : 'n')).toLowerCase()\n return parseBooleanToken(a) === true\n }\n\n try {\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n\n const entityId = (args.entity as string) || (args.e as string) || await ask('Entity ID (e.g., example:todo)')\n const isGlobal = args.global ? true : await askBool('Global (no organization)?', false)\n const orgId = isGlobal ? null : ((args.org as string) || (args.organizationId as string) || await ask('Organization ID'))\n const tenantId = isGlobal ? null : ((args.tenant as string) || (args.tenantId as string) || await ask('Tenant ID'))\n const key = (args.key as string) || await ask('Field key (snake_case)')\n let kind = (args.kind as string) || await ask(\"Kind (text|multiline|integer|float|boolean|select|currency|relation|attachment)\", 'text')\n kind = kind.toLowerCase()\n if (!['text','multiline','integer','float','boolean','select','currency','relation','attachment'].includes(kind)) throw new Error('Invalid kind')\n const label = (args.label as string) || (await ask('Label', key))\n const description = (args.description as string) || ''\n const required = args.required !== undefined ? Boolean(args.required) : await askBool('Required?', false)\n const multi = args.multi !== undefined ? Boolean(args.multi) : await askBool('Allow multiple?', false)\n let options: string[] | undefined\n if (kind === 'select') {\n const raw = (args.options as string) || await ask('Options (comma-separated)', 'low,medium,high')\n options = raw.split(',').map((s) => s.trim()).filter(Boolean)\n }\n let defaultValue: any = undefined\n const defRaw = (args.default as string) ?? (args.defaultValue as string)\n const needDefault = defRaw !== undefined ? defRaw : await ask('Default value (leave empty for none)', '')\n if (needDefault !== '') {\n switch (kind) {\n case 'integer': defaultValue = Number(needDefault); break\n case 'float': defaultValue = Number(needDefault); break\n case 'boolean': defaultValue = parseBooleanToken(String(needDefault)) === true; break\n default: defaultValue = String(needDefault)\n }\n }\n const filterable = args.filterable !== undefined ? Boolean(args.filterable) : await askBool('Filterable?', true)\n const listVisible = args.listVisible !== undefined ? Boolean(args.listVisible) : await askBool('Visible in list?', true)\n const formEditable = args.formEditable !== undefined ? Boolean(args.formEditable) : await askBool('Editable in forms?', true)\n const indexed = args.indexed !== undefined ? Boolean(args.indexed) : await askBool('Indexed?', false)\n\n const where = { entityId, organizationId: orgId, tenantId: tenantId, key }\n const existing = await em.findOne(CustomFieldDef, where)\n const configJson: any = {}\n if (options) configJson.options = options\n if (defaultValue !== undefined) configJson.defaultValue = defaultValue\n if (required !== undefined) configJson.required = required\n if (multi !== undefined) configJson.multi = multi\n if (filterable !== undefined) configJson.filterable = filterable\n if (indexed !== undefined) configJson.indexed = indexed\n if (listVisible !== undefined) configJson.listVisible = listVisible\n if (formEditable !== undefined) configJson.formEditable = formEditable\n if (label !== undefined) configJson.label = label\n if (description !== undefined) configJson.description = description\n\n if (!existing) {\n await em.persist(em.create(CustomFieldDef, {\n entityId,\n organizationId: orgId,\n tenantId: tenantId,\n key,\n kind,\n configJson,\n isActive: true,\n })).flush()\n console.log(`Created custom field: ${entityId}.${key} (${kind})${orgId == null ? ' [global]' : ` [org=${orgId}, tenant=${tenantId}]`}`)\n } else {\n existing.kind = kind as any\n existing.configJson = configJson\n existing.isActive = true\n await em.flush()\n console.log(`Updated custom field: ${entityId}.${key} (${kind})${orgId == null ? ' [global]' : ` [org=${orgId}, tenant=${tenantId}]`}`)\n }\n } catch (e: any) {\n console.error('Failed:', e?.message || e)\n } finally {\n await rl.close()\n }\n },\n}\n\nfunction resolveEncryptionMapModules(): Module[] {\n const cliModules = getCliModules()\n if (cliModules.length > 0) return cliModules\n try {\n const { getModules } = require('@open-mercato/shared/lib/modules/registry')\n return getModules()\n } catch {\n return []\n }\n}\n\nasync function upsertEncryptionMaps(em: any, tenantId: string, organizationId: string | null, logger: (msg: string) => void) {\n for (const spec of getDefaultEncryptionMaps(resolveEncryptionMapModules())) {\n const existing = await em.findOne(EncryptionMap, {\n entityId: spec.entityId,\n tenantId,\n organizationId,\n deletedAt: null,\n })\n if (existing) {\n existing.fieldsJson = spec.fields\n existing.isActive = true\n existing.updatedAt = new Date()\n logger(`\uD83D\uDD12 Updated encryption map for ${spec.entityId} \u2728`)\n await em.persist(existing).flush()\n continue\n }\n const map = em.create(EncryptionMap, {\n entityId: spec.entityId,\n tenantId,\n organizationId,\n fieldsJson: spec.fields,\n isActive: true,\n })\n await em.persist(map).flush()\n logger(`Created encryption map for ${spec.entityId}`)\n }\n}\n\nconst seedEncryptionMaps: ModuleCli = {\n command: 'seed-encryption',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantId = (args.tenant as string) || (args.tenantId as string)\n const organizationId = (args.org as string) || (args.organization as string) || (args.organizationId as string) || null\n\n if (!tenantId) {\n console.error('tenant id is required (use --tenant <uuid>)')\n return\n }\n if (!isTenantDataEncryptionEnabled()) {\n console.warn('TENANT_DATA_ENCRYPTION is disabled; skipping encryption map seeding.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n const logger = (msg: string) => console.log(msg)\n await upsertEncryptionMaps(em, tenantId, organizationId, logger)\n console.log('\u2705 Encryption maps seeded')\n },\n}\n\nfunction normalizeKeyInput(value: string): string {\n return value.trim().replace(/(?:^['\"]|['\"]$)/g, '')\n}\n\nclass DerivedKeyKmsService implements KmsService {\n private root: Buffer\n constructor(secret: string) {\n this.root = crypto.createHash('sha256').update(normalizeKeyInput(secret)).digest()\n }\n\n isHealthy(): boolean {\n return true\n }\n\n private deriveKey(tenantId: string): string {\n const iterations = 310_000\n const keyLength = 32\n const derived = crypto.pbkdf2Sync(this.root, tenantId, iterations, keyLength, 'sha512')\n return derived.toString('base64')\n }\n\n async getTenantDek(tenantId: string): Promise<TenantDek | null> {\n if (!tenantId) return null\n return { tenantId, key: this.deriveKey(tenantId), fetchedAt: Date.now() }\n }\n\n async createTenantDek(tenantId: string): Promise<TenantDek | null> {\n return this.getTenantDek(tenantId)\n }\n}\n\nfunction fingerprintDek(dek: TenantDek | null): string | null {\n if (!dek?.key) return null\n return crypto.createHash('sha256').update(dek.key).digest('hex').slice(0, 12)\n}\n\nfunction decryptWithOldKey(\n payload: string,\n dek: TenantDek | null,\n): string | null {\n if (!dek?.key) return null\n return decryptWithAesGcm(payload, dek.key)\n}\n\nfunction resolveProperty(meta: any, field: string): { columnName: string | null; prop: any | null } {\n if (!meta?.properties) return { columnName: null, prop: null }\n const candidates = [\n field,\n field.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),\n field.replace(/([A-Z])/g, '_$1').toLowerCase(),\n ]\n for (const candidate of candidates) {\n const prop = meta.properties[candidate]\n const fieldName =\n prop?.fieldName ??\n (Array.isArray(prop?.fieldNames) && prop.fieldNames.length ? prop.fieldNames[0] : undefined)\n if (typeof fieldName === 'string' && fieldName.length) return { columnName: fieldName, prop }\n if (prop?.name) return { columnName: prop.name, prop }\n }\n return { columnName: null, prop: null }\n}\n\nfunction buildEntityMetaRegistry(em: any): Map<string, any> {\n const registry = em?.getMetadata?.()\n const allMetaRaw = typeof registry?.getAll === 'function' ? registry.getAll() : []\n const allMeta = Array.isArray(allMetaRaw) ? allMetaRaw : Object.values(allMetaRaw ?? {})\n const metaByEntityId = new Map<string, any>()\n for (const meta of allMeta) {\n const resolved = resolveEntityIdFromMetadata(meta)\n if (resolved) metaByEntityId.set(resolved, meta)\n }\n return metaByEntityId\n}\n\ninterface EncryptionMapMeta {\n entityId: string\n meta: any\n fields: Array<{ field: string; hashField?: string | null }>\n tenantId: string\n}\n\nfunction resolveMapMeta(\n map: EncryptionMap,\n metaByEntityId: Map<string, any>,\n warn: (msg: string) => void = () => {},\n): EncryptionMapMeta | null {\n const entityId = String(map.entityId)\n const meta = metaByEntityId.get(entityId)\n if (!meta) {\n warn(`Skipping ${entityId}: metadata not found.`)\n return null\n }\n const fields = Array.isArray(map.fieldsJson) ? map.fieldsJson : []\n if (!fields.length) return null\n const tenantId = map.tenantId ? String(map.tenantId) : null\n if (!tenantId) return null\n return { entityId, meta, fields, tenantId }\n}\n\nconst rotateEncryptionKey: ModuleCli = {\n command: 'rotate-encryption-key',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string) || null\n const organizationIdArg = (args.org as string) || (args.organization as string) || (args.organizationId as string) || null\n const oldKey = (args['old-key'] as string) || (args.oldKey as string) || null\n const dryRun = Boolean(args['dry-run'] || args.dry)\n const debug = Boolean(args.debug)\n const rotate = Boolean(oldKey)\n if (rotate && !tenantIdArg) {\n console.warn(\n '\u26A0\uFE0F Rotating with --old-key across all tenants. A single old key should normally target one tenant; consider --tenant.',\n )\n }\n if (!isTenantDataEncryptionEnabled()) {\n console.error('TENANT_DATA_ENCRYPTION is disabled; aborting.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n const conn: any = em?.getConnection?.()\n if (!conn || typeof conn.execute !== 'function') {\n console.error('Unable to access raw connection; aborting.')\n return\n }\n\n const encryptionService = new TenantDataEncryptionService(em as any, { kms: createKmsService() })\n const oldKms = rotate && oldKey ? new DerivedKeyKmsService(oldKey) : null\n if (!encryptionService.isEnabled()) {\n console.error('Encryption service is not enabled (KMS unhealthy or no DEK). Aborting.')\n return\n }\n\n if (debug) {\n console.log('[rotate-encryption-key]', {\n hasOldKey: Boolean(oldKey),\n rotate,\n tenantId: tenantIdArg ?? null,\n organizationId: organizationIdArg ?? null,\n })\n if (tenantIdArg) {\n const [oldDek, newDek] = await Promise.all([\n oldKms?.getTenantDek(tenantIdArg) ?? Promise.resolve(null),\n encryptionService.getDek(tenantIdArg),\n ])\n console.log('[rotate-encryption-key] dek fingerprints', {\n oldKey: fingerprintDek(oldDek),\n currentKey: fingerprintDek(newDek),\n })\n } else {\n console.log('[rotate-encryption-key] dek fingerprints skipped (no tenantId)')\n }\n }\n\n const isEncryptedPayload = (value: unknown): boolean => {\n if (typeof value !== 'string') return false\n const parts = value.split(':')\n return parts.length === 4 && parts[3] === 'v1'\n }\n\n const metaByEntityId = buildEntityMetaRegistry(em)\n\n const where: any = { deletedAt: null }\n if (tenantIdArg) where.tenantId = tenantIdArg\n if (organizationIdArg) where.organizationId = organizationIdArg\n const maps = await em.find(EncryptionMap, where)\n if (!maps.length) {\n console.log('No encryption maps found for the selected scope.')\n return\n }\n\n const formatValueForColumn = (prop: any, value: unknown): unknown => {\n if (value === null || value === undefined) return value\n const types = Array.isArray(prop?.columnTypes) ? prop.columnTypes : []\n const type = String(prop?.type ?? '').toLowerCase()\n const isJson = types.some((entry: string) => entry.toLowerCase().includes('json')) || type === 'json' || type === 'jsonb'\n if (!isJson) return value\n return JSON.stringify(value)\n }\n\n const resolveScopes = async (tenantId: string, organizationId: string | null) => {\n if (organizationId) return [{ tenantId, organizationId }]\n const orgs = await em.find(Organization, { tenant: tenantId })\n const scopes = orgs.map((org: Organization) => ({\n tenantId,\n organizationId: String(org.id),\n }))\n scopes.push({ tenantId, organizationId: null })\n return scopes\n }\n\n const oldDekCache = new Map<string, TenantDek | null>()\n const processScope = async (\n entityId: string,\n meta: any,\n fields: Array<{ field: string; hashField?: string | null }>,\n scope: { tenantId: string; organizationId: string | null },\n ): Promise<number> => {\n const pk = Array.isArray(meta?.primaryKeys) && meta.primaryKeys.length ? meta.primaryKeys[0] : 'id'\n const columns = new Set<string>()\n columns.add(pk)\n for (const rule of fields) {\n const resolved = resolveProperty(meta, rule.field)\n if (resolved?.columnName) columns.add(resolved.columnName)\n if (rule.hashField) {\n const resolvedHash = resolveProperty(meta, rule.hashField)\n if (resolvedHash?.columnName) columns.add(resolvedHash.columnName)\n }\n }\n const columnList = Array.from(columns)\n if (!columnList.length) return 0\n const tableName = meta?.tableName\n if (!tableName) return 0\n const schema = meta?.schema\n const qualifiedTable = schema ? `\"${schema}\".\"${tableName}\"` : `\"${tableName}\"`\n const selectSql = `select ${columnList.map((c) => `\"${c}\"`).join(', ')} from ${qualifiedTable} where tenant_id = ? and organization_id is not distinct from ?`\n const rows = await conn.execute(selectSql, [scope.tenantId, scope.organizationId])\n const list = Array.isArray(rows) ? rows : []\n if (!list.length) return 0\n let updated = 0\n for (const row of list) {\n const payload: Record<string, unknown> = {}\n for (const rule of fields) {\n const resolved = resolveProperty(meta, rule.field)\n const col = resolved?.columnName\n if (!col) continue\n const rawValue = row[col]\n if (rotate && !isEncryptedPayload(rawValue)) {\n continue\n }\n payload[rule.field] = rawValue\n if (rule.hashField) {\n const resolvedHash = resolveProperty(meta, rule.hashField)\n const hashCol = resolvedHash?.columnName\n if (hashCol) payload[rule.hashField] = row[hashCol]\n }\n }\n if (rotate && !Object.keys(payload).length) {\n continue\n }\n if (rotate && oldKms) {\n let oldDek = oldDekCache.get(scope.tenantId) ?? null\n if (!oldDekCache.has(scope.tenantId)) {\n oldDek = await oldKms.getTenantDek(scope.tenantId)\n oldDekCache.set(scope.tenantId, oldDek)\n }\n for (const rule of fields) {\n const value = payload[rule.field]\n if (typeof value !== 'string' || !isEncryptedPayload(value)) continue\n const decrypted = decryptWithOldKey(value, oldDek)\n if (decrypted === null) continue\n try {\n payload[rule.field] = JSON.parse(decrypted)\n } catch {\n payload[rule.field] = decrypted\n }\n }\n }\n const encrypted = await encryptionService.encryptEntityPayload(\n entityId,\n payload,\n scope.tenantId,\n scope.organizationId,\n )\n const updates: Record<string, unknown> = {}\n for (const rule of fields) {\n const resolved = resolveProperty(meta, rule.field)\n const col = resolved?.columnName\n if (!col) continue\n const nextValue = (encrypted as any)[rule.field]\n if (nextValue !== undefined && nextValue !== row[col]) {\n if (!rotate && isEncryptedPayload(row[col])) continue\n updates[col] = formatValueForColumn(resolved?.prop, nextValue)\n }\n if (rule.hashField) {\n const resolvedHash = resolveProperty(meta, rule.hashField)\n const hashCol = resolvedHash?.columnName\n const hashValue = (encrypted as any)[rule.hashField]\n if (hashCol && hashValue !== undefined && hashValue !== row[hashCol]) {\n updates[hashCol] = formatValueForColumn(resolvedHash?.prop, hashValue)\n }\n }\n }\n if (!Object.keys(updates).length) continue\n if (!dryRun) {\n const setSql = Object.keys(updates).map((col) => `\"${col}\" = ?`).join(', ')\n await conn.execute(\n `update ${qualifiedTable} set ${setSql} where \"${pk}\" = ?`,\n [...Object.values(updates), row[pk]],\n )\n }\n updated += 1\n }\n return updated\n }\n\n let total = 0\n for (const map of maps) {\n const mapMeta = resolveMapMeta(map, metaByEntityId, console.warn)\n if (!mapMeta) continue\n const { entityId, meta, fields, tenantId } = mapMeta\n const scopes = await resolveScopes(tenantId, map.organizationId ? String(map.organizationId) : null)\n for (const scope of scopes) {\n const updated = await processScope(entityId, meta, fields, scope)\n if (updated > 0) {\n console.log(\n `${dryRun ? '[dry-run] ' : ''}Encrypted ${updated} record(s) for ${entityId} org=${scope.organizationId ?? 'null'}`\n )\n }\n total += updated\n }\n }\n\n if (total > 0) {\n console.log(`Encrypted ${total} record(s) across mapped entities.`)\n } else {\n console.log('All mapped entity fields already encrypted for the selected scope.')\n }\n },\n}\n\nconst decryptDatabase: ModuleCli = {\n command: 'decrypt-database',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string) || null\n const organizationIdArg = (args.org as string) || (args.organization as string) || (args.organizationId as string) || null\n const entityIdArg = (args.entity as string) || null\n const checkMode = Boolean(args.check)\n const dryRun = Boolean(args['dry-run'] || args.dry) || checkMode\n const deactivateMaps = Boolean(args['deactivate-maps'])\n const confirm = (args.confirm as string) || null\n const batchSize = Math.max(1, parseInt(String(args['batch-size'] || args.batchSize || '500'), 10) || 500)\n const sleepMs = Math.max(0, parseInt(String(args['sleep-ms'] || args.sleepMs || '0'), 10) || 0)\n const debug = Boolean(args.debug)\n\n if (!tenantIdArg) {\n console.error('--tenant <uuid> is required.')\n return\n }\n\n if (!checkMode) {\n if (!confirm) {\n console.error('--confirm <tenantUuid> is required (safety gate). Pass the exact tenant UUID to confirm the operation.')\n return\n }\n if (confirm !== tenantIdArg) {\n console.error(`--confirm value \"${confirm}\" does not match --tenant \"${tenantIdArg}\". Aborting.`)\n return\n }\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n const conn: any = em?.getConnection?.()\n if (!conn || typeof conn.execute !== 'function') {\n console.error('Unable to access raw database connection; aborting.')\n return\n }\n\n if (!checkMode && !isTenantDataEncryptionEnabled()) {\n console.error('TENANT_DATA_ENCRYPTION is disabled; aborting. Data may already be decrypted.')\n return\n }\n\n const metaByEntityId = buildEntityMetaRegistry(em)\n\n const resolveDecryptScopes = async (\n tenantId: string,\n organizationId: string | null,\n ): Promise<Array<{ tenantId: string; organizationId: string | null }>> => {\n if (organizationId) return [{ tenantId, organizationId }]\n const rows = await conn.execute(\n `SELECT DISTINCT organization_id FROM encryption_maps WHERE tenant_id = ? AND deleted_at IS NULL`,\n [tenantId],\n )\n const orgIds = new Set<string | null>()\n for (const row of Array.isArray(rows) ? rows : []) {\n orgIds.add(row.organization_id ?? null)\n }\n orgIds.add(null)\n return Array.from(orgIds).map((orgId) => ({ tenantId, organizationId: orgId }))\n }\n\n const mapWhere: any = { tenantId: tenantIdArg, deletedAt: null, isActive: true }\n if (organizationIdArg) mapWhere.organizationId = organizationIdArg\n if (entityIdArg) mapWhere.entityId = entityIdArg\n const maps = await em.find(EncryptionMap, mapWhere)\n\n if (!maps.length) {\n console.log('No active encryption maps found for the selected scope.')\n return\n }\n\n const kms = createKmsService()\n const dekCache = new Map<string, TenantDek | null>()\n const getDek = async (tenantId: string): Promise<TenantDek | null> => {\n if (dekCache.has(tenantId)) return dekCache.get(tenantId) ?? null\n const dek = await kms.getTenantDek(tenantId)\n dekCache.set(tenantId, dek)\n return dek\n }\n\n if (checkMode) {\n const envValue = process.env.TENANT_DATA_ENCRYPTION ?? '(not set)'\n console.log(`TENANT_DATA_ENCRYPTION = ${envValue}`)\n console.log(`Active EncryptionMap records for scope: ${maps.length}`)\n let encryptedCandidatesSampled = 0\n let malformedPayloadCountSampled = 0\n for (const map of maps) {\n const mapMeta = resolveMapMeta(map, metaByEntityId)\n if (!mapMeta) continue\n const { entityId, meta, fields, tenantId } = mapMeta\n const dek = await getDek(tenantId).catch(() => null)\n if (!dek) continue\n const scopes = await resolveDecryptScopes(tenantId, map.organizationId ? String(map.organizationId) : null)\n const pk = Array.isArray(meta?.primaryKeys) && meta.primaryKeys.length ? meta.primaryKeys[0] : 'id'\n const tableName = meta?.tableName\n if (!tableName) continue\n const schema = meta?.schema\n const qualifiedTable = schema ? `\"${schema}\".\"${tableName}\"` : `\"${tableName}\"`\n const fieldCols = fields.flatMap((f: any) => {\n const r = resolveProperty(meta, f.field)\n return r.columnName ? [r.columnName] : []\n })\n const colList = Array.from(new Set([pk, ...fieldCols]))\n for (const scope of scopes) {\n const sampleRows = await conn.execute(\n `SELECT ${colList.map((c: string) => `\"${c}\"`).join(', ')} FROM ${qualifiedTable} WHERE tenant_id = ? AND organization_id IS NOT DISTINCT FROM ? LIMIT 100`,\n [scope.tenantId, scope.organizationId],\n ).catch(() => [])\n for (const row of Array.isArray(sampleRows) ? sampleRows : []) {\n let rowHasEncrypted = false\n for (const fieldRule of fields) {\n const resolved = resolveProperty(meta, fieldRule.field)\n const col = resolved?.columnName\n if (!col) continue\n const rawValue = row[col]\n if (rawValue === null || rawValue === undefined) continue\n try {\n decryptWithAesGcmStrict(String(rawValue), dek.key)\n rowHasEncrypted = true\n } catch (e: any) {\n if (e instanceof TenantDataEncryptionError && e.code === TenantDataEncryptionErrorCode.MALFORMED_PAYLOAD) {\n malformedPayloadCountSampled++\n }\n }\n }\n if (rowHasEncrypted) encryptedCandidatesSampled++\n }\n }\n }\n console.log(`estimated encrypted candidates (sampled): ${encryptedCandidatesSampled}`)\n if (malformedPayloadCountSampled > 0) {\n console.warn(`\u26A0 malformed payloads (sampled): ${malformedPayloadCountSampled} \u2014 may indicate corruption`)\n } else {\n console.log(`malformed payloads (sampled): ${malformedPayloadCountSampled}`)\n }\n console.log('not a proof of absence \u2014 run full command + rerun --check to confirm')\n return\n }\n\n let totalRowsFetched = 0\n let totalRowsUpdated = 0\n let totalHashFieldsCleared = 0\n const totalHashFieldsSkipped = new Set<string>()\n let totalMalformedPayloadCount = 0\n const malformedByLocation = new Map<string, number>()\n let totalEntitiesProcessed = 0\n\n for (const map of maps) {\n const mapMeta = resolveMapMeta(map, metaByEntityId, console.warn)\n if (!mapMeta) continue\n const { entityId, meta, fields, tenantId } = mapMeta\n const dek = await getDek(tenantId)\n if (!dek) {\n console.warn(`No DEK available for tenant ${tenantId}; skipping ${entityId}.`)\n continue\n }\n const pk = Array.isArray(meta?.primaryKeys) && meta.primaryKeys.length ? meta.primaryKeys[0] : 'id'\n const tableName = meta?.tableName\n if (!tableName) {\n console.warn(`Skipping ${entityId}: table name not found.`)\n continue\n }\n const schema = meta?.schema\n const qualifiedTable = schema ? `\"${schema}\".\"${tableName}\"` : `\"${tableName}\"`\n const fieldCols = fields.flatMap((f: any) => {\n const r = resolveProperty(meta, f.field)\n return r.columnName ? [r.columnName] : []\n })\n const colList = Array.from(new Set([pk, ...fieldCols]))\n totalEntitiesProcessed++\n\n const scopes = await resolveDecryptScopes(tenantId, map.organizationId ? String(map.organizationId) : null)\n\n for (const scope of scopes) {\n let lastId: string | null = null\n let scopeMalformedCount = 0\n\n while (true) {\n let selectSql = `SELECT ${colList.map((c: string) => `\"${c}\"`).join(', ')} FROM ${qualifiedTable} WHERE tenant_id = ? AND organization_id IS NOT DISTINCT FROM ?`\n const selectParams: unknown[] = [scope.tenantId, scope.organizationId]\n if (lastId !== null) {\n selectSql += ` AND \"${pk}\" > ?`\n selectParams.push(lastId)\n }\n selectSql += ` ORDER BY \"${pk}\" LIMIT ?`\n selectParams.push(batchSize)\n\n const batchRows = await conn.execute(selectSql, selectParams)\n const batch = Array.isArray(batchRows) ? batchRows : []\n if (!batch.length) break\n\n lastId = String(batch[batch.length - 1]![pk])\n totalRowsFetched += batch.length\n\n const batchStart = Date.now()\n await conn.execute('BEGIN')\n let batchCommitted = false\n try {\n for (const row of batch) {\n const updates: Record<string, unknown> = {}\n let rowDecrypted = false\n\n for (const fieldRule of fields) {\n const resolved = resolveProperty(meta, fieldRule.field)\n const col = resolved?.columnName\n if (!col) continue\n const rawValue = row[col]\n if (rawValue === null || rawValue === undefined) continue\n try {\n const decrypted = decryptWithAesGcmStrict(String(rawValue), dek.key)\n let valueToWrite: string\n try {\n const parsed = JSON.parse(decrypted)\n valueToWrite = typeof parsed === 'string' ? parsed : decrypted\n } catch {\n valueToWrite = decrypted\n }\n updates[col] = valueToWrite\n rowDecrypted = true\n } catch (e: any) {\n if (e instanceof TenantDataEncryptionError) {\n if (e.code === TenantDataEncryptionErrorCode.AUTH_FAILED) {\n // Value is plaintext \u2014 skip silently\n } else if (e.code === TenantDataEncryptionErrorCode.MALFORMED_PAYLOAD) {\n scopeMalformedCount++\n const locationKey = `${tableName}:${col}`\n malformedByLocation.set(locationKey, (malformedByLocation.get(locationKey) ?? 0) + 1)\n console.warn(`\u26A0 MALFORMED_PAYLOAD for ${entityId} field \"${col}\" row ${row[pk]}; skipping field.`)\n } else {\n throw e\n }\n } else {\n throw e\n }\n }\n }\n\n if (rowDecrypted) {\n for (const fieldRule of fields) {\n if (!fieldRule.hashField) continue\n const resolvedHash = resolveProperty(meta, fieldRule.hashField)\n const hashCol = resolvedHash?.columnName\n if (!hashCol) {\n const skippedKey = `${tableName}:${fieldRule.hashField}`\n if (!totalHashFieldsSkipped.has(skippedKey)) {\n console.warn(`\u26A0 Hash column \"${fieldRule.hashField}\" not found in metadata for ${entityId}; skipping.`)\n totalHashFieldsSkipped.add(skippedKey)\n }\n continue\n }\n updates[hashCol] = null\n totalHashFieldsCleared++\n }\n }\n\n if (Object.keys(updates).length > 0) {\n if (!dryRun) {\n const setSql = Object.keys(updates).map((col) => `\"${col}\" = ?`).join(', ')\n await conn.execute(\n `UPDATE ${qualifiedTable} SET ${setSql} WHERE \"${pk}\" = ?`,\n [...Object.values(updates), row[pk]],\n )\n }\n totalRowsUpdated++\n }\n }\n await conn.execute('COMMIT')\n batchCommitted = true\n } catch (fatalErr: any) {\n if (!batchCommitted) {\n try { await conn.execute('ROLLBACK') } catch {}\n }\n console.error(`Fatal error during batch processing for ${entityId}: ${(fatalErr as Error)?.message || String(fatalErr)}`)\n throw fatalErr\n }\n\n const batchDurationMs = Date.now() - batchStart\n if (debug) {\n console.log(\n `[debug] Batch ${entityId} org=${scope.organizationId ?? 'null'}: ${batch.length} rows in ${batchDurationMs}ms, scopeMalformed=${scopeMalformedCount}`,\n )\n if (batchDurationMs > 30_000) {\n console.warn('\u26A0 Batch took >30s; consider reducing --batch-size.')\n }\n }\n if (sleepMs > 0) {\n await new Promise<void>((r) => setTimeout(r, sleepMs))\n }\n }\n\n totalMalformedPayloadCount += scopeMalformedCount\n }\n }\n\n if (deactivateMaps && !dryRun) {\n let deactivateSql = `UPDATE encryption_maps SET is_active = false, deleted_at = now() WHERE tenant_id = ? AND deleted_at IS NULL`\n const deactivateParams: unknown[] = [tenantIdArg]\n if (organizationIdArg) {\n deactivateSql += ` AND (organization_id = ? OR organization_id IS NULL)`\n deactivateParams.push(organizationIdArg)\n }\n if (entityIdArg) {\n deactivateSql += ` AND entity_id = ?`\n deactivateParams.push(entityIdArg)\n }\n await conn.execute(deactivateSql, deactivateParams)\n console.warn('\u26A0 Restart all application replicas \u2014 in-process map caches may still be active.')\n if (isTenantDataEncryptionEnabled()) {\n console.warn('\u26A0 Env TENANT_DATA_ENCRYPTION is still true \u2014 new writes will be re-encrypted until env is updated and replicas restarted.')\n }\n }\n\n if (deactivateMaps && dryRun) {\n console.log(`[dry-run] Would deactivate ${maps.length} EncryptionMap record(s).`)\n }\n\n const prefix = dryRun ? '[dry-run] ' : ''\n console.log(`\\n${prefix}Decryption summary:`)\n console.log(` Rows fetched: ${totalRowsFetched}`)\n console.log(` Rows updated: ${totalRowsUpdated}`)\n console.log(` Entities processed: ${totalEntitiesProcessed}`)\n console.log(` Hash fields cleared: ${totalHashFieldsCleared}`)\n if (totalHashFieldsSkipped.size > 0) {\n console.log(` Hash fields skipped (missing columns): ${Array.from(totalHashFieldsSkipped).join(', ')}`)\n }\n if (totalMalformedPayloadCount > 0) {\n console.warn(\n ` \u26A0 ${totalMalformedPayloadCount} field value(s) returned MALFORMED_PAYLOAD and were skipped; these may be corrupted ciphertexts. Investigate before assuming decryption is complete.`,\n )\n if (debug && malformedByLocation.size > 0) {\n const top = Array.from(malformedByLocation.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n console.log(' Top malformed locations:')\n for (const [loc, count] of top) {\n console.log(` ${loc}: ${count}`)\n }\n }\n }\n\n if (!dryRun) {\n console.log(`\\n\u2705 Decryption complete. Required next steps:`)\n console.log(` 1. Set TENANT_DATA_ENCRYPTION=false in your environment / secrets`)\n console.log(` 2. Restart all application replicas`)\n console.log(` 3. Run: mercato query_index reindex --tenant ${tenantIdArg} \u2190 run after env flip + restart; search/filter degraded until this completes`)\n console.log(` 4. Run: mercato entities decrypt-database --tenant ${tenantIdArg} --check to confirm no encrypted values remain`)\n console.log(` NOTE: if the run was long and concurrent inserts occurred, run again before step 4 \u2014 it is idempotent.`)\n }\n },\n}\n\n// Keep default export stable (install first for help listing)\nexport default [seedDefs, reinstallDefs, addField, seedEncryptionMaps, rotateEncryptionKey, decryptDatabase]\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { getCliModules, getDefaultEncryptionMaps, type Module, type ModuleCli } from '@open-mercato/shared/modules/registry'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { CacheStrategy } from '@open-mercato/cache/types'\nimport { CustomEntity, CustomFieldDef, EncryptionMap } from './data/entities'\nimport {\n installCustomEntitiesFromModules,\n getAggregatedCustomEntityConfigs,\n} from './lib/install-from-ce'\nimport readline from 'node:readline/promises'\nimport { stdin as input, stdout as output } from 'node:process'\nimport { isTenantDataEncryptionEnabled } from '@open-mercato/shared/lib/encryption/toggles'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport { createKmsService, type KmsService, type TenantDek } from '@open-mercato/shared/lib/encryption/kms'\nimport {\n decryptWithAesGcm,\n decryptWithAesGcmStrict,\n TenantDataEncryptionError,\n TenantDataEncryptionErrorCode,\n} from '@open-mercato/shared/lib/encryption/aes'\nimport {\n TenantDataEncryptionService,\n parseDecryptedFieldValue,\n} from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'\nimport { resolveEntityIdFromMetadata } from '@open-mercato/shared/lib/encryption/entityIds'\nimport { Organization } from '../directory/data/entities'\nimport crypto from 'node:crypto'\n\nfunction parseArgs(rest: string[]) {\n const args: Record<string, string | boolean> = {}\n for (let i = 0; i < rest.length; i++) {\n const a = rest[i]\n if (!a) continue\n if (a.startsWith('--')) {\n const [k, v] = a.replace(/^--/, '').split('=')\n if (v !== undefined) args[k] = v\n else if (rest[i + 1] && !rest[i + 1]!.startsWith('--')) { args[k] = rest[i + 1]!; i++ }\n else args[k] = true\n }\n }\n return args\n}\n\nconst seedDefs: ModuleCli = {\n command: 'install',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string)\n const globalOnly = Boolean(args.global)\n const dry = Boolean(args['dry-run'] || args.dry)\n const force = Boolean(args.force)\n const includeGlobal = args['no-global'] ? false : true\n\n if (globalOnly && includeGlobal === false) {\n console.error('Cannot combine --global with --no-global.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n let cache: CacheStrategy | null = null\n try { cache = resolve('cache') as CacheStrategy } catch {}\n\n const tenantIds = tenantIdArg\n ? [tenantIdArg]\n : (globalOnly ? [] : undefined)\n\n const logger = (message: string) => {\n const prefix = dry ? '[dry-run] ' : ''\n console.log(`${prefix}${message}`)\n }\n\n const result = await installCustomEntitiesFromModules(em, cache, {\n tenantIds,\n includeGlobal,\n dryRun: dry,\n force,\n logger,\n })\n const label = dry ? 'Dry-run' : 'Sync'\n console.log(`\u2705 ${label} complete: processed=${result.processed}, updated=${result.synchronized}, fieldsChanged=${result.fieldChanges}, skipped=${result.skipped}`)\n },\n}\n\n// Reinstall: remove existing definitions for target scope and re-seed from modules\nconst reinstallDefs: ModuleCli = {\n command: 'reinstall',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string)\n const globalOnly = Boolean(args.global)\n const dry = Boolean(args['dry-run'] || args.dry)\n const includeGlobal = globalOnly ? true : (args['no-global'] ? false : true)\n\n if (globalOnly && includeGlobal === false) {\n console.error('Cannot combine --global with --no-global.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n let cache: CacheStrategy | null = null\n try { cache = resolve('cache') as CacheStrategy } catch {}\n\n const tenantIds = tenantIdArg\n ? [tenantIdArg]\n : (globalOnly ? [] : undefined)\n\n const aggregates = getAggregatedCustomEntityConfigs()\n const relevant = aggregates.filter((entry) => (globalOnly ? entry.spec?.global === true : true))\n if (!relevant.length) {\n console.log('No custom entities or fields discovered. Nothing to reinstall.')\n return\n }\n const entityIds = Array.from(new Set(relevant.map((entry) => entry.entityId)))\n if (!entityIds.length) {\n console.log('No entity ids discovered. Nothing to reinstall.')\n return\n }\n\n const logger = (message: string) => {\n const prefix = dry ? '[dry-run] ' : ''\n console.log(`${prefix}${message}`)\n }\n\n if (dry) {\n console.log('Dry-run: would remove existing custom entity definitions before reinstall.')\n } else {\n const fieldWhere: any = { entityId: { $in: entityIds } }\n if (tenantIds !== undefined) {\n if (tenantIds.length === 0) fieldWhere.tenantId = null\n else fieldWhere.tenantId = { $in: tenantIds }\n }\n const removedFields = await em.nativeDelete(CustomFieldDef, fieldWhere)\n\n const entityWhere: any = { entityId: { $in: entityIds } }\n if (tenantIds !== undefined) {\n if (tenantIds.length === 0) entityWhere.tenantId = null\n else entityWhere.tenantId = { $in: tenantIds }\n }\n const removedEntities = await em.nativeDelete(CustomEntity, entityWhere)\n\n if (cache && entityIds.length) {\n try {\n await cache.deleteByTags(entityIds.map((id) => `custom-entity:${id}`))\n } catch {}\n }\n console.log(`Cleared definitions: fields=${removedFields}, entities=${removedEntities}`)\n }\n\n const result = await installCustomEntitiesFromModules(em, cache, {\n tenantIds,\n includeGlobal,\n dryRun: dry,\n force: true,\n logger,\n })\n const label = dry ? 'Dry-run' : 'Reinstall'\n console.log(`\u2705 ${label} complete: processed=${result.processed}, updated=${result.synchronized}, fieldsChanged=${result.fieldChanges}, skipped=${result.skipped}`)\n },\n}\n\n// Interactive: add a single custom field definition\nconst addField: ModuleCli = {\n command: 'add-field',\n async run(rest) {\n const args = parseArgs(rest)\n const rl = readline.createInterface({ input, output })\n const ask = async (q: string, d?: string) => {\n const a = (await rl.question(d ? `${q} [${d}]: ` : `${q}: `)).trim()\n return a || (d ?? '')\n }\n const askBool = async (q: string, d = false) => {\n const a = (await ask(q, d ? 'y' : 'n')).toLowerCase()\n return parseBooleanToken(a) === true\n }\n\n try {\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n\n const entityId = (args.entity as string) || (args.e as string) || await ask('Entity ID (e.g., example:todo)')\n const isGlobal = args.global ? true : await askBool('Global (no organization)?', false)\n const orgId = isGlobal ? null : ((args.org as string) || (args.organizationId as string) || await ask('Organization ID'))\n const tenantId = isGlobal ? null : ((args.tenant as string) || (args.tenantId as string) || await ask('Tenant ID'))\n const key = (args.key as string) || await ask('Field key (snake_case)')\n let kind = (args.kind as string) || await ask(\"Kind (text|multiline|integer|float|boolean|select|currency|relation|attachment)\", 'text')\n kind = kind.toLowerCase()\n if (!['text','multiline','integer','float','boolean','select','currency','relation','attachment'].includes(kind)) throw new Error('Invalid kind')\n const label = (args.label as string) || (await ask('Label', key))\n const description = (args.description as string) || ''\n const required = args.required !== undefined ? Boolean(args.required) : await askBool('Required?', false)\n const multi = args.multi !== undefined ? Boolean(args.multi) : await askBool('Allow multiple?', false)\n let options: string[] | undefined\n if (kind === 'select') {\n const raw = (args.options as string) || await ask('Options (comma-separated)', 'low,medium,high')\n options = raw.split(',').map((s) => s.trim()).filter(Boolean)\n }\n let defaultValue: any = undefined\n const defRaw = (args.default as string) ?? (args.defaultValue as string)\n const needDefault = defRaw !== undefined ? defRaw : await ask('Default value (leave empty for none)', '')\n if (needDefault !== '') {\n switch (kind) {\n case 'integer': defaultValue = Number(needDefault); break\n case 'float': defaultValue = Number(needDefault); break\n case 'boolean': defaultValue = parseBooleanToken(String(needDefault)) === true; break\n default: defaultValue = String(needDefault)\n }\n }\n const filterable = args.filterable !== undefined ? Boolean(args.filterable) : await askBool('Filterable?', true)\n const listVisible = args.listVisible !== undefined ? Boolean(args.listVisible) : await askBool('Visible in list?', true)\n const formEditable = args.formEditable !== undefined ? Boolean(args.formEditable) : await askBool('Editable in forms?', true)\n const indexed = args.indexed !== undefined ? Boolean(args.indexed) : await askBool('Indexed?', false)\n\n const where = { entityId, organizationId: orgId, tenantId: tenantId, key }\n const existing = await em.findOne(CustomFieldDef, where)\n const configJson: any = {}\n if (options) configJson.options = options\n if (defaultValue !== undefined) configJson.defaultValue = defaultValue\n if (required !== undefined) configJson.required = required\n if (multi !== undefined) configJson.multi = multi\n if (filterable !== undefined) configJson.filterable = filterable\n if (indexed !== undefined) configJson.indexed = indexed\n if (listVisible !== undefined) configJson.listVisible = listVisible\n if (formEditable !== undefined) configJson.formEditable = formEditable\n if (label !== undefined) configJson.label = label\n if (description !== undefined) configJson.description = description\n\n if (!existing) {\n await em.persist(em.create(CustomFieldDef, {\n entityId,\n organizationId: orgId,\n tenantId: tenantId,\n key,\n kind,\n configJson,\n isActive: true,\n })).flush()\n console.log(`Created custom field: ${entityId}.${key} (${kind})${orgId == null ? ' [global]' : ` [org=${orgId}, tenant=${tenantId}]`}`)\n } else {\n existing.kind = kind as any\n existing.configJson = configJson\n existing.isActive = true\n await em.flush()\n console.log(`Updated custom field: ${entityId}.${key} (${kind})${orgId == null ? ' [global]' : ` [org=${orgId}, tenant=${tenantId}]`}`)\n }\n } catch (e: any) {\n console.error('Failed:', e?.message || e)\n } finally {\n await rl.close()\n }\n },\n}\n\nfunction resolveEncryptionMapModules(): Module[] {\n const cliModules = getCliModules()\n if (cliModules.length > 0) return cliModules\n try {\n const { getModules } = require('@open-mercato/shared/lib/modules/registry')\n return getModules()\n } catch {\n return []\n }\n}\n\nasync function upsertEncryptionMaps(em: any, tenantId: string, organizationId: string | null, logger: (msg: string) => void) {\n for (const spec of getDefaultEncryptionMaps(resolveEncryptionMapModules())) {\n const existing = await em.findOne(EncryptionMap, {\n entityId: spec.entityId,\n tenantId,\n organizationId,\n deletedAt: null,\n })\n if (existing) {\n existing.fieldsJson = spec.fields\n existing.isActive = true\n existing.updatedAt = new Date()\n logger(`\uD83D\uDD12 Updated encryption map for ${spec.entityId} \u2728`)\n await em.persist(existing).flush()\n continue\n }\n const map = em.create(EncryptionMap, {\n entityId: spec.entityId,\n tenantId,\n organizationId,\n fieldsJson: spec.fields,\n isActive: true,\n })\n await em.persist(map).flush()\n logger(`Created encryption map for ${spec.entityId}`)\n }\n}\n\nconst seedEncryptionMaps: ModuleCli = {\n command: 'seed-encryption',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantId = (args.tenant as string) || (args.tenantId as string)\n const organizationId = (args.org as string) || (args.organization as string) || (args.organizationId as string) || null\n\n if (!tenantId) {\n console.error('tenant id is required (use --tenant <uuid>)')\n return\n }\n if (!isTenantDataEncryptionEnabled()) {\n console.warn('TENANT_DATA_ENCRYPTION is disabled; skipping encryption map seeding.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n const logger = (msg: string) => console.log(msg)\n await upsertEncryptionMaps(em, tenantId, organizationId, logger)\n console.log('\u2705 Encryption maps seeded')\n },\n}\n\nfunction normalizeKeyInput(value: string): string {\n return value.trim().replace(/(?:^['\"]|['\"]$)/g, '')\n}\n\nclass DerivedKeyKmsService implements KmsService {\n private root: Buffer\n constructor(secret: string) {\n this.root = crypto.createHash('sha256').update(normalizeKeyInput(secret)).digest()\n }\n\n isHealthy(): boolean {\n return true\n }\n\n private deriveKey(tenantId: string): string {\n const iterations = 310_000\n const keyLength = 32\n const derived = crypto.pbkdf2Sync(this.root, tenantId, iterations, keyLength, 'sha512')\n return derived.toString('base64')\n }\n\n async getTenantDek(tenantId: string): Promise<TenantDek | null> {\n if (!tenantId) return null\n return { tenantId, key: this.deriveKey(tenantId), fetchedAt: Date.now() }\n }\n\n async createTenantDek(tenantId: string): Promise<TenantDek | null> {\n return this.getTenantDek(tenantId)\n }\n}\n\nfunction fingerprintDek(dek: TenantDek | null): string | null {\n if (!dek?.key) return null\n return crypto.createHash('sha256').update(dek.key).digest('hex').slice(0, 12)\n}\n\nfunction decryptWithOldKey(\n payload: string,\n dek: TenantDek | null,\n): string | null {\n if (!dek?.key) return null\n return decryptWithAesGcm(payload, dek.key)\n}\n\nfunction resolveProperty(meta: any, field: string): { columnName: string | null; prop: any | null } {\n if (!meta?.properties) return { columnName: null, prop: null }\n const candidates = [\n field,\n field.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),\n field.replace(/([A-Z])/g, '_$1').toLowerCase(),\n ]\n for (const candidate of candidates) {\n const prop = meta.properties[candidate]\n const fieldName =\n prop?.fieldName ??\n (Array.isArray(prop?.fieldNames) && prop.fieldNames.length ? prop.fieldNames[0] : undefined)\n if (typeof fieldName === 'string' && fieldName.length) return { columnName: fieldName, prop }\n if (prop?.name) return { columnName: prop.name, prop }\n }\n return { columnName: null, prop: null }\n}\n\nfunction buildEntityMetaRegistry(em: any): Map<string, any> {\n const registry = em?.getMetadata?.()\n const allMetaRaw = typeof registry?.getAll === 'function' ? registry.getAll() : []\n const allMeta = Array.isArray(allMetaRaw) ? allMetaRaw : Object.values(allMetaRaw ?? {})\n const metaByEntityId = new Map<string, any>()\n for (const meta of allMeta) {\n const resolved = resolveEntityIdFromMetadata(meta)\n if (resolved) metaByEntityId.set(resolved, meta)\n }\n return metaByEntityId\n}\n\ninterface EncryptionMapMeta {\n entityId: string\n meta: any\n fields: Array<{ field: string; hashField?: string | null }>\n tenantId: string\n}\n\nfunction resolveMapMeta(\n map: EncryptionMap,\n metaByEntityId: Map<string, any>,\n warn: (msg: string) => void = () => {},\n): EncryptionMapMeta | null {\n const entityId = String(map.entityId)\n const meta = metaByEntityId.get(entityId)\n if (!meta) {\n warn(`Skipping ${entityId}: metadata not found.`)\n return null\n }\n const fields = Array.isArray(map.fieldsJson) ? map.fieldsJson : []\n if (!fields.length) return null\n const tenantId = map.tenantId ? String(map.tenantId) : null\n if (!tenantId) return null\n return { entityId, meta, fields, tenantId }\n}\n\nconst rotateEncryptionKey: ModuleCli = {\n command: 'rotate-encryption-key',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string) || null\n const organizationIdArg = (args.org as string) || (args.organization as string) || (args.organizationId as string) || null\n const oldKey = (args['old-key'] as string) || (args.oldKey as string) || null\n const dryRun = Boolean(args['dry-run'] || args.dry)\n const debug = Boolean(args.debug)\n const rotate = Boolean(oldKey)\n if (rotate && !tenantIdArg) {\n console.warn(\n '\u26A0\uFE0F Rotating with --old-key across all tenants. A single old key should normally target one tenant; consider --tenant.',\n )\n }\n if (!isTenantDataEncryptionEnabled()) {\n console.error('TENANT_DATA_ENCRYPTION is disabled; aborting.')\n return\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n const conn: any = em?.getConnection?.()\n if (!conn || typeof conn.execute !== 'function') {\n console.error('Unable to access raw connection; aborting.')\n return\n }\n\n const encryptionService = new TenantDataEncryptionService(em as any, { kms: createKmsService() })\n const oldKms = rotate && oldKey ? new DerivedKeyKmsService(oldKey) : null\n if (!encryptionService.isEnabled()) {\n console.error('Encryption service is not enabled (KMS unhealthy or no DEK). Aborting.')\n return\n }\n\n if (debug) {\n console.log('[rotate-encryption-key]', {\n hasOldKey: Boolean(oldKey),\n rotate,\n tenantId: tenantIdArg ?? null,\n organizationId: organizationIdArg ?? null,\n })\n if (tenantIdArg) {\n const [oldDek, newDek] = await Promise.all([\n oldKms?.getTenantDek(tenantIdArg) ?? Promise.resolve(null),\n encryptionService.getDek(tenantIdArg),\n ])\n console.log('[rotate-encryption-key] dek fingerprints', {\n oldKey: fingerprintDek(oldDek),\n currentKey: fingerprintDek(newDek),\n })\n } else {\n console.log('[rotate-encryption-key] dek fingerprints skipped (no tenantId)')\n }\n }\n\n const isEncryptedPayload = (value: unknown): boolean => {\n if (typeof value !== 'string') return false\n const parts = value.split(':')\n return parts.length === 4 && parts[3] === 'v1'\n }\n\n const metaByEntityId = buildEntityMetaRegistry(em)\n\n const where: any = { deletedAt: null }\n if (tenantIdArg) where.tenantId = tenantIdArg\n if (organizationIdArg) where.organizationId = organizationIdArg\n const maps = await em.find(EncryptionMap, where)\n if (!maps.length) {\n console.log('No encryption maps found for the selected scope.')\n return\n }\n\n const formatValueForColumn = (prop: any, value: unknown): unknown => {\n if (value === null || value === undefined) return value\n const types = Array.isArray(prop?.columnTypes) ? prop.columnTypes : []\n const type = String(prop?.type ?? '').toLowerCase()\n const isJson = types.some((entry: string) => entry.toLowerCase().includes('json')) || type === 'json' || type === 'jsonb'\n if (!isJson) return value\n return JSON.stringify(value)\n }\n\n const resolveScopes = async (tenantId: string, organizationId: string | null) => {\n if (organizationId) return [{ tenantId, organizationId }]\n const orgs = await em.find(Organization, { tenant: tenantId })\n const scopes = orgs.map((org: Organization) => ({\n tenantId,\n organizationId: String(org.id),\n }))\n scopes.push({ tenantId, organizationId: null })\n return scopes\n }\n\n const oldDekCache = new Map<string, TenantDek | null>()\n const processScope = async (\n entityId: string,\n meta: any,\n fields: Array<{ field: string; hashField?: string | null }>,\n scope: { tenantId: string; organizationId: string | null },\n ): Promise<number> => {\n const pk = Array.isArray(meta?.primaryKeys) && meta.primaryKeys.length ? meta.primaryKeys[0] : 'id'\n const columns = new Set<string>()\n columns.add(pk)\n for (const rule of fields) {\n const resolved = resolveProperty(meta, rule.field)\n if (resolved?.columnName) columns.add(resolved.columnName)\n if (rule.hashField) {\n const resolvedHash = resolveProperty(meta, rule.hashField)\n if (resolvedHash?.columnName) columns.add(resolvedHash.columnName)\n }\n }\n const columnList = Array.from(columns)\n if (!columnList.length) return 0\n const tableName = meta?.tableName\n if (!tableName) return 0\n const schema = meta?.schema\n const qualifiedTable = schema ? `\"${schema}\".\"${tableName}\"` : `\"${tableName}\"`\n const selectSql = `select ${columnList.map((c) => `\"${c}\"`).join(', ')} from ${qualifiedTable} where tenant_id = ? and organization_id is not distinct from ?`\n const rows = await conn.execute(selectSql, [scope.tenantId, scope.organizationId])\n const list = Array.isArray(rows) ? rows : []\n if (!list.length) return 0\n let updated = 0\n for (const row of list) {\n const payload: Record<string, unknown> = {}\n for (const rule of fields) {\n const resolved = resolveProperty(meta, rule.field)\n const col = resolved?.columnName\n if (!col) continue\n const rawValue = row[col]\n if (rotate && !isEncryptedPayload(rawValue)) {\n continue\n }\n payload[rule.field] = rawValue\n if (rule.hashField) {\n const resolvedHash = resolveProperty(meta, rule.hashField)\n const hashCol = resolvedHash?.columnName\n if (hashCol) payload[rule.hashField] = row[hashCol]\n }\n }\n if (rotate && !Object.keys(payload).length) {\n continue\n }\n if (rotate && oldKms) {\n let oldDek = oldDekCache.get(scope.tenantId) ?? null\n if (!oldDekCache.has(scope.tenantId)) {\n oldDek = await oldKms.getTenantDek(scope.tenantId)\n oldDekCache.set(scope.tenantId, oldDek)\n }\n for (const rule of fields) {\n const value = payload[rule.field]\n if (typeof value !== 'string' || !isEncryptedPayload(value)) continue\n const decrypted = decryptWithOldKey(value, oldDek)\n if (decrypted === null) continue\n payload[rule.field] = parseDecryptedFieldValue(decrypted)\n }\n }\n const encrypted = await encryptionService.encryptEntityPayload(\n entityId,\n payload,\n scope.tenantId,\n scope.organizationId,\n )\n const updates: Record<string, unknown> = {}\n for (const rule of fields) {\n const resolved = resolveProperty(meta, rule.field)\n const col = resolved?.columnName\n if (!col) continue\n const nextValue = (encrypted as any)[rule.field]\n if (nextValue !== undefined && nextValue !== row[col]) {\n if (!rotate && isEncryptedPayload(row[col])) continue\n updates[col] = formatValueForColumn(resolved?.prop, nextValue)\n }\n if (rule.hashField) {\n const resolvedHash = resolveProperty(meta, rule.hashField)\n const hashCol = resolvedHash?.columnName\n const hashValue = (encrypted as any)[rule.hashField]\n if (hashCol && hashValue !== undefined && hashValue !== row[hashCol]) {\n updates[hashCol] = formatValueForColumn(resolvedHash?.prop, hashValue)\n }\n }\n }\n if (!Object.keys(updates).length) continue\n if (!dryRun) {\n const setSql = Object.keys(updates).map((col) => `\"${col}\" = ?`).join(', ')\n await conn.execute(\n `update ${qualifiedTable} set ${setSql} where \"${pk}\" = ?`,\n [...Object.values(updates), row[pk]],\n )\n }\n updated += 1\n }\n return updated\n }\n\n let total = 0\n for (const map of maps) {\n const mapMeta = resolveMapMeta(map, metaByEntityId, console.warn)\n if (!mapMeta) continue\n const { entityId, meta, fields, tenantId } = mapMeta\n const scopes = await resolveScopes(tenantId, map.organizationId ? String(map.organizationId) : null)\n for (const scope of scopes) {\n const updated = await processScope(entityId, meta, fields, scope)\n if (updated > 0) {\n console.log(\n `${dryRun ? '[dry-run] ' : ''}Encrypted ${updated} record(s) for ${entityId} org=${scope.organizationId ?? 'null'}`\n )\n }\n total += updated\n }\n }\n\n if (total > 0) {\n console.log(`Encrypted ${total} record(s) across mapped entities.`)\n } else {\n console.log('All mapped entity fields already encrypted for the selected scope.')\n }\n },\n}\n\nconst decryptDatabase: ModuleCli = {\n command: 'decrypt-database',\n async run(rest) {\n const args = parseArgs(rest)\n const tenantIdArg = (args.tenant as string) || (args.tenantId as string) || null\n const organizationIdArg = (args.org as string) || (args.organization as string) || (args.organizationId as string) || null\n const entityIdArg = (args.entity as string) || null\n const checkMode = Boolean(args.check)\n const dryRun = Boolean(args['dry-run'] || args.dry) || checkMode\n const deactivateMaps = Boolean(args['deactivate-maps'])\n const confirm = (args.confirm as string) || null\n const batchSize = Math.max(1, parseInt(String(args['batch-size'] || args.batchSize || '500'), 10) || 500)\n const sleepMs = Math.max(0, parseInt(String(args['sleep-ms'] || args.sleepMs || '0'), 10) || 0)\n const debug = Boolean(args.debug)\n\n if (!tenantIdArg) {\n console.error('--tenant <uuid> is required.')\n return\n }\n\n if (!checkMode) {\n if (!confirm) {\n console.error('--confirm <tenantUuid> is required (safety gate). Pass the exact tenant UUID to confirm the operation.')\n return\n }\n if (confirm !== tenantIdArg) {\n console.error(`--confirm value \"${confirm}\" does not match --tenant \"${tenantIdArg}\". Aborting.`)\n return\n }\n }\n\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as any\n const conn: any = em?.getConnection?.()\n if (!conn || typeof conn.execute !== 'function') {\n console.error('Unable to access raw database connection; aborting.')\n return\n }\n\n if (!checkMode && !isTenantDataEncryptionEnabled()) {\n console.error('TENANT_DATA_ENCRYPTION is disabled; aborting. Data may already be decrypted.')\n return\n }\n\n const metaByEntityId = buildEntityMetaRegistry(em)\n\n const resolveDecryptScopes = async (\n tenantId: string,\n organizationId: string | null,\n ): Promise<Array<{ tenantId: string; organizationId: string | null }>> => {\n if (organizationId) return [{ tenantId, organizationId }]\n const rows = await conn.execute(\n `SELECT DISTINCT organization_id FROM encryption_maps WHERE tenant_id = ? AND deleted_at IS NULL`,\n [tenantId],\n )\n const orgIds = new Set<string | null>()\n for (const row of Array.isArray(rows) ? rows : []) {\n orgIds.add(row.organization_id ?? null)\n }\n orgIds.add(null)\n return Array.from(orgIds).map((orgId) => ({ tenantId, organizationId: orgId }))\n }\n\n const mapWhere: any = { tenantId: tenantIdArg, deletedAt: null, isActive: true }\n if (organizationIdArg) mapWhere.organizationId = organizationIdArg\n if (entityIdArg) mapWhere.entityId = entityIdArg\n const maps = await em.find(EncryptionMap, mapWhere)\n\n if (!maps.length) {\n console.log('No active encryption maps found for the selected scope.')\n return\n }\n\n const kms = createKmsService()\n const dekCache = new Map<string, TenantDek | null>()\n const getDek = async (tenantId: string): Promise<TenantDek | null> => {\n if (dekCache.has(tenantId)) return dekCache.get(tenantId) ?? null\n const dek = await kms.getTenantDek(tenantId)\n dekCache.set(tenantId, dek)\n return dek\n }\n\n if (checkMode) {\n const envValue = process.env.TENANT_DATA_ENCRYPTION ?? '(not set)'\n console.log(`TENANT_DATA_ENCRYPTION = ${envValue}`)\n console.log(`Active EncryptionMap records for scope: ${maps.length}`)\n let encryptedCandidatesSampled = 0\n let malformedPayloadCountSampled = 0\n for (const map of maps) {\n const mapMeta = resolveMapMeta(map, metaByEntityId)\n if (!mapMeta) continue\n const { entityId, meta, fields, tenantId } = mapMeta\n const dek = await getDek(tenantId).catch(() => null)\n if (!dek) continue\n const scopes = await resolveDecryptScopes(tenantId, map.organizationId ? String(map.organizationId) : null)\n const pk = Array.isArray(meta?.primaryKeys) && meta.primaryKeys.length ? meta.primaryKeys[0] : 'id'\n const tableName = meta?.tableName\n if (!tableName) continue\n const schema = meta?.schema\n const qualifiedTable = schema ? `\"${schema}\".\"${tableName}\"` : `\"${tableName}\"`\n const fieldCols = fields.flatMap((f: any) => {\n const r = resolveProperty(meta, f.field)\n return r.columnName ? [r.columnName] : []\n })\n const colList = Array.from(new Set([pk, ...fieldCols]))\n for (const scope of scopes) {\n const sampleRows = await conn.execute(\n `SELECT ${colList.map((c: string) => `\"${c}\"`).join(', ')} FROM ${qualifiedTable} WHERE tenant_id = ? AND organization_id IS NOT DISTINCT FROM ? LIMIT 100`,\n [scope.tenantId, scope.organizationId],\n ).catch(() => [])\n for (const row of Array.isArray(sampleRows) ? sampleRows : []) {\n let rowHasEncrypted = false\n for (const fieldRule of fields) {\n const resolved = resolveProperty(meta, fieldRule.field)\n const col = resolved?.columnName\n if (!col) continue\n const rawValue = row[col]\n if (rawValue === null || rawValue === undefined) continue\n try {\n decryptWithAesGcmStrict(String(rawValue), dek.key)\n rowHasEncrypted = true\n } catch (e: any) {\n if (e instanceof TenantDataEncryptionError && e.code === TenantDataEncryptionErrorCode.MALFORMED_PAYLOAD) {\n malformedPayloadCountSampled++\n }\n }\n }\n if (rowHasEncrypted) encryptedCandidatesSampled++\n }\n }\n }\n console.log(`estimated encrypted candidates (sampled): ${encryptedCandidatesSampled}`)\n if (malformedPayloadCountSampled > 0) {\n console.warn(`\u26A0 malformed payloads (sampled): ${malformedPayloadCountSampled} \u2014 may indicate corruption`)\n } else {\n console.log(`malformed payloads (sampled): ${malformedPayloadCountSampled}`)\n }\n console.log('not a proof of absence \u2014 run full command + rerun --check to confirm')\n return\n }\n\n let totalRowsFetched = 0\n let totalRowsUpdated = 0\n let totalHashFieldsCleared = 0\n const totalHashFieldsSkipped = new Set<string>()\n let totalMalformedPayloadCount = 0\n const malformedByLocation = new Map<string, number>()\n let totalEntitiesProcessed = 0\n\n for (const map of maps) {\n const mapMeta = resolveMapMeta(map, metaByEntityId, console.warn)\n if (!mapMeta) continue\n const { entityId, meta, fields, tenantId } = mapMeta\n const dek = await getDek(tenantId)\n if (!dek) {\n console.warn(`No DEK available for tenant ${tenantId}; skipping ${entityId}.`)\n continue\n }\n const pk = Array.isArray(meta?.primaryKeys) && meta.primaryKeys.length ? meta.primaryKeys[0] : 'id'\n const tableName = meta?.tableName\n if (!tableName) {\n console.warn(`Skipping ${entityId}: table name not found.`)\n continue\n }\n const schema = meta?.schema\n const qualifiedTable = schema ? `\"${schema}\".\"${tableName}\"` : `\"${tableName}\"`\n const fieldCols = fields.flatMap((f: any) => {\n const r = resolveProperty(meta, f.field)\n return r.columnName ? [r.columnName] : []\n })\n const colList = Array.from(new Set([pk, ...fieldCols]))\n totalEntitiesProcessed++\n\n const scopes = await resolveDecryptScopes(tenantId, map.organizationId ? String(map.organizationId) : null)\n\n for (const scope of scopes) {\n let lastId: string | null = null\n let scopeMalformedCount = 0\n\n while (true) {\n let selectSql = `SELECT ${colList.map((c: string) => `\"${c}\"`).join(', ')} FROM ${qualifiedTable} WHERE tenant_id = ? AND organization_id IS NOT DISTINCT FROM ?`\n const selectParams: unknown[] = [scope.tenantId, scope.organizationId]\n if (lastId !== null) {\n selectSql += ` AND \"${pk}\" > ?`\n selectParams.push(lastId)\n }\n selectSql += ` ORDER BY \"${pk}\" LIMIT ?`\n selectParams.push(batchSize)\n\n const batchRows = await conn.execute(selectSql, selectParams)\n const batch = Array.isArray(batchRows) ? batchRows : []\n if (!batch.length) break\n\n lastId = String(batch[batch.length - 1]![pk])\n totalRowsFetched += batch.length\n\n const batchStart = Date.now()\n await conn.execute('BEGIN')\n let batchCommitted = false\n try {\n for (const row of batch) {\n const updates: Record<string, unknown> = {}\n let rowDecrypted = false\n\n for (const fieldRule of fields) {\n const resolved = resolveProperty(meta, fieldRule.field)\n const col = resolved?.columnName\n if (!col) continue\n const rawValue = row[col]\n if (rawValue === null || rawValue === undefined) continue\n try {\n const decrypted = decryptWithAesGcmStrict(String(rawValue), dek.key)\n let valueToWrite: string\n try {\n const parsed = JSON.parse(decrypted)\n valueToWrite = typeof parsed === 'string' ? parsed : decrypted\n } catch {\n valueToWrite = decrypted\n }\n updates[col] = valueToWrite\n rowDecrypted = true\n } catch (e: any) {\n if (e instanceof TenantDataEncryptionError) {\n if (e.code === TenantDataEncryptionErrorCode.AUTH_FAILED) {\n // Value is plaintext \u2014 skip silently\n } else if (e.code === TenantDataEncryptionErrorCode.MALFORMED_PAYLOAD) {\n scopeMalformedCount++\n const locationKey = `${tableName}:${col}`\n malformedByLocation.set(locationKey, (malformedByLocation.get(locationKey) ?? 0) + 1)\n console.warn(`\u26A0 MALFORMED_PAYLOAD for ${entityId} field \"${col}\" row ${row[pk]}; skipping field.`)\n } else {\n throw e\n }\n } else {\n throw e\n }\n }\n }\n\n if (rowDecrypted) {\n for (const fieldRule of fields) {\n if (!fieldRule.hashField) continue\n const resolvedHash = resolveProperty(meta, fieldRule.hashField)\n const hashCol = resolvedHash?.columnName\n if (!hashCol) {\n const skippedKey = `${tableName}:${fieldRule.hashField}`\n if (!totalHashFieldsSkipped.has(skippedKey)) {\n console.warn(`\u26A0 Hash column \"${fieldRule.hashField}\" not found in metadata for ${entityId}; skipping.`)\n totalHashFieldsSkipped.add(skippedKey)\n }\n continue\n }\n updates[hashCol] = null\n totalHashFieldsCleared++\n }\n }\n\n if (Object.keys(updates).length > 0) {\n if (!dryRun) {\n const setSql = Object.keys(updates).map((col) => `\"${col}\" = ?`).join(', ')\n await conn.execute(\n `UPDATE ${qualifiedTable} SET ${setSql} WHERE \"${pk}\" = ?`,\n [...Object.values(updates), row[pk]],\n )\n }\n totalRowsUpdated++\n }\n }\n await conn.execute('COMMIT')\n batchCommitted = true\n } catch (fatalErr: any) {\n if (!batchCommitted) {\n try { await conn.execute('ROLLBACK') } catch {}\n }\n console.error(`Fatal error during batch processing for ${entityId}: ${(fatalErr as Error)?.message || String(fatalErr)}`)\n throw fatalErr\n }\n\n const batchDurationMs = Date.now() - batchStart\n if (debug) {\n console.log(\n `[debug] Batch ${entityId} org=${scope.organizationId ?? 'null'}: ${batch.length} rows in ${batchDurationMs}ms, scopeMalformed=${scopeMalformedCount}`,\n )\n if (batchDurationMs > 30_000) {\n console.warn('\u26A0 Batch took >30s; consider reducing --batch-size.')\n }\n }\n if (sleepMs > 0) {\n await new Promise<void>((r) => setTimeout(r, sleepMs))\n }\n }\n\n totalMalformedPayloadCount += scopeMalformedCount\n }\n }\n\n if (deactivateMaps && !dryRun) {\n let deactivateSql = `UPDATE encryption_maps SET is_active = false, deleted_at = now() WHERE tenant_id = ? AND deleted_at IS NULL`\n const deactivateParams: unknown[] = [tenantIdArg]\n if (organizationIdArg) {\n deactivateSql += ` AND (organization_id = ? OR organization_id IS NULL)`\n deactivateParams.push(organizationIdArg)\n }\n if (entityIdArg) {\n deactivateSql += ` AND entity_id = ?`\n deactivateParams.push(entityIdArg)\n }\n await conn.execute(deactivateSql, deactivateParams)\n console.warn('\u26A0 Restart all application replicas \u2014 in-process map caches may still be active.')\n if (isTenantDataEncryptionEnabled()) {\n console.warn('\u26A0 Env TENANT_DATA_ENCRYPTION is still true \u2014 new writes will be re-encrypted until env is updated and replicas restarted.')\n }\n }\n\n if (deactivateMaps && dryRun) {\n console.log(`[dry-run] Would deactivate ${maps.length} EncryptionMap record(s).`)\n }\n\n const prefix = dryRun ? '[dry-run] ' : ''\n console.log(`\\n${prefix}Decryption summary:`)\n console.log(` Rows fetched: ${totalRowsFetched}`)\n console.log(` Rows updated: ${totalRowsUpdated}`)\n console.log(` Entities processed: ${totalEntitiesProcessed}`)\n console.log(` Hash fields cleared: ${totalHashFieldsCleared}`)\n if (totalHashFieldsSkipped.size > 0) {\n console.log(` Hash fields skipped (missing columns): ${Array.from(totalHashFieldsSkipped).join(', ')}`)\n }\n if (totalMalformedPayloadCount > 0) {\n console.warn(\n ` \u26A0 ${totalMalformedPayloadCount} field value(s) returned MALFORMED_PAYLOAD and were skipped; these may be corrupted ciphertexts. Investigate before assuming decryption is complete.`,\n )\n if (debug && malformedByLocation.size > 0) {\n const top = Array.from(malformedByLocation.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n console.log(' Top malformed locations:')\n for (const [loc, count] of top) {\n console.log(` ${loc}: ${count}`)\n }\n }\n }\n\n if (!dryRun) {\n console.log(`\\n\u2705 Decryption complete. Required next steps:`)\n console.log(` 1. Set TENANT_DATA_ENCRYPTION=false in your environment / secrets`)\n console.log(` 2. Restart all application replicas`)\n console.log(` 3. Run: mercato query_index reindex --tenant ${tenantIdArg} \u2190 run after env flip + restart; search/filter degraded until this completes`)\n console.log(` 4. Run: mercato entities decrypt-database --tenant ${tenantIdArg} --check to confirm no encrypted values remain`)\n console.log(` NOTE: if the run was long and concurrent inserts occurred, run again before step 4 \u2014 it is idempotent.`)\n }\n },\n}\n\n// Keep default export stable (install first for help listing)\nexport default [seedDefs, reinstallDefs, addField, seedEncryptionMaps, rotateEncryptionKey, decryptDatabase]\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,124 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useMemo, useState, useEffect } from "react";
4
+ import { useSearchParams } from "next/navigation";
5
+ import Link from "next/link";
6
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
7
+ import { Input } from "@open-mercato/ui/primitives/input";
8
+ import { Label } from "@open-mercato/ui/primitives/label";
9
+ import { Button } from "@open-mercato/ui/primitives/button";
10
+ import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
11
+ import { Spinner } from "@open-mercato/ui/primitives/spinner";
12
+ import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
13
+ import { usePortalContext } from "@open-mercato/ui/portal/PortalContext";
14
+ import { InjectionSpot } from "@open-mercato/ui/backend/injection/InjectionSpot";
15
+ import { PortalInjectionSpots } from "@open-mercato/ui/backend/injection/spotIds";
16
+ function PortalResetPasswordPage({ params }) {
17
+ const t = useT();
18
+ const orgSlug = params.orgSlug;
19
+ const { tenant } = usePortalContext();
20
+ const searchParams = useSearchParams();
21
+ const [password, setPassword] = useState("");
22
+ const [confirmPassword, setConfirmPassword] = useState("");
23
+ const [error, setError] = useState(null);
24
+ const [success, setSuccess] = useState(false);
25
+ const [submitting, setSubmitting] = useState(false);
26
+ const [token, setToken] = useState(null);
27
+ useEffect(() => {
28
+ const tokenParam = searchParams.get("token");
29
+ if (!tokenParam) {
30
+ setError(t("portal.resetPassword.error.noToken", "Invalid or missing reset token."));
31
+ } else {
32
+ setToken(tokenParam);
33
+ }
34
+ }, [searchParams, t]);
35
+ const handleSubmit = useCallback(
36
+ async (event) => {
37
+ event.preventDefault();
38
+ setError(null);
39
+ if (!token) {
40
+ setError(t("portal.resetPassword.error.noToken", "Invalid or missing reset token."));
41
+ return;
42
+ }
43
+ if (password !== confirmPassword) {
44
+ setError(t("portal.resetPassword.error.passwordMismatch", "Passwords do not match."));
45
+ return;
46
+ }
47
+ if (password.length < 8) {
48
+ setError(t("portal.resetPassword.error.passwordTooShort", "Password must be at least 8 characters long."));
49
+ return;
50
+ }
51
+ setSubmitting(true);
52
+ try {
53
+ const result = await apiCall("/api/customer_accounts/password/reset-confirm", {
54
+ method: "POST",
55
+ headers: { "Content-Type": "application/json" },
56
+ body: JSON.stringify({ token, password })
57
+ });
58
+ if (result.ok && result.result?.ok) {
59
+ setSuccess(true);
60
+ return;
61
+ }
62
+ if (result.status === 400) {
63
+ setError(t("portal.resetPassword.error.invalidToken", "Invalid or expired reset token."));
64
+ } else {
65
+ setError(result.result?.error || t("portal.resetPassword.error.generic", "Password reset failed. Please try again."));
66
+ }
67
+ } catch {
68
+ setError(t("portal.resetPassword.error.generic", "Password reset failed. Please try again."));
69
+ } finally {
70
+ setSubmitting(false);
71
+ }
72
+ },
73
+ [token, password, confirmPassword, t]
74
+ );
75
+ const injectionContext = useMemo(
76
+ () => ({ orgSlug }),
77
+ [orgSlug]
78
+ );
79
+ if (tenant.loading) {
80
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-20", children: /* @__PURE__ */ jsx(Spinner, {}) });
81
+ }
82
+ if (tenant.error) {
83
+ return /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-md py-12", children: /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: t("portal.org.invalid", "Organization not found.") }) }) });
84
+ }
85
+ if (success) {
86
+ return /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-sm", children: [
87
+ /* @__PURE__ */ jsxs("div", { className: "mb-8 text-center", children: [
88
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold tracking-tight", children: t("portal.resetPassword.success.title", "Password Reset Complete") }),
89
+ /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-muted-foreground", children: t("portal.resetPassword.success.description", "Your password has been successfully reset.") })
90
+ ] }),
91
+ /* @__PURE__ */ jsx(Alert, { children: /* @__PURE__ */ jsx(AlertDescription, { children: t("portal.resetPassword.success.message", "You can now sign in with your new password.") }) }),
92
+ /* @__PURE__ */ jsx("div", { className: "mt-6 text-center", children: /* @__PURE__ */ jsx(Link, { href: `/${orgSlug}/portal/login`, className: "font-medium text-foreground underline underline-offset-4 hover:opacity-80", children: t("portal.resetPassword.success.loginLink", "Go to Sign In") }) })
93
+ ] });
94
+ }
95
+ return /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-sm", children: [
96
+ /* @__PURE__ */ jsxs("div", { className: "mb-8 text-center", children: [
97
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold tracking-tight", children: t("portal.resetPassword.title", "Reset Password") }),
98
+ /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-muted-foreground", children: t("portal.resetPassword.description", "Enter your new password below.") })
99
+ ] }),
100
+ /* @__PURE__ */ jsx(InjectionSpot, { spotId: PortalInjectionSpots.pageBefore("reset-password"), context: injectionContext }),
101
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [
102
+ error ? /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }) : null,
103
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
104
+ /* @__PURE__ */ jsx(Label, { htmlFor: "reset-password", className: "text-overline font-semibold uppercase tracking-wider text-muted-foreground/70", children: t("portal.resetPassword.password", "New Password") }),
105
+ /* @__PURE__ */ jsx(Input, { id: "reset-password", type: "password", autoComplete: "new-password", required: true, placeholder: t("portal.resetPassword.password.placeholder", "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"), value: password, onChange: (e) => setPassword(e.target.value), disabled: submitting || !token, className: "rounded-lg" })
106
+ ] }),
107
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
108
+ /* @__PURE__ */ jsx(Label, { htmlFor: "confirm-password", className: "text-overline font-semibold uppercase tracking-wider text-muted-foreground/70", children: t("portal.resetPassword.confirmPassword", "Confirm New Password") }),
109
+ /* @__PURE__ */ jsx(Input, { id: "confirm-password", type: "password", autoComplete: "new-password", required: true, placeholder: t("portal.resetPassword.confirmPassword.placeholder", "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"), value: confirmPassword, onChange: (e) => setConfirmPassword(e.target.value), disabled: submitting || !token, className: "rounded-lg" })
110
+ ] }),
111
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: submitting || !token, className: "mt-1 w-full rounded-lg", children: submitting ? t("portal.resetPassword.submitting", "Resetting password...") : t("portal.resetPassword.submit", "Reset Password") }),
112
+ /* @__PURE__ */ jsxs("p", { className: "text-center text-sm text-muted-foreground", children: [
113
+ t("portal.resetPassword.backToLogin", "Remember your password?"),
114
+ " ",
115
+ /* @__PURE__ */ jsx(Link, { href: `/${orgSlug}/portal/login`, className: "font-medium text-foreground underline underline-offset-4 hover:opacity-80", children: t("portal.resetPassword.loginLink", "Sign in") })
116
+ ] })
117
+ ] }),
118
+ /* @__PURE__ */ jsx(InjectionSpot, { spotId: PortalInjectionSpots.pageAfter("reset-password"), context: injectionContext })
119
+ ] });
120
+ }
121
+ export {
122
+ PortalResetPasswordPage as default
123
+ };
124
+ //# sourceMappingURL=page.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/portal/frontend/%5BorgSlug%5D/portal/reset-password/page.tsx"],
4
+ "sourcesContent": ["\"use client\"\nimport { useCallback, useMemo, useState, useEffect } from 'react'\nimport { useSearchParams } from 'next/navigation'\nimport Link from 'next/link'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { usePortalContext } from '@open-mercato/ui/portal/PortalContext'\nimport { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'\n\ntype Props = { params: { orgSlug: string } }\n\nexport default function PortalResetPasswordPage({ params }: Props) {\n const t = useT()\n const orgSlug = params.orgSlug\n const { tenant } = usePortalContext()\n const searchParams = useSearchParams()\n\n const [password, setPassword] = useState('')\n const [confirmPassword, setConfirmPassword] = useState('')\n const [error, setError] = useState<string | null>(null)\n const [success, setSuccess] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n const [token, setToken] = useState<string | null>(null)\n\n useEffect(() => {\n const tokenParam = searchParams.get('token')\n if (!tokenParam) {\n setError(t('portal.resetPassword.error.noToken', 'Invalid or missing reset token.'))\n } else {\n setToken(tokenParam)\n }\n }, [searchParams, t])\n\n const handleSubmit = useCallback(\n async (event: React.FormEvent) => {\n event.preventDefault()\n setError(null)\n\n if (!token) {\n setError(t('portal.resetPassword.error.noToken', 'Invalid or missing reset token.'))\n return\n }\n\n if (password !== confirmPassword) {\n setError(t('portal.resetPassword.error.passwordMismatch', 'Passwords do not match.'))\n return\n }\n\n if (password.length < 8) {\n setError(t('portal.resetPassword.error.passwordTooShort', 'Password must be at least 8 characters long.'))\n return\n }\n\n setSubmitting(true)\n try {\n const result = await apiCall<{ ok: boolean; error?: string }>('/api/customer_accounts/password/reset-confirm', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token, password }),\n })\n\n if (result.ok && result.result?.ok) {\n setSuccess(true)\n return\n }\n\n if (result.status === 400) {\n setError(t('portal.resetPassword.error.invalidToken', 'Invalid or expired reset token.'))\n } else {\n setError(result.result?.error || t('portal.resetPassword.error.generic', 'Password reset failed. Please try again.'))\n }\n } catch {\n setError(t('portal.resetPassword.error.generic', 'Password reset failed. Please try again.'))\n } finally {\n setSubmitting(false)\n }\n },\n [token, password, confirmPassword, t],\n )\n\n const injectionContext = useMemo(\n () => ({ orgSlug }),\n [orgSlug],\n )\n\n if (tenant.loading) {\n return <div className=\"flex items-center justify-center py-20\"><Spinner /></div>\n }\n\n if (tenant.error) {\n return (\n <div className=\"mx-auto w-full max-w-md py-12\">\n <Alert variant=\"destructive\">\n <AlertDescription>{t('portal.org.invalid', 'Organization not found.')}</AlertDescription>\n </Alert>\n </div>\n )\n }\n\n if (success) {\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.resetPassword.success.title', 'Password Reset Complete')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.resetPassword.success.description', 'Your password has been successfully reset.')}</p>\n </div>\n\n <Alert>\n <AlertDescription>{t('portal.resetPassword.success.message', 'You can now sign in with your new password.')}</AlertDescription>\n </Alert>\n\n <div className=\"mt-6 text-center\">\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.resetPassword.success.loginLink', 'Go to Sign In')}\n </Link>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-8 text-center\">\n <h1 className=\"text-2xl font-bold tracking-tight\">{t('portal.resetPassword.title', 'Reset Password')}</h1>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{t('portal.resetPassword.description', 'Enter your new password below.')}</p>\n </div>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageBefore('reset-password')} context={injectionContext} />\n\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-4\">\n {error ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n ) : null}\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"reset-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.resetPassword.password', 'New Password')}</Label>\n <Input id=\"reset-password\" type=\"password\" autoComplete=\"new-password\" required placeholder={t('portal.resetPassword.password.placeholder', '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022')} value={password} onChange={(e) => setPassword(e.target.value)} disabled={submitting || !token} className=\"rounded-lg\" />\n </div>\n\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"confirm-password\" className=\"text-overline font-semibold uppercase tracking-wider text-muted-foreground/70\">{t('portal.resetPassword.confirmPassword', 'Confirm New Password')}</Label>\n <Input id=\"confirm-password\" type=\"password\" autoComplete=\"new-password\" required placeholder={t('portal.resetPassword.confirmPassword.placeholder', '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022')} value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} disabled={submitting || !token} className=\"rounded-lg\" />\n </div>\n\n <Button type=\"submit\" disabled={submitting || !token} className=\"mt-1 w-full rounded-lg\">\n {submitting ? t('portal.resetPassword.submitting', 'Resetting password...') : t('portal.resetPassword.submit', 'Reset Password')}\n </Button>\n\n <p className=\"text-center text-sm text-muted-foreground\">\n {t('portal.resetPassword.backToLogin', 'Remember your password?')}{' '}\n <Link href={`/${orgSlug}/portal/login`} className=\"font-medium text-foreground underline underline-offset-4 hover:opacity-80\">\n {t('portal.resetPassword.loginLink', 'Sign in')}\n </Link>\n </p>\n </form>\n\n <InjectionSpot spotId={PortalInjectionSpots.pageAfter('reset-password')} context={injectionContext} />\n </div>\n )\n}"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ const metadata = {
2
+ titleKey: "portal.nav.resetPassword",
3
+ title: "Reset Password",
4
+ navHidden: true
5
+ };
6
+ var page_meta_default = metadata;
7
+ export {
8
+ page_meta_default as default,
9
+ metadata
10
+ };
11
+ //# sourceMappingURL=page.meta.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/modules/portal/frontend/%5BorgSlug%5D/portal/reset-password/page.meta.ts"],
4
+ "sourcesContent": ["import type { PageMetadata } from '@open-mercato/shared/modules/registry'\n\nexport const metadata: PageMetadata = {\n titleKey: 'portal.nav.resetPassword',\n title: 'Reset Password',\n navHidden: true,\n}\n\nexport default metadata\n"],
5
+ "mappings": "AAEO,MAAM,WAAyB;AAAA,EACpC,UAAU;AAAA,EACV,OAAO;AAAA,EACP,WAAW;AACb;AAEA,IAAO,oBAAQ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ export const id = "id";
2
+ export const user = "user";
3
+ export const tenant_id = "tenant_id";
4
+ export const organization_id = "organization_id";
5
+ export const locale = "locale";
6
+ export const name = "name";
7
+ export const settings_json = "settings_json";
8
+ export const is_active = "is_active";
9
+ export const created_at = "created_at";
10
+ export const updated_at = "updated_at";
11
+ export const deleted_at = "deleted_at";
@@ -44,6 +44,7 @@ export const M = {
44
44
  "role": "auth:role",
45
45
  "user_sidebar_preference": "auth:user_sidebar_preference",
46
46
  "role_sidebar_preference": "auth:role_sidebar_preference",
47
+ "sidebar_variant": "auth:sidebar_variant",
47
48
  "user_role": "auth:user_role",
48
49
  "session": "auth:session",
49
50
  "password_reset": "auth:password_reset",
@@ -2326,6 +2326,19 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
2326
2326
  "last_used_at": "last_used_at",
2327
2327
  "deleted_at": "deleted_at"
2328
2328
  },
2329
+ "sidebar_variant": {
2330
+ "id": "id",
2331
+ "user": "user",
2332
+ "tenant_id": "tenant_id",
2333
+ "organization_id": "organization_id",
2334
+ "locale": "locale",
2335
+ "name": "name",
2336
+ "settings_json": "settings_json",
2337
+ "is_active": "is_active",
2338
+ "created_at": "created_at",
2339
+ "updated_at": "updated_at",
2340
+ "deleted_at": "deleted_at"
2341
+ },
2329
2342
  "staff_leave_request": {
2330
2343
  "id": "id",
2331
2344
  "tenant_id": "tenant_id",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.5.1-develop.2975.ccbadc8198",
3
+ "version": "0.5.1-develop.2996.ce62fd491c",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -223,9 +223,9 @@
223
223
  }
224
224
  },
225
225
  "dependencies": {
226
- "@mikro-orm/core": "^7.0.10",
227
- "@mikro-orm/decorators": "^7.0.10",
228
- "@mikro-orm/postgresql": "^7.0.10",
226
+ "@mikro-orm/core": "^7.0.13",
227
+ "@mikro-orm/decorators": "^7.0.13",
228
+ "@mikro-orm/postgresql": "^7.0.13",
229
229
  "@xyflow/react": "^12.10.2",
230
230
  "ai": "^6.0.168",
231
231
  "date-fns": "^4.1.0",
@@ -237,10 +237,10 @@
237
237
  "ts-pattern": "^5.0.0"
238
238
  },
239
239
  "peerDependencies": {
240
- "@open-mercato/shared": "0.5.1-develop.2975.ccbadc8198"
240
+ "@open-mercato/shared": "0.5.1-develop.2996.ce62fd491c"
241
241
  },
242
242
  "devDependencies": {
243
- "@open-mercato/shared": "0.5.1-develop.2975.ccbadc8198",
243
+ "@open-mercato/shared": "0.5.1-develop.2996.ce62fd491c",
244
244
  "@testing-library/dom": "^10.4.1",
245
245
  "@testing-library/jest-dom": "^6.9.1",
246
246
  "@testing-library/react": "^16.3.1",