@lenne.tech/nest-server 12.0.0 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/rules/architecture.md +6 -1
- package/.claude/rules/better-auth.md +46 -0
- package/.claude/rules/configurable-features.md +3 -2
- package/.claude/rules/package-management.md +24 -2
- package/.claude/rules/persistence.md +100 -0
- package/.claude/rules/role-system.md +9 -0
- package/.claude/rules/testing.md +116 -18
- package/CLAUDE.md +21 -2
- package/FRAMEWORK-API.md +6 -4
- package/README.md +106 -34
- package/dist/core/common/decorators/unified-field.decorator.d.ts +2 -1
- package/dist/core/common/decorators/unified-field.decorator.js +4 -1
- package/dist/core/common/decorators/unified-field.decorator.js.map +1 -1
- package/dist/core/common/filters/mongoose-cast-error.filter.d.ts +7 -5
- package/dist/core/common/filters/mongoose-cast-error.filter.js +3 -2
- package/dist/core/common/filters/mongoose-cast-error.filter.js.map +1 -1
- package/dist/core/common/helpers/db.helper.d.ts +2 -1
- package/dist/core/common/helpers/db.helper.js +32 -26
- package/dist/core/common/helpers/db.helper.js.map +1 -1
- package/dist/core/common/helpers/decorator.helper.d.ts +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +2 -1
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/helpers/gridfs.helper.d.ts +4 -4
- package/dist/core/common/helpers/gridfs.helper.js +14 -6
- package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
- package/dist/core/common/helpers/id.helper.d.ts +4 -1
- package/dist/core/common/helpers/id.helper.js +10 -4
- package/dist/core/common/helpers/id.helper.js.map +1 -1
- package/dist/core/common/helpers/model.helper.js +5 -5
- package/dist/core/common/helpers/model.helper.js.map +1 -1
- package/dist/core/common/helpers/service.helper.js +3 -3
- package/dist/core/common/helpers/service.helper.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +18 -2
- package/dist/core/common/interfaces/service-options.interface.d.ts +2 -2
- package/dist/core/common/models/core-persistence.model.d.ts +1 -2
- package/dist/core/common/models/core-persistence.model.js +3 -3
- package/dist/core/common/models/core-persistence.model.js.map +1 -1
- package/dist/core/common/persistence/core-persistence.lifecycle.d.ts +9 -0
- package/dist/core/common/persistence/core-persistence.lifecycle.js +38 -0
- package/dist/core/common/persistence/core-persistence.lifecycle.js.map +1 -0
- package/dist/core/common/persistence/core-persistence.module.d.ts +9 -0
- package/dist/core/common/persistence/core-persistence.module.js +76 -0
- package/dist/core/common/persistence/core-persistence.module.js.map +1 -0
- package/dist/core/common/persistence/data-source.config.d.ts +33 -0
- package/dist/core/common/persistence/data-source.config.js +151 -0
- package/dist/core/common/persistence/data-source.config.js.map +1 -0
- package/dist/core/common/persistence/data-source.runtime.d.ts +45 -0
- package/dist/core/common/persistence/data-source.runtime.js +278 -0
- package/dist/core/common/persistence/data-source.runtime.js.map +1 -0
- package/dist/core/common/persistence/data-store.interface.d.ts +73 -0
- package/dist/core/common/persistence/data-store.interface.js +2 -0
- package/dist/core/common/persistence/data-store.interface.js.map +1 -0
- package/dist/core/common/persistence/expiry-sweep.d.ts +12 -0
- package/dist/core/common/persistence/expiry-sweep.js +55 -0
- package/dist/core/common/persistence/expiry-sweep.js.map +1 -0
- package/dist/core/common/persistence/id-format.d.ts +3 -0
- package/dist/core/common/persistence/id-format.js +21 -0
- package/dist/core/common/persistence/id-format.js.map +1 -0
- package/dist/core/common/persistence/infrastructure-locks.d.ts +13 -0
- package/dist/core/common/persistence/infrastructure-locks.js +35 -0
- package/dist/core/common/persistence/infrastructure-locks.js.map +1 -0
- package/dist/core/common/persistence/inject-store.decorator.d.ts +1 -0
- package/dist/core/common/persistence/inject-store.decorator.js +6 -0
- package/dist/core/common/persistence/inject-store.decorator.js.map +1 -0
- package/dist/core/common/persistence/lock-store.interface.d.ts +5 -0
- package/dist/core/common/persistence/lock-store.interface.js +2 -0
- package/dist/core/common/persistence/lock-store.interface.js.map +1 -0
- package/dist/core/common/persistence/model-descriptor.interface.d.ts +36 -0
- package/dist/core/common/persistence/model-descriptor.interface.js +2 -0
- package/dist/core/common/persistence/model-descriptor.interface.js.map +1 -0
- package/dist/core/common/persistence/model-metadata.registry.d.ts +14 -0
- package/dist/core/common/persistence/model-metadata.registry.js +194 -0
- package/dist/core/common/persistence/model-metadata.registry.js.map +1 -0
- package/dist/core/common/persistence/mongo/collection-name.d.ts +2 -0
- package/dist/core/common/persistence/mongo/collection-name.js +73 -0
- package/dist/core/common/persistence/mongo/collection-name.js.map +1 -0
- package/dist/core/common/persistence/mongo/declared-schema.view.d.ts +11 -0
- package/dist/core/common/persistence/mongo/declared-schema.view.js +292 -0
- package/dist/core/common/persistence/mongo/declared-schema.view.js.map +1 -0
- package/dist/core/common/persistence/mongo/hex-object-id.d.ts +13 -0
- package/dist/core/common/persistence/mongo/hex-object-id.js +54 -0
- package/dist/core/common/persistence/mongo/hex-object-id.js.map +1 -0
- package/dist/core/common/persistence/mongo/model-declarations.d.ts +35 -0
- package/dist/core/common/persistence/mongo/model-declarations.js +80 -0
- package/dist/core/common/persistence/mongo/model-declarations.js.map +1 -0
- package/dist/core/common/persistence/mongo/mongo-packages.d.ts +15 -0
- package/dist/core/common/persistence/mongo/mongo-packages.js +66 -0
- package/dist/core/common/persistence/mongo/mongo-packages.js.map +1 -0
- package/dist/core/common/persistence/mongo/mongoose-compat.d.ts +22 -0
- package/dist/core/common/persistence/mongo/mongoose-compat.js +65 -0
- package/dist/core/common/persistence/mongo/mongoose-compat.js.map +1 -0
- package/dist/core/common/persistence/mongo/no-mongo-connection.module.d.ts +2 -0
- package/dist/core/common/persistence/mongo/no-mongo-connection.module.js +19 -0
- package/dist/core/common/persistence/mongo/no-mongo-connection.module.js.map +1 -0
- package/dist/core/common/persistence/mongo-lock-store.d.ts +21 -0
- package/dist/core/common/persistence/mongo-lock-store.js +72 -0
- package/dist/core/common/persistence/mongo-lock-store.js.map +1 -0
- package/dist/core/common/persistence/mongoose-data-store.d.ts +33 -0
- package/dist/core/common/persistence/mongoose-data-store.js +187 -0
- package/dist/core/common/persistence/mongoose-data-store.js.map +1 -0
- package/dist/core/common/persistence/neutral-populate.d.ts +6 -0
- package/dist/core/common/persistence/neutral-populate.js +72 -0
- package/dist/core/common/persistence/neutral-populate.js.map +1 -0
- package/dist/core/common/persistence/persisted-model.decorator.d.ts +6 -0
- package/dist/core/common/persistence/persisted-model.decorator.js +24 -0
- package/dist/core/common/persistence/persisted-model.decorator.js.map +1 -0
- package/dist/core/common/persistence/persistence-runtime.registry.d.ts +61 -0
- package/dist/core/common/persistence/persistence-runtime.registry.js +47 -0
- package/dist/core/common/persistence/persistence-runtime.registry.js.map +1 -0
- package/dist/core/common/persistence/persistence.tokens.d.ts +1 -0
- package/dist/core/common/persistence/persistence.tokens.js +4 -0
- package/dist/core/common/persistence/persistence.tokens.js.map +1 -0
- package/dist/core/common/persistence/policies/audit.policy.d.ts +8 -0
- package/dist/core/common/persistence/policies/audit.policy.js +37 -0
- package/dist/core/common/persistence/policies/audit.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/password.policy.d.ts +3 -0
- package/dist/core/common/persistence/policies/password.policy.js +46 -0
- package/dist/core/common/persistence/policies/password.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/role-guard.policy.d.ts +3 -0
- package/dist/core/common/persistence/policies/role-guard.policy.js +46 -0
- package/dist/core/common/persistence/policies/role-guard.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/system-role.policy.d.ts +5 -0
- package/dist/core/common/persistence/policies/system-role.policy.js +46 -0
- package/dist/core/common/persistence/policies/system-role.policy.js.map +1 -0
- package/dist/core/common/persistence/policies/tenant.policy.d.ts +19 -0
- package/dist/core/common/persistence/policies/tenant.policy.js +120 -0
- package/dist/core/common/persistence/policies/tenant.policy.js.map +1 -0
- package/dist/core/common/persistence/routed-model.guard.d.ts +4 -0
- package/dist/core/common/persistence/routed-model.guard.js +73 -0
- package/dist/core/common/persistence/routed-model.guard.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.d.ts +46 -0
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.js +350 -0
- package/dist/core/common/persistence/sql/mysql/mysql-data-store.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-executor.d.ts +13 -0
- package/dist/core/common/persistence/sql/mysql/mysql-executor.js +194 -0
- package/dist/core/common/persistence/sql/mysql/mysql-executor.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-lock-store.d.ts +11 -0
- package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js +55 -0
- package/dist/core/common/persistence/sql/mysql/mysql-lock-store.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.d.ts +36 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js +288 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.d.ts +19 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js +328 -0
- package/dist/core/common/persistence/sql/mysql/mysql-schema.migrator.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-session.d.ts +13 -0
- package/dist/core/common/persistence/sql/mysql/mysql-session.js +85 -0
- package/dist/core/common/persistence/sql/mysql/mysql-session.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.d.ts +9 -0
- package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js +264 -0
- package/dist/core/common/persistence/sql/mysql/mysql-update.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.d.ts +20 -0
- package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js +519 -0
- package/dist/core/common/persistence/sql/mysql/mysql-where.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-lock-store.d.ts +11 -0
- package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js +44 -0
- package/dist/core/common/persistence/sql/postgres/postgres-lock-store.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.d.ts +42 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js +220 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.d.ts +12 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js +315 -0
- package/dist/core/common/persistence/sql/postgres/postgres-schema.migrator.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.d.ts +5 -0
- package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js +225 -0
- package/dist/core/common/persistence/sql/postgres/postgres-update.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.d.ts +13 -0
- package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js +484 -0
- package/dist/core/common/persistence/sql/postgres/postgres-where.compiler.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-cast.d.ts +2 -0
- package/dist/core/common/persistence/sql/sql-cast.js +194 -0
- package/dist/core/common/persistence/sql/sql-cast.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-data-store.d.ts +79 -0
- package/dist/core/common/persistence/sql/sql-data-store.js +592 -0
- package/dist/core/common/persistence/sql/sql-data-store.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-dialect.d.ts +20 -0
- package/dist/core/common/persistence/sql/sql-dialect.js +38 -0
- package/dist/core/common/persistence/sql/sql-dialect.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-errors.d.ts +17 -0
- package/dist/core/common/persistence/sql/sql-errors.js +25 -0
- package/dist/core/common/persistence/sql/sql-errors.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-executor.factory.d.ts +11 -0
- package/dist/core/common/persistence/sql/sql-executor.factory.js +199 -0
- package/dist/core/common/persistence/sql/sql-executor.factory.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-executor.interface.d.ts +32 -0
- package/dist/core/common/persistence/sql/sql-executor.interface.js +2 -0
- package/dist/core/common/persistence/sql/sql-executor.interface.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-naming.d.ts +15 -0
- package/dist/core/common/persistence/sql/sql-naming.js +90 -0
- package/dist/core/common/persistence/sql/sql-naming.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-schema.shared.d.ts +25 -0
- package/dist/core/common/persistence/sql/sql-schema.shared.js +69 -0
- package/dist/core/common/persistence/sql/sql-schema.shared.js.map +1 -0
- package/dist/core/common/persistence/sql/sql-session.d.ts +6 -0
- package/dist/core/common/persistence/sql/sql-session.js +78 -0
- package/dist/core/common/persistence/sql/sql-session.js.map +1 -0
- package/dist/core/common/persistence/sql/where-shared.d.ts +18 -0
- package/dist/core/common/persistence/sql/where-shared.js +93 -0
- package/dist/core/common/persistence/sql/where-shared.js.map +1 -0
- package/dist/core/common/persistence/store-guards.d.ts +10 -0
- package/dist/core/common/persistence/store-guards.js +49 -0
- package/dist/core/common/persistence/store-guards.js.map +1 -0
- package/dist/core/common/persistence/store-upsert.d.ts +2 -0
- package/dist/core/common/persistence/store-upsert.js +20 -0
- package/dist/core/common/persistence/store-upsert.js.map +1 -0
- package/dist/core/common/persistence/unavailable-store.d.ts +2 -0
- package/dist/core/common/persistence/unavailable-store.js +53 -0
- package/dist/core/common/persistence/unavailable-store.js.map +1 -0
- package/dist/core/common/persistence/unsupported-capability.error.d.ts +3 -0
- package/dist/core/common/persistence/unsupported-capability.error.js +4 -0
- package/dist/core/common/persistence/unsupported-capability.error.js.map +1 -0
- package/dist/core/common/plugins/mongoose-audit-fields.plugin.js +24 -68
- package/dist/core/common/plugins/mongoose-audit-fields.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-id.plugin.js +3 -0
- package/dist/core/common/plugins/mongoose-id.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-password.plugin.d.ts +1 -3
- package/dist/core/common/plugins/mongoose-password.plugin.js +2 -45
- package/dist/core/common/plugins/mongoose-password.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-role-guard.plugin.js +5 -46
- package/dist/core/common/plugins/mongoose-role-guard.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-system-role.plugin.js +2 -43
- package/dist/core/common/plugins/mongoose-system-role.plugin.js.map +1 -1
- package/dist/core/common/plugins/mongoose-tenant.plugin.js +10 -70
- package/dist/core/common/plugins/mongoose-tenant.plugin.js.map +1 -1
- package/dist/core/common/scalars/upload.scalar.js +1 -1
- package/dist/core/common/scalars/upload.scalar.js.map +1 -1
- package/dist/core/common/services/core-cron-jobs.initializer.js +1 -1
- package/dist/core/common/services/core-cron-jobs.initializer.js.map +1 -1
- package/dist/core/common/services/core-cron-jobs.service.d.ts +1 -0
- package/dist/core/common/services/core-cron-jobs.service.js +23 -14
- package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
- package/dist/core/common/services/crud.service.d.ts +4 -1
- package/dist/core/common/services/crud.service.js +132 -23
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/common/services/model-doc.service.js +1 -1
- package/dist/core/common/services/model-doc.service.js.map +1 -1
- package/dist/core/common/services/module.service.d.ts +9 -2
- package/dist/core/common/services/module.service.js +51 -6
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/core/common/types/field-selection.type.d.ts +1 -1
- package/dist/core/common/types/id.type.d.ts +4 -4
- package/dist/core/common/types/object-id-like.type.d.ts +3 -0
- package/dist/core/common/types/object-id-like.type.js +2 -0
- package/dist/core/common/types/object-id-like.type.js.map +1 -0
- package/dist/core/common/types/populate-config.type.d.ts +1 -1
- package/dist/core/common/types/string-or-object-id.type.d.ts +2 -2
- package/dist/core/modules/ai/core-ai.constants.d.ts +4 -0
- package/dist/core/modules/ai/core-ai.constants.js +4 -0
- package/dist/core/modules/ai/core-ai.constants.js.map +1 -1
- package/dist/core/modules/ai/core-ai.module.js +21 -17
- package/dist/core/modules/ai/core-ai.module.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-budget-limit.model.d.ts +2 -92
- package/dist/core/modules/ai/models/core-ai-budget-limit.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-budget-limit.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-connection-preference.model.d.ts +2 -87
- package/dist/core/modules/ai/models/core-ai-connection-preference.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-connection-preference.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-connection.model.d.ts +2 -177
- package/dist/core/modules/ai/models/core-ai-connection.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-connection.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-conversation.model.d.ts +2 -92
- package/dist/core/modules/ai/models/core-ai-conversation.model.js +3 -4
- package/dist/core/modules/ai/models/core-ai-conversation.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-interaction.model.d.ts +2 -120
- package/dist/core/modules/ai/models/core-ai-interaction.model.js +2 -3
- package/dist/core/modules/ai/models/core-ai-interaction.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.d.ts +3 -0
- package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js +21 -0
- package/dist/core/modules/ai/models/core-ai-mcp-oauth.models.js.map +1 -0
- package/dist/core/modules/ai/models/core-ai-mode.model.d.ts +2 -102
- package/dist/core/modules/ai/models/core-ai-mode.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-mode.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt-hint.model.d.ts +2 -97
- package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt-hint.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt.model.d.ts +2 -112
- package/dist/core/modules/ai/models/core-ai-prompt.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-prompt.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-slot.model.d.ts +2 -112
- package/dist/core/modules/ai/models/core-ai-slot.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-slot.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-grant.model.d.ts +2 -97
- package/dist/core/modules/ai/models/core-ai-tool-grant.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-grant.model.js.map +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-policy.model.d.ts +2 -103
- package/dist/core/modules/ai/models/core-ai-tool-policy.model.js +1 -1
- package/dist/core/modules/ai/models/core-ai-tool-policy.model.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-budget.service.d.ts +3 -1
- package/dist/core/modules/ai/services/core-ai-budget.service.js +15 -5
- package/dist/core/modules/ai/services/core-ai-budget.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-connection-preference.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-connection-preference.service.js +6 -10
- package/dist/core/modules/ai/services/core-ai-connection-preference.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-connection.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-connection.service.js +20 -42
- package/dist/core/modules/ai/services/core-ai-connection.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-conversation.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-conversation.service.js +28 -29
- package/dist/core/modules/ai/services/core-ai-conversation.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-interaction.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-interaction.service.js +3 -4
- package/dist/core/modules/ai/services/core-ai-interaction.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.d.ts +8 -0
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js +70 -18
- package/dist/core/modules/ai/services/core-ai-mcp-oauth.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-mode.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-mode.service.js +3 -7
- package/dist/core/modules/ai/services/core-ai-mode.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-prompt-hint.service.d.ts +8 -1
- package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js +32 -26
- package/dist/core/modules/ai/services/core-ai-prompt-hint.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-prompt.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-prompt.service.js +10 -13
- package/dist/core/modules/ai/services/core-ai-prompt.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-slot.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-slot.service.js +14 -25
- package/dist/core/modules/ai/services/core-ai-slot.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-grant.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-grant.service.js +6 -18
- package/dist/core/modules/ai/services/core-ai-tool-grant.service.js.map +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-policy.service.d.ts +1 -1
- package/dist/core/modules/ai/services/core-ai-tool-policy.service.js +4 -8
- package/dist/core/modules/ai/services/core-ai-tool-policy.service.js.map +1 -1
- package/dist/core/modules/api-token/core-api-token.model.js +1 -1
- package/dist/core/modules/api-token/core-api-token.model.js.map +1 -1
- package/dist/core/modules/api-token/core-api-token.module.js +3 -2
- package/dist/core/modules/api-token/core-api-token.module.js.map +1 -1
- package/dist/core/modules/api-token/core-api-token.service.d.ts +8 -2
- package/dist/core/modules/api-token/core-api-token.service.js +106 -39
- package/dist/core/modules/api-token/core-api-token.service.js.map +1 -1
- package/dist/core/modules/auth/core-auth.module.js +2 -0
- package/dist/core/modules/auth/core-auth.module.js.map +1 -1
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +1 -2
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -1
- package/dist/core/modules/auth/guards/role-guard.token.d.ts +1 -0
- package/dist/core/modules/auth/guards/role-guard.token.js +2 -0
- package/dist/core/modules/auth/guards/role-guard.token.js.map +1 -0
- package/dist/core/modules/auth/services/core-auth.service.js +4 -2
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-sql.helper.d.ts +6 -0
- package/dist/core/modules/better-auth/better-auth-sql.helper.js +113 -0
- package/dist/core/modules/better-auth/better-auth-sql.helper.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-token.service.d.ts +3 -1
- package/dist/core/modules/better-auth/better-auth-token.service.js +15 -24
- package/dist/core/modules/better-auth/better-auth-token.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.config.d.ts +7 -0
- package/dist/core/modules/better-auth/better-auth.config.js +16 -5
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +1 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +6 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js +30 -15
- package/dist/core/modules/better-auth/core-better-auth-challenge.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-mongo.users.d.ts +10 -0
- package/dist/core/modules/better-auth/core-better-auth-mongo.users.js +24 -0
- package/dist/core/modules/better-auth/core-better-auth-mongo.users.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.registry.d.ts +3 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.registry.js +8 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.registry.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.store.d.ts +71 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.store.js +190 -0
- package/dist/core/modules/better-auth/core-better-auth-sql.store.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.d.ts +24 -1
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +308 -32
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.d.ts +2 -0
- package/dist/core/modules/better-auth/core-better-auth.module.js +54 -32
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.d.ts +7 -2
- package/dist/core/modules/better-auth/core-better-auth.service.js +61 -9
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/core/modules/file/core-file-info.model.d.ts +1 -2
- package/dist/core/modules/file/core-file-info.model.js +2 -2
- package/dist/core/modules/file/core-file-info.model.js.map +1 -1
- package/dist/core/modules/file/core-file.service.d.ts +5 -3
- package/dist/core/modules/file/core-file.service.js +16 -9
- package/dist/core/modules/file/core-file.service.js.map +1 -1
- package/dist/core/modules/file/file-metadata.helper.d.ts +1 -1
- package/dist/core/modules/file/file-metadata.helper.js +2 -2
- package/dist/core/modules/file/file-metadata.helper.js.map +1 -1
- package/dist/core/modules/file/file-metadata.models.d.ts +35 -0
- package/dist/core/modules/file/file-metadata.models.js +20 -0
- package/dist/core/modules/file/file-metadata.models.js.map +1 -0
- package/dist/core/modules/file/file-metadata.store.d.ts +6 -0
- package/dist/core/modules/file/file-metadata.store.js +77 -0
- package/dist/core/modules/file/file-metadata.store.js.map +1 -0
- package/dist/core/modules/file/file-storage.helper.d.ts +1 -0
- package/dist/core/modules/file/file-storage.helper.js +34 -0
- package/dist/core/modules/file/file-storage.helper.js.map +1 -1
- package/dist/core/modules/file/filesystem-file.helper.d.ts +1 -1
- package/dist/core/modules/file/filesystem-file.helper.js +4 -4
- package/dist/core/modules/file/filesystem-file.helper.js.map +1 -1
- package/dist/core/modules/file/s3-file.helper.d.ts +1 -1
- package/dist/core/modules/file/s3-file.helper.js +5 -5
- package/dist/core/modules/file/s3-file.helper.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.module.js +12 -2
- package/dist/core/modules/health-check/core-health-check.module.js.map +1 -1
- package/dist/core/modules/health-check/core-health-check.service.d.ts +4 -3
- package/dist/core/modules/health-check/core-health-check.service.js +26 -5
- package/dist/core/modules/health-check/core-health-check.service.js.map +1 -1
- package/dist/core/modules/hub/core-hub.controller.d.ts +1 -0
- package/dist/core/modules/hub/core-hub.controller.js +10 -0
- package/dist/core/modules/hub/core-hub.controller.js.map +1 -1
- package/dist/core/modules/hub/core-hub.service.js +1 -1
- package/dist/core/modules/hub/core-hub.service.js.map +1 -1
- package/dist/core/modules/hub/helpers/hub-client-js.helper.js +23 -0
- package/dist/core/modules/hub/helpers/hub-client-js.helper.js.map +1 -1
- package/dist/core/modules/hub/hub-action-messages.d.ts +2 -0
- package/dist/core/modules/hub/hub-action-messages.js +2 -0
- package/dist/core/modules/hub/hub-action-messages.js.map +1 -1
- package/dist/core/modules/hub/hub-nav.js +1 -0
- package/dist/core/modules/hub/hub-nav.js.map +1 -1
- package/dist/core/modules/hub/interfaces/hub-panels.interface.d.ts +17 -1
- package/dist/core/modules/hub/services/core-hub-db.service.d.ts +6 -1
- package/dist/core/modules/hub/services/core-hub-db.service.js +16 -14
- package/dist/core/modules/hub/services/core-hub-db.service.js.map +1 -1
- package/dist/core/modules/hub/services/core-hub-migrations.service.d.ts +5 -0
- package/dist/core/modules/hub/services/core-hub-migrations.service.js +74 -1
- package/dist/core/modules/hub/services/core-hub-migrations.service.js.map +1 -1
- package/dist/core/modules/hub/services/core-hub-sources.service.d.ts +2 -1
- package/dist/core/modules/hub/services/core-hub-sources.service.js +32 -0
- package/dist/core/modules/hub/services/core-hub-sources.service.js.map +1 -1
- package/dist/core/modules/hub/services/hub-query-profiler.service.js +1 -1
- package/dist/core/modules/hub/services/hub-query-profiler.service.js.map +1 -1
- package/dist/core/modules/migrate/cli/migrate-cli.d.ts +2 -0
- package/dist/core/modules/migrate/cli/migrate-cli.js +35 -1
- package/dist/core/modules/migrate/cli/migrate-cli.js.map +1 -1
- package/dist/core/modules/migrate/index.d.ts +3 -0
- package/dist/core/modules/migrate/index.js +3 -0
- package/dist/core/modules/migrate/index.js.map +1 -1
- package/dist/core/modules/migrate/migration-runner.d.ts +2 -2
- package/dist/core/modules/migrate/migration-runner.js.map +1 -1
- package/dist/core/modules/migrate/migration-state-store.interface.d.ts +16 -0
- package/dist/core/modules/migrate/migration-state-store.interface.js +2 -0
- package/dist/core/modules/migrate/migration-state-store.interface.js.map +1 -0
- package/dist/core/modules/migrate/migration.helper.d.ts +3 -2
- package/dist/core/modules/migrate/migration.helper.js +21 -6
- package/dist/core/modules/migrate/migration.helper.js.map +1 -1
- package/dist/core/modules/migrate/mongo-state-store.d.ts +5 -12
- package/dist/core/modules/migrate/mongo-state-store.js +30 -24
- package/dist/core/modules/migrate/mongo-state-store.js.map +1 -1
- package/dist/core/modules/migrate/sql-migration.helper.d.ts +4 -0
- package/dist/core/modules/migrate/sql-migration.helper.js +34 -0
- package/dist/core/modules/migrate/sql-migration.helper.js.map +1 -0
- package/dist/core/modules/migrate/sql-state-store.d.ts +24 -0
- package/dist/core/modules/migrate/sql-state-store.js +129 -0
- package/dist/core/modules/migrate/sql-state-store.js.map +1 -0
- package/dist/core/modules/system-setup/core-system-setup.service.d.ts +8 -0
- package/dist/core/modules/system-setup/core-system-setup.service.js +41 -25
- package/dist/core/modules/system-setup/core-system-setup.service.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant-member.model.js +1 -1
- package/dist/core/modules/tenant/core-tenant-member.model.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant-member.store.d.ts +2 -0
- package/dist/core/modules/tenant/core-tenant-member.store.js +6 -0
- package/dist/core/modules/tenant/core-tenant-member.store.js.map +1 -0
- package/dist/core/modules/tenant/core-tenant.guard.d.ts +8 -3
- package/dist/core/modules/tenant/core-tenant.guard.js +57 -28
- package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.module.js +3 -2
- package/dist/core/modules/tenant/core-tenant.module.js.map +1 -1
- package/dist/core/modules/tenant/core-tenant.service.d.ts +3 -1
- package/dist/core/modules/tenant/core-tenant.service.js +48 -28
- package/dist/core/modules/tenant/core-tenant.service.js.map +1 -1
- package/dist/core/modules/tus/core-tus.service.d.ts +1 -1
- package/dist/core/modules/tus/core-tus.service.js +8 -7
- package/dist/core/modules/tus/core-tus.service.js.map +1 -1
- package/dist/core/modules/tus/tus.module.js +1 -1
- package/dist/core/modules/tus/tus.module.js.map +1 -1
- package/dist/core/modules/user/core-user.model.d.ts +1 -1
- package/dist/core/modules/user/core-user.model.js +1 -1
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/core/modules/user/core-user.service.d.ts +3 -1
- package/dist/core/modules/user/core-user.service.js +71 -16
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core.module.js +39 -5
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +26 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -1
- package/dist/server/common/models/persistence.model.d.ts +1 -1
- package/dist/server/common/models/persistence.model.js +3 -3
- package/dist/server/common/models/persistence.model.js.map +1 -1
- package/dist/server/modules/file/file-info.model.d.ts +1 -77
- package/dist/server/modules/file/file-info.model.js +1 -1
- package/dist/server/modules/file/file-info.model.js.map +1 -1
- package/dist/server/modules/file/file.service.js +1 -1
- package/dist/server/modules/file/file.service.js.map +1 -1
- package/dist/server/modules/user/user.model.d.ts +2 -186
- package/dist/server/modules/user/user.model.js +4 -5
- package/dist/server/modules/user/user.model.js.map +1 -1
- package/dist/server/modules/user/user.module.js +4 -3
- package/dist/server/modules/user/user.module.js.map +1 -1
- package/dist/server/modules/user/user.service.d.ts +1 -1
- package/dist/server/modules/user/user.service.js +5 -8
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/test/test.helper.js +2 -2
- package/dist/test/test.helper.js.map +1 -1
- package/dist/types/graphql-upload.d.ts +10 -7
- package/docs/REQUEST-LIFECYCLE.md +6 -3
- package/docs/choosing-a-database.md +107 -0
- package/docs/native-driver-security.md +29 -0
- package/docs/security-overrides.md +15 -6
- package/migration-guides/12.0.x-to-12.1.x.md +255 -0
- package/package.json +75 -29
- package/src/core/common/decorators/unified-field.decorator.ts +11 -1
- package/src/core/common/filters/mongoose-cast-error.filter.ts +12 -6
- package/src/core/common/helpers/db.helper.ts +40 -25
- package/src/core/common/helpers/decorator.helper.ts +1 -1
- package/src/core/common/helpers/filter.helper.ts +2 -1
- package/src/core/common/helpers/gridfs.helper.ts +28 -9
- package/src/core/common/helpers/id.helper.ts +21 -4
- package/src/core/common/helpers/model.helper.ts +5 -6
- package/src/core/common/helpers/service.helper.ts +3 -3
- package/src/core/common/interfaces/server-options.interface.ts +118 -10
- package/src/core/common/interfaces/service-options.interface.ts +2 -2
- package/src/core/common/models/core-persistence.model.ts +3 -3
- package/src/core/common/persistence/core-persistence.lifecycle.ts +47 -0
- package/src/core/common/persistence/core-persistence.module.ts +109 -0
- package/src/core/common/persistence/data-source.config.ts +271 -0
- package/src/core/common/persistence/data-source.runtime.ts +351 -0
- package/src/core/common/persistence/data-store.interface.ts +155 -0
- package/src/core/common/persistence/expiry-sweep.ts +105 -0
- package/src/core/common/persistence/id-format.ts +43 -0
- package/src/core/common/persistence/infrastructure-locks.ts +66 -0
- package/src/core/common/persistence/inject-store.decorator.ts +16 -0
- package/src/core/common/persistence/lock-store.interface.ts +17 -0
- package/src/core/common/persistence/model-descriptor.interface.ts +90 -0
- package/src/core/common/persistence/model-metadata.registry.ts +285 -0
- package/src/core/common/persistence/mongo/collection-name.ts +87 -0
- package/src/core/common/persistence/mongo/declared-schema.view.ts +378 -0
- package/src/core/common/persistence/mongo/hex-object-id.ts +75 -0
- package/src/core/common/persistence/mongo/model-declarations.ts +135 -0
- package/src/core/common/persistence/mongo/mongo-packages.ts +130 -0
- package/src/core/common/persistence/mongo/mongoose-compat.ts +129 -0
- package/src/core/common/persistence/mongo/no-mongo-connection.module.ts +18 -0
- package/src/core/common/persistence/mongo-lock-store.ts +121 -0
- package/src/core/common/persistence/mongoose-data-store.ts +232 -0
- package/src/core/common/persistence/neutral-populate.ts +98 -0
- package/src/core/common/persistence/persisted-model.decorator.ts +61 -0
- package/src/core/common/persistence/persistence-runtime.registry.ts +152 -0
- package/src/core/common/persistence/persistence.tokens.ts +9 -0
- package/src/core/common/persistence/policies/audit.policy.ts +80 -0
- package/src/core/common/persistence/policies/password.policy.ts +69 -0
- package/src/core/common/persistence/policies/role-guard.policy.ts +74 -0
- package/src/core/common/persistence/policies/system-role.policy.ts +90 -0
- package/src/core/common/persistence/policies/tenant.policy.ts +245 -0
- package/src/core/common/persistence/routed-model.guard.ts +107 -0
- package/src/core/common/persistence/sql/mysql/mysql-data-store.ts +503 -0
- package/src/core/common/persistence/sql/mysql/mysql-executor.ts +281 -0
- package/src/core/common/persistence/sql/mysql/mysql-lock-store.ts +87 -0
- package/src/core/common/persistence/sql/mysql/mysql-schema.compiler.ts +424 -0
- package/src/core/common/persistence/sql/mysql/mysql-schema.migrator.ts +453 -0
- package/src/core/common/persistence/sql/mysql/mysql-session.ts +131 -0
- package/src/core/common/persistence/sql/mysql/mysql-update.compiler.ts +379 -0
- package/src/core/common/persistence/sql/mysql/mysql-where.compiler.ts +686 -0
- package/src/core/common/persistence/sql/postgres/postgres-lock-store.ts +76 -0
- package/src/core/common/persistence/sql/postgres/postgres-schema.compiler.ts +328 -0
- package/src/core/common/persistence/sql/postgres/postgres-schema.migrator.ts +448 -0
- package/src/core/common/persistence/sql/postgres/postgres-update.compiler.ts +310 -0
- package/src/core/common/persistence/sql/postgres/postgres-where.compiler.ts +638 -0
- package/src/core/common/persistence/sql/sql-cast.ts +227 -0
- package/src/core/common/persistence/sql/sql-data-store.ts +762 -0
- package/src/core/common/persistence/sql/sql-dialect.ts +85 -0
- package/src/core/common/persistence/sql/sql-errors.ts +49 -0
- package/src/core/common/persistence/sql/sql-executor.factory.ts +282 -0
- package/src/core/common/persistence/sql/sql-executor.interface.ts +57 -0
- package/src/core/common/persistence/sql/sql-naming.ts +133 -0
- package/src/core/common/persistence/sql/sql-schema.shared.ts +105 -0
- package/src/core/common/persistence/sql/sql-session.ts +158 -0
- package/src/core/common/persistence/sql/where-shared.ts +118 -0
- package/src/core/common/persistence/store-guards.ts +73 -0
- package/src/core/common/persistence/store-upsert.ts +36 -0
- package/src/core/common/persistence/unavailable-store.ts +63 -0
- package/src/core/common/persistence/unsupported-capability.error.ts +7 -0
- package/src/core/common/plugins/mongoose-audit-fields.plugin.ts +33 -74
- package/src/core/common/plugins/mongoose-id.plugin.ts +9 -0
- package/src/core/common/plugins/mongoose-password.plugin.ts +6 -62
- package/src/core/common/plugins/mongoose-role-guard.plugin.ts +11 -63
- package/src/core/common/plugins/mongoose-system-role.plugin.ts +7 -78
- package/src/core/common/plugins/mongoose-tenant.plugin.ts +23 -144
- package/src/core/common/scalars/upload.scalar.ts +8 -3
- package/src/core/common/services/core-cron-jobs.initializer.ts +1 -1
- package/src/core/common/services/core-cron-jobs.service.ts +33 -22
- package/src/core/common/services/crud.service.ts +166 -35
- package/src/core/common/services/model-doc.service.ts +1 -1
- package/src/core/common/services/module.service.ts +78 -6
- package/src/core/common/types/field-selection.type.ts +1 -1
- package/src/core/common/types/id.type.ts +2 -2
- package/src/core/common/types/object-id-like.type.ts +11 -0
- package/src/core/common/types/populate-config.type.ts +1 -1
- package/src/core/common/types/string-or-object-id.type.ts +2 -2
- package/src/core/modules/ai/README.md +15 -2
- package/src/core/modules/ai/core-ai.constants.ts +10 -0
- package/src/core/modules/ai/core-ai.module.ts +32 -17
- package/src/core/modules/ai/models/core-ai-budget-limit.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-connection-preference.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-connection.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-conversation.model.ts +8 -4
- package/src/core/modules/ai/models/core-ai-interaction.model.ts +3 -3
- package/src/core/modules/ai/models/core-ai-mcp-oauth.models.ts +46 -0
- package/src/core/modules/ai/models/core-ai-mode.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-prompt-hint.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-prompt.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-slot.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-tool-grant.model.ts +2 -2
- package/src/core/modules/ai/models/core-ai-tool-policy.model.ts +2 -2
- package/src/core/modules/ai/services/core-ai-budget.service.ts +22 -4
- package/src/core/modules/ai/services/core-ai-connection-preference.service.ts +6 -13
- package/src/core/modules/ai/services/core-ai-connection.service.ts +34 -44
- package/src/core/modules/ai/services/core-ai-conversation.service.ts +31 -29
- package/src/core/modules/ai/services/core-ai-interaction.service.ts +3 -3
- package/src/core/modules/ai/services/core-ai-mcp-oauth.service.ts +93 -20
- package/src/core/modules/ai/services/core-ai-mode.service.ts +3 -6
- package/src/core/modules/ai/services/core-ai-prompt-hint.service.ts +43 -26
- package/src/core/modules/ai/services/core-ai-prompt.service.ts +15 -12
- package/src/core/modules/ai/services/core-ai-slot.service.ts +20 -24
- package/src/core/modules/ai/services/core-ai-tool-grant.service.ts +17 -27
- package/src/core/modules/ai/services/core-ai-tool-policy.service.ts +7 -10
- package/src/core/modules/api-token/core-api-token.model.ts +1 -1
- package/src/core/modules/api-token/core-api-token.module.ts +4 -2
- package/src/core/modules/api-token/core-api-token.service.ts +118 -43
- package/src/core/modules/auth/core-auth.module.ts +2 -0
- package/src/core/modules/auth/guards/legacy-auth-rate-limit.guard.ts +4 -3
- package/src/core/modules/auth/guards/role-guard.token.ts +7 -0
- package/src/core/modules/auth/services/core-auth.service.ts +16 -2
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +1 -1
- package/src/core/modules/better-auth/README.md +10 -1
- package/src/core/modules/better-auth/better-auth-sql.helper.ts +191 -0
- package/src/core/modules/better-auth/better-auth-token.service.ts +26 -35
- package/src/core/modules/better-auth/better-auth.config.ts +43 -7
- package/src/core/modules/better-auth/better-auth.types.ts +1 -1
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +13 -1
- package/src/core/modules/better-auth/core-better-auth-challenge.service.ts +36 -18
- package/src/core/modules/better-auth/core-better-auth-mongo.users.ts +35 -0
- package/src/core/modules/better-auth/core-better-auth-sql.registry.ts +20 -0
- package/src/core/modules/better-auth/core-better-auth-sql.store.ts +309 -0
- package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +418 -40
- package/src/core/modules/better-auth/core-better-auth.module.ts +71 -35
- package/src/core/modules/better-auth/core-better-auth.service.ts +81 -12
- package/src/core/modules/file/README.md +16 -3
- package/src/core/modules/file/core-file-info.model.ts +2 -2
- package/src/core/modules/file/core-file.service.ts +27 -18
- package/src/core/modules/file/file-metadata.helper.ts +7 -3
- package/src/core/modules/file/file-metadata.models.ts +44 -0
- package/src/core/modules/file/file-metadata.store.ts +109 -0
- package/src/core/modules/file/file-storage.helper.ts +47 -2
- package/src/core/modules/file/filesystem-file.helper.ts +11 -8
- package/src/core/modules/file/s3-file.helper.ts +11 -7
- package/src/core/modules/health-check/core-health-check.module.ts +16 -2
- package/src/core/modules/health-check/core-health-check.service.ts +25 -3
- package/src/core/modules/hub/README.md +20 -11
- package/src/core/modules/hub/core-hub.controller.ts +5 -0
- package/src/core/modules/hub/core-hub.service.ts +1 -1
- package/src/core/modules/hub/helpers/hub-client-js.helper.ts +23 -0
- package/src/core/modules/hub/hub-action-messages.ts +6 -0
- package/src/core/modules/hub/hub-nav.ts +1 -0
- package/src/core/modules/hub/interfaces/hub-panels.interface.ts +8 -1
- package/src/core/modules/hub/services/core-hub-db.service.ts +35 -17
- package/src/core/modules/hub/services/core-hub-migrations.service.ts +96 -2
- package/src/core/modules/hub/services/core-hub-sources.service.ts +47 -1
- package/src/core/modules/hub/services/hub-query-profiler.service.ts +1 -1
- package/src/core/modules/migrate/README.md +54 -0
- package/src/core/modules/migrate/cli/migrate-cli.ts +44 -3
- package/src/core/modules/migrate/index.ts +3 -0
- package/src/core/modules/migrate/migration-runner.ts +3 -2
- package/src/core/modules/migrate/migration-state-store.interface.ts +24 -0
- package/src/core/modules/migrate/migration.helper.ts +35 -10
- package/src/core/modules/migrate/mongo-state-store.ts +64 -65
- package/src/core/modules/migrate/sql-migration.helper.ts +48 -0
- package/src/core/modules/migrate/sql-state-store.ts +198 -0
- package/src/core/modules/system-setup/README.md +14 -2
- package/src/core/modules/system-setup/core-system-setup.service.ts +77 -45
- package/src/core/modules/tenant/README.md +9 -2
- package/src/core/modules/tenant/core-tenant-member.model.ts +1 -1
- package/src/core/modules/tenant/core-tenant-member.store.ts +13 -0
- package/src/core/modules/tenant/core-tenant.guard.ts +77 -24
- package/src/core/modules/tenant/core-tenant.module.ts +6 -3
- package/src/core/modules/tenant/core-tenant.service.ts +59 -42
- package/src/core/modules/tus/core-tus.service.ts +11 -12
- package/src/core/modules/tus/tus.module.ts +1 -1
- package/src/core/modules/user/core-user.model.ts +2 -2
- package/src/core/modules/user/core-user.service.ts +98 -20
- package/src/core.module.ts +60 -5
- package/src/index.ts +26 -0
- package/src/server/common/models/persistence.model.ts +4 -4
- package/src/server/modules/file/file-info.model.ts +1 -1
- package/src/server/modules/file/file.service.ts +1 -1
- package/src/server/modules/user/user.model.ts +10 -5
- package/src/server/modules/user/user.module.ts +9 -3
- package/src/server/modules/user/user.service.ts +9 -11
- package/src/test/test.helper.ts +2 -2
- package/src/types/graphql-upload.d.ts +10 -7
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Injectable, Logger, Optional } from '@nestjs/common';
|
|
2
|
-
import { InjectConnection } from '
|
|
2
|
+
import { InjectConnection } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
3
3
|
import * as bcrypt from 'bcrypt';
|
|
4
4
|
import { randomBytes, scrypt, ScryptOptions } from 'crypto';
|
|
5
5
|
import { sha256 } from 'js-sha256';
|
|
6
|
-
import { ObjectId } from 'mongodb';
|
|
6
|
+
import type { ObjectId } from 'mongodb';
|
|
7
7
|
import type { Connection } from 'mongoose';
|
|
8
8
|
|
|
9
9
|
// Promisify Node.js crypto.scrypt
|
|
@@ -19,6 +19,9 @@ const scryptPromise = (password: string, salt: string, keylen: number, options:
|
|
|
19
19
|
import { RoleEnum } from '../../common/enums/role.enum.js';
|
|
20
20
|
import { maskEmail } from '../../common/helpers/logging.helper.js';
|
|
21
21
|
import { legacyCredentialAccountIssuer } from './core-better-auth-account-issuer.helper.js';
|
|
22
|
+
import { getBetterAuthSqlStore } from './core-better-auth-sql.registry.js';
|
|
23
|
+
import type { BetterAuthSqlStore } from './core-better-auth-sql.store.js';
|
|
24
|
+
import { isValidObjectId, newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* Interface for Better-Auth session user
|
|
@@ -183,7 +186,8 @@ export class CoreBetterAuthUserMapper {
|
|
|
183
186
|
}
|
|
184
187
|
|
|
185
188
|
// If no database connection, return user with default roles
|
|
186
|
-
|
|
189
|
+
const sql = getBetterAuthSqlStore();
|
|
190
|
+
if (!this.connection && !sql) {
|
|
187
191
|
this.logger.warn('No database connection available - using default role mapping');
|
|
188
192
|
return this.createMappedUser({
|
|
189
193
|
email: sessionUser.email,
|
|
@@ -217,10 +221,12 @@ export class CoreBetterAuthUserMapper {
|
|
|
217
221
|
|
|
218
222
|
// Look up the user in our database by email OR iamId
|
|
219
223
|
// This ensures we find the user regardless of which system they signed up with
|
|
220
|
-
|
|
221
|
-
const dbUser =
|
|
222
|
-
|
|
223
|
-
|
|
224
|
+
// (on SQL, Better-Auth's user id IS the row's id — one row per user)
|
|
225
|
+
const dbUser = sql
|
|
226
|
+
? await sql.findUser({ email: sessionUser.email, iamId: sessionUser.id, id: sessionUser.id })
|
|
227
|
+
: await this.connection?.collection('users').findOne({
|
|
228
|
+
$or: [{ email: sessionUser.email }, { iamId: sessionUser.id }],
|
|
229
|
+
});
|
|
224
230
|
|
|
225
231
|
if (dbUser) {
|
|
226
232
|
// User exists in our database - use their roles and verified status
|
|
@@ -230,14 +236,14 @@ export class CoreBetterAuthUserMapper {
|
|
|
230
236
|
|
|
231
237
|
// Cache only the minimal data needed (not the full document)
|
|
232
238
|
if (CoreBetterAuthUserMapper.USER_CACHE_TTL_MS > 0) {
|
|
233
|
-
this.cacheUserData(sessionUser.id, { id: dbUser._id.
|
|
239
|
+
this.cacheUserData(sessionUser.id, { id: String(dbUser._id ?? dbUser.id), roles, verified });
|
|
234
240
|
}
|
|
235
241
|
|
|
236
242
|
return this.createMappedUser({
|
|
237
243
|
email: sessionUser.email,
|
|
238
244
|
emailVerified: sessionUser.emailVerified,
|
|
239
245
|
iamId: sessionUser.id,
|
|
240
|
-
id: dbUser._id.
|
|
246
|
+
id: String(dbUser._id ?? dbUser.id),
|
|
241
247
|
image: sessionUser.image,
|
|
242
248
|
name: sessionUser.name,
|
|
243
249
|
roles,
|
|
@@ -344,6 +350,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
344
350
|
* @returns true if sync was successful, false otherwise
|
|
345
351
|
*/
|
|
346
352
|
async syncPasswordToLegacy(iamUserId: string, userEmail: string, plainPassword?: string): Promise<boolean> {
|
|
353
|
+
const sql = getBetterAuthSqlStore();
|
|
354
|
+
if (sql) {
|
|
355
|
+
return this.syncPasswordToLegacyOnSql(sql, iamUserId, userEmail, plainPassword);
|
|
356
|
+
}
|
|
347
357
|
if (!this.connection) {
|
|
348
358
|
this.logger.warn('No database connection available - cannot sync password to legacy');
|
|
349
359
|
return false;
|
|
@@ -403,6 +413,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
403
413
|
* @returns true if sync was successful, false otherwise
|
|
404
414
|
*/
|
|
405
415
|
async syncPasswordChangeToIam(userEmail: string, plainPassword: string): Promise<boolean> {
|
|
416
|
+
const sql = getBetterAuthSqlStore();
|
|
417
|
+
if (sql) {
|
|
418
|
+
return this.syncPasswordChangeToIamOnSql(sql, userEmail, plainPassword);
|
|
419
|
+
}
|
|
406
420
|
if (!this.connection) {
|
|
407
421
|
this.logger.warn('No database connection available - cannot sync password to IAM');
|
|
408
422
|
return false;
|
|
@@ -466,6 +480,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
466
480
|
* @returns true if account was created, false otherwise
|
|
467
481
|
*/
|
|
468
482
|
async migrateAccountToIam(userEmail: string, plainPassword?: string): Promise<boolean> {
|
|
483
|
+
const sql = getBetterAuthSqlStore();
|
|
484
|
+
if (sql) {
|
|
485
|
+
return this.migrateAccountToIamOnSql(sql, userEmail, plainPassword);
|
|
486
|
+
}
|
|
469
487
|
if (!this.connection) {
|
|
470
488
|
return false;
|
|
471
489
|
}
|
|
@@ -665,6 +683,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
665
683
|
if (!sessionUser?.email) {
|
|
666
684
|
return null;
|
|
667
685
|
}
|
|
686
|
+
const sql = getBetterAuthSqlStore();
|
|
687
|
+
if (sql) {
|
|
688
|
+
return this.linkOrCreateUserOnSql(sql, sessionUser, additionalData);
|
|
689
|
+
}
|
|
668
690
|
|
|
669
691
|
// Cannot sync without database connection
|
|
670
692
|
if (!this.connection) {
|
|
@@ -680,34 +702,7 @@ export class CoreBetterAuthUserMapper {
|
|
|
680
702
|
$or: [{ email: sessionUser.email }, { iamId: sessionUser.id }],
|
|
681
703
|
});
|
|
682
704
|
|
|
683
|
-
|
|
684
|
-
const processedAdditionalData = { ...additionalData };
|
|
685
|
-
if (processedAdditionalData?.termsAndPrivacyAccepted === true) {
|
|
686
|
-
processedAdditionalData.termsAndPrivacyAcceptedAt = new Date();
|
|
687
|
-
delete processedAdditionalData.termsAndPrivacyAccepted;
|
|
688
|
-
} else {
|
|
689
|
-
delete processedAdditionalData?.termsAndPrivacyAccepted;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
const updateData: Record<string, any> = {
|
|
693
|
-
email: sessionUser.email,
|
|
694
|
-
...(sessionUser.name && { firstName: sessionUser.name.split(' ')[0] }),
|
|
695
|
-
...(sessionUser.name &&
|
|
696
|
-
sessionUser.name.includes(' ') && {
|
|
697
|
-
lastName: sessionUser.name.split(' ').slice(1).join(' '),
|
|
698
|
-
}),
|
|
699
|
-
...(sessionUser.emailVerified !== undefined && { verified: sessionUser.emailVerified }),
|
|
700
|
-
// Deliberately NOT `avatar: sessionUser.image`. `image` is a Better-Auth BUILT-IN column,
|
|
701
|
-
// so it is client-writable through `POST /iam/update-user` — it is not covered by
|
|
702
|
-
// PROTECTED_INPUT_FALSE_KEYS, which only locks the fields this framework adds. Copying it
|
|
703
|
-
// here wrote an attacker-chosen value into `avatar` through a NATIVE driver update, past
|
|
704
|
-
// both the `S_NO_ONE` input restriction on the field and every Mongoose plugin. Since the
|
|
705
|
-
// avatar endpoint deletes the file the previous value points at, that turned "set your own
|
|
706
|
-
// image" into "delete any file in the store". The avatar upload is the only writer.
|
|
707
|
-
iamId: sessionUser.id,
|
|
708
|
-
updatedAt: new Date(),
|
|
709
|
-
...processedAdditionalData,
|
|
710
|
-
};
|
|
705
|
+
const updateData = this.linkedUserFields(sessionUser, existingUser, additionalData);
|
|
711
706
|
|
|
712
707
|
// Build the update query
|
|
713
708
|
const updateQuery: Record<string, any> = {
|
|
@@ -740,6 +735,96 @@ export class CoreBetterAuthUserMapper {
|
|
|
740
735
|
}
|
|
741
736
|
}
|
|
742
737
|
|
|
738
|
+
/**
|
|
739
|
+
* The fields `linkOrCreateUser()` writes onto the app user, on MongoDB and on SQL alike
|
|
740
|
+
*/
|
|
741
|
+
protected linkedUserFields(
|
|
742
|
+
sessionUser: BetterAuthSessionUser,
|
|
743
|
+
existingUser: null | Record<string, any> | undefined,
|
|
744
|
+
additionalData?: Record<string, any>,
|
|
745
|
+
): Record<string, any> {
|
|
746
|
+
// Process additionalData to convert termsAndPrivacyAccepted to timestamp
|
|
747
|
+
const processedAdditionalData = { ...additionalData };
|
|
748
|
+
if (processedAdditionalData?.termsAndPrivacyAccepted === true) {
|
|
749
|
+
processedAdditionalData.termsAndPrivacyAcceptedAt = new Date();
|
|
750
|
+
delete processedAdditionalData.termsAndPrivacyAccepted;
|
|
751
|
+
} else {
|
|
752
|
+
delete processedAdditionalData?.termsAndPrivacyAccepted;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Reverse-sync the Better-Auth name into firstName/lastName ONLY when it actually
|
|
756
|
+
// differs from the stored combination. The split is lossy (first word vs. rest), so an
|
|
757
|
+
// unconditional overwrite would clobber locally maintained names on EVERY sign-in —
|
|
758
|
+
// e.g. firstName "Anna Maria" / lastName "von Berg" would mutate to "Anna" / "Maria von
|
|
759
|
+
// Berg" although nothing changed on the Better-Auth side.
|
|
760
|
+
const existingFullName = [existingUser?.firstName, existingUser?.lastName].filter(Boolean).join(' ');
|
|
761
|
+
const nameChangedInIam = !!sessionUser.name && sessionUser.name !== existingFullName;
|
|
762
|
+
|
|
763
|
+
return {
|
|
764
|
+
email: sessionUser.email,
|
|
765
|
+
...(sessionUser.name && nameChangedInIam && { firstName: sessionUser.name.split(' ')[0] }),
|
|
766
|
+
...(sessionUser.name &&
|
|
767
|
+
nameChangedInIam &&
|
|
768
|
+
sessionUser.name.includes(' ') && {
|
|
769
|
+
lastName: sessionUser.name.split(' ').slice(1).join(' '),
|
|
770
|
+
}),
|
|
771
|
+
...(sessionUser.emailVerified !== undefined && { verified: sessionUser.emailVerified }),
|
|
772
|
+
// Deliberately NOT `avatar: sessionUser.image`. `image` is a Better-Auth BUILT-IN column,
|
|
773
|
+
// so it is client-writable through `POST /iam/update-user` — it is not covered by
|
|
774
|
+
// PROTECTED_INPUT_FALSE_KEYS, which only locks the fields this framework adds. Copying it
|
|
775
|
+
// here wrote an attacker-chosen value into `avatar` through a NATIVE driver update, past
|
|
776
|
+
// both the `S_NO_ONE` input restriction on the field and every Mongoose plugin. Since the
|
|
777
|
+
// avatar endpoint deletes the file the previous value points at, that turned "set your own
|
|
778
|
+
// image" into "delete any file in the store". The avatar upload is the only writer.
|
|
779
|
+
iamId: sessionUser.id,
|
|
780
|
+
updatedAt: new Date(),
|
|
781
|
+
...processedAdditionalData,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// ===================================================================================================================
|
|
786
|
+
// Name Sync
|
|
787
|
+
// ===================================================================================================================
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Syncs a name change from Legacy Auth to Better-Auth (IAM)
|
|
791
|
+
*
|
|
792
|
+
* When a user changes their firstName/lastName in Legacy Auth (e.g. via PATCH /users/:id),
|
|
793
|
+
* the Better-Auth `name` field on the shared users document must follow. Without this sync,
|
|
794
|
+
* the next sign-in reverse-syncs the STALE Better-Auth name back into firstName/lastName
|
|
795
|
+
* (see linkOrCreateUser), silently discarding the user's edit.
|
|
796
|
+
*
|
|
797
|
+
* @param userEmail - The user's current email address (lookup key on the shared collection)
|
|
798
|
+
* @param name - The new display name (typically `firstName lastName`). May be empty: a cleared
|
|
799
|
+
* name must reach the Better-Auth side too, or the next sign-in writes the old one back.
|
|
800
|
+
* @returns true if sync was successful, false otherwise
|
|
801
|
+
*/
|
|
802
|
+
async syncNameChangeFromLegacy(userEmail: string, name: string): Promise<boolean> {
|
|
803
|
+
const sql = getBetterAuthSqlStore();
|
|
804
|
+
if (sql) {
|
|
805
|
+
return this.syncNameChangeFromLegacyOnSql(sql, userEmail, name);
|
|
806
|
+
}
|
|
807
|
+
if (!this.connection) {
|
|
808
|
+
this.logger.warn('No database connection available - cannot sync name change');
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
try {
|
|
813
|
+
const usersCollection = this.connection.collection('users');
|
|
814
|
+
const result = await usersCollection.updateOne({ email: userEmail }, { $set: { name, updatedAt: new Date() } });
|
|
815
|
+
if (result.matchedCount === 0) {
|
|
816
|
+
return false;
|
|
817
|
+
}
|
|
818
|
+
this.logger.debug(`Synced name change from Legacy to IAM for ${maskEmail(userEmail)}`);
|
|
819
|
+
return true;
|
|
820
|
+
} catch (error) {
|
|
821
|
+
this.logger.error(
|
|
822
|
+
`Error syncing name change from Legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
823
|
+
);
|
|
824
|
+
return false;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
743
828
|
// ===================================================================================================================
|
|
744
829
|
// Email Sync
|
|
745
830
|
// ===================================================================================================================
|
|
@@ -759,6 +844,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
759
844
|
* @returns true if sync was successful, false otherwise
|
|
760
845
|
*/
|
|
761
846
|
async syncEmailChangeFromLegacy(oldEmail: string, newEmail: string): Promise<boolean> {
|
|
847
|
+
const sql = getBetterAuthSqlStore();
|
|
848
|
+
if (sql) {
|
|
849
|
+
return this.syncEmailChangeFromLegacyOnSql(sql, oldEmail, newEmail);
|
|
850
|
+
}
|
|
762
851
|
if (!this.connection) {
|
|
763
852
|
this.logger.warn('No database connection available - cannot sync email change');
|
|
764
853
|
return false;
|
|
@@ -805,6 +894,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
805
894
|
* @returns true if sync was successful, false otherwise
|
|
806
895
|
*/
|
|
807
896
|
async syncEmailChangeFromIam(userId: string, newEmail: string): Promise<boolean> {
|
|
897
|
+
const sql = getBetterAuthSqlStore();
|
|
898
|
+
if (sql) {
|
|
899
|
+
return this.syncEmailChangeFromIamOnSql(sql, userId, newEmail);
|
|
900
|
+
}
|
|
808
901
|
if (!this.connection) {
|
|
809
902
|
this.logger.warn('No database connection available - cannot sync email change');
|
|
810
903
|
return false;
|
|
@@ -857,6 +950,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
857
950
|
success: boolean;
|
|
858
951
|
userDeleted: boolean;
|
|
859
952
|
}> {
|
|
953
|
+
const sql = getBetterAuthSqlStore();
|
|
954
|
+
if (sql) {
|
|
955
|
+
return this.deleteUserFromBothSystemsOnSql(sql, userIdentifier);
|
|
956
|
+
}
|
|
860
957
|
if (!this.connection) {
|
|
861
958
|
this.logger.warn('No database connection available - cannot delete user');
|
|
862
959
|
return { accountsDeleted: 0, sessionsDeleted: 0, success: false, userDeleted: false };
|
|
@@ -879,8 +976,8 @@ export class CoreBetterAuthUserMapper {
|
|
|
879
976
|
}
|
|
880
977
|
|
|
881
978
|
// Try by MongoDB _id
|
|
882
|
-
if (!user &&
|
|
883
|
-
user = await usersCollection.findOne({ _id:
|
|
979
|
+
if (!user && isValidObjectId(userIdentifier)) {
|
|
980
|
+
user = await usersCollection.findOne({ _id: newObjectId(userIdentifier) });
|
|
884
981
|
}
|
|
885
982
|
|
|
886
983
|
if (!user) {
|
|
@@ -931,6 +1028,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
931
1028
|
sessionsDeleted: number;
|
|
932
1029
|
success: boolean;
|
|
933
1030
|
}> {
|
|
1031
|
+
const sql = getBetterAuthSqlStore();
|
|
1032
|
+
if (sql) {
|
|
1033
|
+
return this.cleanupIamDataForDeletedUserOnSql(sql, String(userId));
|
|
1034
|
+
}
|
|
934
1035
|
if (!this.connection) {
|
|
935
1036
|
this.logger.warn('No database connection available - cannot cleanup IAM data');
|
|
936
1037
|
return { accountsDeleted: 0, sessionsDeleted: 0, success: false };
|
|
@@ -940,7 +1041,7 @@ export class CoreBetterAuthUserMapper {
|
|
|
940
1041
|
const accountCollection = this.connection.collection('account');
|
|
941
1042
|
const sessionCollection = this.connection.collection('session');
|
|
942
1043
|
|
|
943
|
-
const userObjectId = typeof userId === 'string' ?
|
|
1044
|
+
const userObjectId = typeof userId === 'string' ? newObjectId(userId) : userId;
|
|
944
1045
|
|
|
945
1046
|
// Delete Better-Auth sessions
|
|
946
1047
|
const sessionsResult = await sessionCollection.deleteMany({ userId: userObjectId });
|
|
@@ -971,6 +1072,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
971
1072
|
* @returns true if cleanup was successful, false otherwise
|
|
972
1073
|
*/
|
|
973
1074
|
async cleanupLegacyDataForDeletedIamUser(iamUserId: string): Promise<boolean> {
|
|
1075
|
+
const sql = getBetterAuthSqlStore();
|
|
1076
|
+
if (sql) {
|
|
1077
|
+
return this.cleanupLegacyDataForDeletedIamUserOnSql(sql, iamUserId);
|
|
1078
|
+
}
|
|
974
1079
|
if (!this.connection) {
|
|
975
1080
|
this.logger.warn('No database connection available - cannot cleanup Legacy data');
|
|
976
1081
|
return false;
|
|
@@ -1015,6 +1120,10 @@ export class CoreBetterAuthUserMapper {
|
|
|
1015
1120
|
// A caller that only needs the counts — the boot-time deprecation warning does — should
|
|
1016
1121
|
// not pay for a field it discards.
|
|
1017
1122
|
const includePendingEmails = options?.includePendingEmails !== false;
|
|
1123
|
+
const sql = getBetterAuthSqlStore();
|
|
1124
|
+
if (sql) {
|
|
1125
|
+
return this.getMigrationStatusOnSql(sql, includePendingEmails);
|
|
1126
|
+
}
|
|
1018
1127
|
if (!this.connection) {
|
|
1019
1128
|
this.logger.warn('No database connection available - cannot get migration status');
|
|
1020
1129
|
return {
|
|
@@ -1155,4 +1264,273 @@ export class CoreBetterAuthUserMapper {
|
|
|
1155
1264
|
};
|
|
1156
1265
|
}
|
|
1157
1266
|
}
|
|
1267
|
+
|
|
1268
|
+
// ===================================================================================================================
|
|
1269
|
+
// SQL data source — Better-Auth and the user model share ONE row per user in `users`, and Better-Auth's user id IS
|
|
1270
|
+
// that row's id (see BetterAuthSqlStore). Same behaviour as the MongoDB paths above; only the access differs.
|
|
1271
|
+
// ===================================================================================================================
|
|
1272
|
+
|
|
1273
|
+
protected async syncPasswordToLegacyOnSql(
|
|
1274
|
+
sql: BetterAuthSqlStore,
|
|
1275
|
+
iamUserId: string,
|
|
1276
|
+
userEmail: string,
|
|
1277
|
+
plainPassword?: string,
|
|
1278
|
+
): Promise<boolean> {
|
|
1279
|
+
if (!plainPassword) {
|
|
1280
|
+
return false;
|
|
1281
|
+
}
|
|
1282
|
+
try {
|
|
1283
|
+
// bcrypt(sha256(password)), as on MongoDB; the password policy keeps a bcrypt value as it is
|
|
1284
|
+
const bcryptHash = await bcrypt.hash(this.normalizePasswordForIam(plainPassword), 10);
|
|
1285
|
+
return !!(await sql.updateUser({ email: userEmail, iamId: iamUserId }, { password: bcryptHash }));
|
|
1286
|
+
} catch (error) {
|
|
1287
|
+
this.logger.error(
|
|
1288
|
+
`Error syncing password to legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1289
|
+
);
|
|
1290
|
+
return false;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
protected async syncPasswordChangeToIamOnSql(
|
|
1295
|
+
sql: BetterAuthSqlStore,
|
|
1296
|
+
userEmail: string,
|
|
1297
|
+
plainPassword: string,
|
|
1298
|
+
): Promise<boolean> {
|
|
1299
|
+
if (!plainPassword) {
|
|
1300
|
+
return false;
|
|
1301
|
+
}
|
|
1302
|
+
try {
|
|
1303
|
+
const user = await sql.findUser({ email: userEmail });
|
|
1304
|
+
if (!user || !(await sql.findCredentialAccount(user.id))) {
|
|
1305
|
+
return false;
|
|
1306
|
+
}
|
|
1307
|
+
await sql.updateCredentialPassword(user.id, await this.hashPasswordForBetterAuth(plainPassword));
|
|
1308
|
+
return true;
|
|
1309
|
+
} catch (error) {
|
|
1310
|
+
this.logger.error(`Error syncing password to IAM: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1311
|
+
return false;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
protected async migrateAccountToIamOnSql(
|
|
1316
|
+
sql: BetterAuthSqlStore,
|
|
1317
|
+
userEmail: string,
|
|
1318
|
+
plainPassword?: string,
|
|
1319
|
+
): Promise<boolean> {
|
|
1320
|
+
try {
|
|
1321
|
+
const legacyUser = await sql.findUser({ email: userEmail });
|
|
1322
|
+
if (!legacyUser?.password) {
|
|
1323
|
+
return false;
|
|
1324
|
+
}
|
|
1325
|
+
// FAST PATH, as on MongoDB: an existing credential account means the user is migrated already
|
|
1326
|
+
if (await sql.findCredentialAccount(legacyUser.id)) {
|
|
1327
|
+
return true;
|
|
1328
|
+
}
|
|
1329
|
+
if (!plainPassword) {
|
|
1330
|
+
return false;
|
|
1331
|
+
}
|
|
1332
|
+
const directMatch = await bcrypt.compare(plainPassword, legacyUser.password);
|
|
1333
|
+
const sha256Match = !directMatch ? await bcrypt.compare(sha256(plainPassword), legacyUser.password) : false;
|
|
1334
|
+
if (!directMatch && !sha256Match) {
|
|
1335
|
+
this.logger.warn(`Migration password verification failed for ${maskEmail(userEmail)}`);
|
|
1336
|
+
return false;
|
|
1337
|
+
}
|
|
1338
|
+
if (!legacyUser.iamId) {
|
|
1339
|
+
// The row IS Better-Auth's user already: link it by its own id instead of minting a second one
|
|
1340
|
+
await sql.updateUser({ id: legacyUser.id }, { iamId: legacyUser.id });
|
|
1341
|
+
await sql.updateIamUser(legacyUser.id, {
|
|
1342
|
+
emailVerified: legacyUser.verified === true,
|
|
1343
|
+
name: [legacyUser.firstName, legacyUser.lastName].filter(Boolean).join(' ') || undefined,
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
const credentialIssuer = legacyCredentialAccountIssuer();
|
|
1347
|
+
await sql.createAccount({
|
|
1348
|
+
accountId: legacyUser.id,
|
|
1349
|
+
...(credentialIssuer ? { issuer: credentialIssuer } : {}),
|
|
1350
|
+
password: await this.hashPasswordForBetterAuth(plainPassword),
|
|
1351
|
+
providerId: 'credential',
|
|
1352
|
+
userId: legacyUser.id,
|
|
1353
|
+
});
|
|
1354
|
+
return true;
|
|
1355
|
+
} catch (error) {
|
|
1356
|
+
this.logger.error(`Error migrating account to IAM: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1357
|
+
return false;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
protected async linkOrCreateUserOnSql(
|
|
1362
|
+
sql: BetterAuthSqlStore,
|
|
1363
|
+
sessionUser: BetterAuthSessionUser,
|
|
1364
|
+
additionalData?: Record<string, any>,
|
|
1365
|
+
): Promise<null | SyncedUserDocument> {
|
|
1366
|
+
try {
|
|
1367
|
+
const match = { email: sessionUser.email, iamId: sessionUser.id, id: sessionUser.id };
|
|
1368
|
+
const existingUser = await sql.findUser(match);
|
|
1369
|
+
if (!existingUser) {
|
|
1370
|
+
// Better-Auth writes the row itself (same table): a missing one is a user Better-Auth does not know either
|
|
1371
|
+
this.logger.warn(`Better-Auth user ${maskEmail(sessionUser.email)} has no row in the users table`);
|
|
1372
|
+
return null;
|
|
1373
|
+
}
|
|
1374
|
+
const synced = await sql.updateUser(
|
|
1375
|
+
{ id: existingUser.id },
|
|
1376
|
+
this.linkedUserFields(sessionUser, existingUser, additionalData),
|
|
1377
|
+
);
|
|
1378
|
+
return synced ? ({ ...synced, _id: synced.id } as SyncedUserDocument) : null;
|
|
1379
|
+
} catch (error) {
|
|
1380
|
+
this.logger.error(`Error syncing Better-Auth user: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1381
|
+
return null;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
protected async syncNameChangeFromLegacyOnSql(
|
|
1386
|
+
sql: BetterAuthSqlStore,
|
|
1387
|
+
userEmail: string,
|
|
1388
|
+
name: string,
|
|
1389
|
+
): Promise<boolean> {
|
|
1390
|
+
try {
|
|
1391
|
+
const user = await sql.findUser({ email: userEmail });
|
|
1392
|
+
if (!user) {
|
|
1393
|
+
return false;
|
|
1394
|
+
}
|
|
1395
|
+
// `name` is Better-Auth's field, not the user model's: written through Better-Auth's adapter
|
|
1396
|
+
await sql.updateIamUser(user.id, { name });
|
|
1397
|
+
this.logger.debug(`Synced name change from Legacy to IAM for ${maskEmail(userEmail)}`);
|
|
1398
|
+
return true;
|
|
1399
|
+
} catch (error) {
|
|
1400
|
+
this.logger.error(
|
|
1401
|
+
`Error syncing name change from Legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1402
|
+
);
|
|
1403
|
+
return false;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
protected async syncEmailChangeFromLegacyOnSql(
|
|
1408
|
+
sql: BetterAuthSqlStore,
|
|
1409
|
+
oldEmail: string,
|
|
1410
|
+
newEmail: string,
|
|
1411
|
+
): Promise<boolean> {
|
|
1412
|
+
try {
|
|
1413
|
+
const user = (await sql.findUser({ email: newEmail })) ?? (await sql.findUser({ email: oldEmail }));
|
|
1414
|
+
if (!user) {
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
await sql.deleteSessions(user.id);
|
|
1418
|
+
this.logger.debug(`Invalidated sessions for email change: ${maskEmail(oldEmail)} → ${maskEmail(newEmail)}`);
|
|
1419
|
+
return true;
|
|
1420
|
+
} catch (error) {
|
|
1421
|
+
this.logger.error(
|
|
1422
|
+
`Error syncing email change from Legacy: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1423
|
+
);
|
|
1424
|
+
return false;
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
protected async syncEmailChangeFromIamOnSql(
|
|
1429
|
+
sql: BetterAuthSqlStore,
|
|
1430
|
+
userId: string,
|
|
1431
|
+
newEmail: string,
|
|
1432
|
+
): Promise<boolean> {
|
|
1433
|
+
try {
|
|
1434
|
+
return !!(await sql.updateUser({ iamId: userId, id: userId }, { email: newEmail, refreshTokens: {} }));
|
|
1435
|
+
} catch (error) {
|
|
1436
|
+
this.logger.error(
|
|
1437
|
+
`Error syncing email change from IAM: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1438
|
+
);
|
|
1439
|
+
return false;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
protected async deleteUserFromBothSystemsOnSql(
|
|
1444
|
+
sql: BetterAuthSqlStore,
|
|
1445
|
+
userIdentifier: string,
|
|
1446
|
+
): Promise<{ accountsDeleted: number; sessionsDeleted: number; success: boolean; userDeleted: boolean }> {
|
|
1447
|
+
try {
|
|
1448
|
+
const user =
|
|
1449
|
+
(await sql.findUser({ email: userIdentifier })) ??
|
|
1450
|
+
(await sql.findUser({ iamId: userIdentifier })) ??
|
|
1451
|
+
(await sql.findUser({ id: userIdentifier }));
|
|
1452
|
+
if (!user) {
|
|
1453
|
+
return { accountsDeleted: 0, sessionsDeleted: 0, success: false, userDeleted: false };
|
|
1454
|
+
}
|
|
1455
|
+
const sessionsDeleted = await sql.deleteSessions(user.id);
|
|
1456
|
+
const accountsDeleted = await sql.deleteAccounts(user.id);
|
|
1457
|
+
await sql.deleteUser(user.id);
|
|
1458
|
+
this.logger.log(
|
|
1459
|
+
`Deleted user ${maskEmail(user.email)}: user=true, accounts=${accountsDeleted}, sessions=${sessionsDeleted}`,
|
|
1460
|
+
);
|
|
1461
|
+
return { accountsDeleted, sessionsDeleted, success: true, userDeleted: true };
|
|
1462
|
+
} catch (error) {
|
|
1463
|
+
this.logger.error(`Error deleting user: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1464
|
+
return { accountsDeleted: 0, sessionsDeleted: 0, success: false, userDeleted: false };
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
protected async cleanupIamDataForDeletedUserOnSql(
|
|
1469
|
+
sql: BetterAuthSqlStore,
|
|
1470
|
+
userId: string,
|
|
1471
|
+
): Promise<{ accountsDeleted: number; sessionsDeleted: number; success: boolean }> {
|
|
1472
|
+
try {
|
|
1473
|
+
const sessionsDeleted = await sql.deleteSessions(userId);
|
|
1474
|
+
const accountsDeleted = await sql.deleteAccounts(userId);
|
|
1475
|
+
return { accountsDeleted, sessionsDeleted, success: true };
|
|
1476
|
+
} catch (error) {
|
|
1477
|
+
this.logger.error(`Error cleaning up IAM data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1478
|
+
return { accountsDeleted: 0, sessionsDeleted: 0, success: false };
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
protected async cleanupLegacyDataForDeletedIamUserOnSql(
|
|
1483
|
+
sql: BetterAuthSqlStore,
|
|
1484
|
+
iamUserId: string,
|
|
1485
|
+
): Promise<boolean> {
|
|
1486
|
+
try {
|
|
1487
|
+
const user = await sql.findUser({ iamId: iamUserId, id: iamUserId });
|
|
1488
|
+
if (!user) {
|
|
1489
|
+
return false;
|
|
1490
|
+
}
|
|
1491
|
+
await sql.deleteUser(user.id);
|
|
1492
|
+
return true;
|
|
1493
|
+
} catch (error) {
|
|
1494
|
+
this.logger.error(`Error cleaning up Legacy data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1495
|
+
return false;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
protected async getMigrationStatusOnSql(
|
|
1500
|
+
sql: BetterAuthSqlStore,
|
|
1501
|
+
includePendingEmails: boolean,
|
|
1502
|
+
): Promise<MigrationStatus> {
|
|
1503
|
+
try {
|
|
1504
|
+
const counts = await sql.migrationCounts(includePendingEmails ? 100 : 0);
|
|
1505
|
+
const totalUsers = counts.total;
|
|
1506
|
+
const usersWithIamId = counts.withIamId;
|
|
1507
|
+
const usersWithIamAccount = counts.withIamAccount;
|
|
1508
|
+
const fullyMigratedUsers = counts.fullyMigrated;
|
|
1509
|
+
const pendingMigrationUsers = totalUsers - fullyMigratedUsers;
|
|
1510
|
+
const migrationPercentage = totalUsers > 0 ? Math.round((fullyMigratedUsers / totalUsers) * 100 * 100) / 100 : 0;
|
|
1511
|
+
const pendingUserEmails = counts.pendingEmails;
|
|
1512
|
+
return {
|
|
1513
|
+
canDisableLegacyAuth: totalUsers > 0 && fullyMigratedUsers === totalUsers,
|
|
1514
|
+
fullyMigratedUsers,
|
|
1515
|
+
migrationPercentage,
|
|
1516
|
+
pendingMigrationUsers,
|
|
1517
|
+
pendingUserEmails,
|
|
1518
|
+
totalUsers,
|
|
1519
|
+
usersWithIamAccount,
|
|
1520
|
+
usersWithIamId,
|
|
1521
|
+
};
|
|
1522
|
+
} catch (error) {
|
|
1523
|
+
this.logger.error(`Error getting migration status: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
1524
|
+
return {
|
|
1525
|
+
canDisableLegacyAuth: false,
|
|
1526
|
+
fullyMigratedUsers: 0,
|
|
1527
|
+
migrationPercentage: 0,
|
|
1528
|
+
pendingMigrationUsers: 0,
|
|
1529
|
+
pendingUserEmails: [],
|
|
1530
|
+
totalUsers: 0,
|
|
1531
|
+
usersWithIamAccount: 0,
|
|
1532
|
+
usersWithIamId: 0,
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1158
1536
|
}
|