@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
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { getAuthTables } from 'better-auth/db';
|
|
2
|
+
import { getMigrations } from 'better-auth/db/migration';
|
|
3
|
+
|
|
4
|
+
import { DataSourceConfigError } from '../../common/persistence/data-source.config.js';
|
|
5
|
+
import { generateId } from '../../common/persistence/id-format.js';
|
|
6
|
+
import { type IamSqlStorage, registerForeignColumns } from '../../common/persistence/persistence-runtime.registry.js';
|
|
7
|
+
import { columnName, quoteIdentifier } from '../../common/persistence/sql/sql-naming.js';
|
|
8
|
+
|
|
9
|
+
/** The table Better-Auth shares with the user model — created and owned by the framework */
|
|
10
|
+
const USERS_TABLE = 'users';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Better-Auth's own fields of the user row that the user model does not declare. Their columns are Better-Auth's, not
|
|
14
|
+
* left-overs of a removed field: the framework's schema evolution must not report them at every boot.
|
|
15
|
+
*/
|
|
16
|
+
registerForeignColumns(USERS_TABLE, ['email_verified', 'image', 'name']);
|
|
17
|
+
|
|
18
|
+
/** Postgres column type of a Better-Auth field, for a column the framework adds before Better-Auth's migration */
|
|
19
|
+
const SQL_TYPES: Record<string, string> = {
|
|
20
|
+
boolean: 'boolean',
|
|
21
|
+
date: 'timestamptz',
|
|
22
|
+
json: 'jsonb',
|
|
23
|
+
number: 'integer',
|
|
24
|
+
'number[]': 'jsonb',
|
|
25
|
+
string: 'text',
|
|
26
|
+
'string[]': 'jsonb',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** The tables Better-Auth's own options name (models of plugins come from the plugins) */
|
|
30
|
+
const CORE_MODELS = ['user', 'session', 'account', 'verification'] as const;
|
|
31
|
+
|
|
32
|
+
type Options = Record<string, any>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Better-Auth on a SQL data source: its built-in Kysely adapter on the given `pg` pool (Better-Auth recognises the
|
|
36
|
+
* pool and builds its own Kysely instance — the core imports no Kysely), ids in the framework's format, and every table
|
|
37
|
+
* and column named the way the framework names it.
|
|
38
|
+
*
|
|
39
|
+
* Naming is not cosmetic. Better-Auth and the user model share ONE row per user in `users`: the framework creates that
|
|
40
|
+
* table from the user model, its column for a field is `columnName(field)` (`firstName` → `first_name`), and Better-Auth
|
|
41
|
+
* must address exactly those columns — a second, camelCase `firstName` column would split one value in two. Applying the
|
|
42
|
+
* same rule to every name Better-Auth uses (the stored name it has on MongoDB, snake-cased) covers the user model's
|
|
43
|
+
* fields, Better-Auth's own tables and every plugin's tables, the project's plugins included, with no list to maintain.
|
|
44
|
+
* On MongoDB nothing of this applies: the stored names stay exactly as they are.
|
|
45
|
+
*
|
|
46
|
+
* Plugins are copied, never changed: a plugin object a project passes may also serve an instance on MongoDB in the same
|
|
47
|
+
* process, which must keep its names.
|
|
48
|
+
*/
|
|
49
|
+
export function withSqlStorage(options: Options, pool: unknown): Options {
|
|
50
|
+
const sqlOptions: Options = {
|
|
51
|
+
...options,
|
|
52
|
+
advanced: {
|
|
53
|
+
...options.advanced,
|
|
54
|
+
// ObjectId-hex, generated in the application: the id the framework gives every other row, so a user created by
|
|
55
|
+
// Better-Auth and one created through the user service are indistinguishable (plan §3.5)
|
|
56
|
+
database: { ...options.advanced?.database, generateId: () => generateId() },
|
|
57
|
+
},
|
|
58
|
+
database: pool,
|
|
59
|
+
plugins: (options.plugins ?? []).map((plugin: Options) =>
|
|
60
|
+
plugin?.schema ? { ...plugin, schema: snakeCaseSchema(plugin.schema) } : plugin,
|
|
61
|
+
),
|
|
62
|
+
};
|
|
63
|
+
const tables = getAuthTables(sqlOptions as any) as Record<
|
|
64
|
+
string,
|
|
65
|
+
{ fields: Record<string, Options>; modelName: string }
|
|
66
|
+
>;
|
|
67
|
+
for (const model of CORE_MODELS) {
|
|
68
|
+
const own = (sqlOptions[model] ?? {}) as Options;
|
|
69
|
+
const fields: Record<string, string> = {};
|
|
70
|
+
for (const [key, field] of Object.entries(tables[model]?.fields ?? {})) {
|
|
71
|
+
fields[key] = columnName(field.fieldName ?? key);
|
|
72
|
+
}
|
|
73
|
+
sqlOptions[model] = {
|
|
74
|
+
...own,
|
|
75
|
+
additionalFields: own.additionalFields ? snakeCaseFields(own.additionalFields) : undefined,
|
|
76
|
+
fields,
|
|
77
|
+
modelName: columnName(own.modelName ?? tables[model]?.modelName ?? model),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return sqlOptions;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** A plugin's schema with its tables and columns named like the framework's */
|
|
84
|
+
function snakeCaseSchema(schema: Record<string, Options>): Record<string, Options> {
|
|
85
|
+
return Object.fromEntries(
|
|
86
|
+
Object.entries(schema).map(([key, table]) => [
|
|
87
|
+
key,
|
|
88
|
+
{
|
|
89
|
+
...table,
|
|
90
|
+
fields: snakeCaseFields(table.fields ?? {}),
|
|
91
|
+
// A plugin's entry for a core table only adds fields; the table's name is Better-Auth's own option
|
|
92
|
+
...((CORE_MODELS as readonly string[]).includes(key) ? {} : { modelName: columnName(table.modelName ?? key) }),
|
|
93
|
+
},
|
|
94
|
+
]),
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function snakeCaseFields(fields: Record<string, Options>): Record<string, Options> {
|
|
99
|
+
return Object.fromEntries(
|
|
100
|
+
Object.entries(fields).map(([key, field]) => [key, { ...field, fieldName: columnName(field.fieldName ?? key) }]),
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** The tables Better-Auth's options declare that Better-Auth owns: all of them but the shared `users` table */
|
|
105
|
+
export function betterAuthOwnedTables(options: Options): string[] {
|
|
106
|
+
const tables = getAuthTables(options as any) as Record<string, { modelName: string }>;
|
|
107
|
+
return [...new Set(Object.values(tables).map((table) => table.modelName))].filter((name) => name !== USERS_TABLE);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Bring Better-Auth's tables up to date before the instance exists (it validates its schema as it starts): Better-Auth's
|
|
112
|
+
* own migrator, run as the owner under the framework's schema lock. It only creates tables and adds columns — on `users`
|
|
113
|
+
* the ones the user model does not declare (`name`, `email_verified`, `image`); it never drops or alters a column.
|
|
114
|
+
* Without an owner connection it only checks, and a pending change stops the boot like a framework table would.
|
|
115
|
+
*/
|
|
116
|
+
export async function applyBetterAuthSchema(options: Options, storage: IamSqlStorage): Promise<void> {
|
|
117
|
+
await storage.applySchema(async (pool, asOwner) => {
|
|
118
|
+
const nullable = asOwner ? await addRequiredUserColumnsAsNullable(options, pool as PgPool) : new Set<string>();
|
|
119
|
+
const { runMigrations, toBeAdded, toBeCreated } = await getMigrations({
|
|
120
|
+
...options,
|
|
121
|
+
database: pool,
|
|
122
|
+
logger: withoutNullabilityWarnings(options.logger, nullable),
|
|
123
|
+
} as any);
|
|
124
|
+
if (asOwner) {
|
|
125
|
+
await runMigrations();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const pending = [...toBeCreated, ...toBeAdded].map((change: { table: string }) => change.table);
|
|
129
|
+
if (pending.length) {
|
|
130
|
+
throw new DataSourceConfigError(
|
|
131
|
+
`Better-Auth's tables in "${storage.source}" are not up to date (${[...new Set(pending)].join(', ')}), and ` +
|
|
132
|
+
'without database.ownerUrl the application role may only verify them — configure the owner, or migrate them',
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}, betterAuthOwnedTables(options));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface PgPool {
|
|
139
|
+
query(text: string, params?: unknown[]): Promise<{ rows: any[] }>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* A field Better-Auth declares required without a default (`name`) becomes a NOT NULL column when Better-Auth adds it —
|
|
144
|
+
* and every user the FRAMEWORK creates (legacy sign-up, user service, system setup) would then fail to insert, because the
|
|
145
|
+
* user model knows nothing of it. On MongoDB such a user simply has no `name`. So the framework adds these columns
|
|
146
|
+
* first, nullable like every column it creates (the database does not enforce `required`, as on MongoDB); Better-Auth
|
|
147
|
+
* then finds them and adds nothing. Returns every required user column that is nullable by the framework's design.
|
|
148
|
+
*/
|
|
149
|
+
async function addRequiredUserColumnsAsNullable(options: Options, pool: PgPool): Promise<Set<string>> {
|
|
150
|
+
const users = (getAuthTables(options as any) as Record<string, any>).user;
|
|
151
|
+
const { rows } = await pool.query(
|
|
152
|
+
'SELECT column_name FROM information_schema.columns WHERE table_schema = current_schema() AND table_name = $1',
|
|
153
|
+
[users.modelName],
|
|
154
|
+
);
|
|
155
|
+
const existing = new Set(rows.map((row) => row.column_name as string));
|
|
156
|
+
const nullable = new Set<string>();
|
|
157
|
+
for (const [key, field] of Object.entries(users.fields as Record<string, any>)) {
|
|
158
|
+
const column = field.fieldName ?? key;
|
|
159
|
+
if (field.required === false) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
// Every column the framework created for a field is nullable — the user model's `email` and timestamps included
|
|
163
|
+
nullable.add(column);
|
|
164
|
+
if (field.defaultValue === undefined && !existing.has(column) && SQL_TYPES[field.type]) {
|
|
165
|
+
await pool.query(
|
|
166
|
+
`ALTER TABLE ${quoteIdentifier(users.modelName)} ADD COLUMN IF NOT EXISTS ${quoteIdentifier(column)} ${SQL_TYPES[field.type]}`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return nullable;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Better-Auth's logger, minus the warning that a required user column is nullable — for the columns the framework made
|
|
175
|
+
* nullable on purpose; every other message (a type mismatch, an unsafe change) is still reported
|
|
176
|
+
*/
|
|
177
|
+
function withoutNullabilityWarnings(logger: Options | undefined, columns: Set<string>): Options | undefined {
|
|
178
|
+
if (!columns.size || typeof logger?.log !== 'function') {
|
|
179
|
+
return logger;
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
...logger,
|
|
183
|
+
log: (level: string, message: string, ...args: unknown[]) => {
|
|
184
|
+
const column = /^Column "([^"]+)" on table "users" stays nullable/.exec(String(message))?.[1];
|
|
185
|
+
if (level === 'warn' && column && columns.has(column)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
logger.log(level, message, ...args);
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Injectable, Logger, Optional } from '@nestjs/common';
|
|
2
|
-
import { InjectConnection } from '
|
|
3
|
-
import {
|
|
2
|
+
import { InjectConnection } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
3
|
+
import type { Connection } from 'mongoose';
|
|
4
4
|
|
|
5
5
|
import { BetterAuthenticatedUser } from './better-auth.types.js';
|
|
6
|
+
import { BetterAuthMongoUsers, type IamUserLookup } from './core-better-auth-mongo.users.js';
|
|
7
|
+
import { getBetterAuthSqlStore } from './core-better-auth-sql.registry.js';
|
|
6
8
|
import { CoreBetterAuthService } from './core-better-auth.service.js';
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -95,7 +97,7 @@ export class BetterAuthTokenService {
|
|
|
95
97
|
* @returns User object with hasRole method, or null if verification fails
|
|
96
98
|
*/
|
|
97
99
|
async verifyAndLoadUser(token: string): Promise<BetterAuthenticatedUser | null> {
|
|
98
|
-
if (!this.betterAuthService || !this.
|
|
100
|
+
if (!this.betterAuthService || !this.users()) {
|
|
99
101
|
return null;
|
|
100
102
|
}
|
|
101
103
|
|
|
@@ -152,10 +154,19 @@ export class BetterAuthTokenService {
|
|
|
152
154
|
}
|
|
153
155
|
return roles.some((role) => userRoles.includes(role));
|
|
154
156
|
},
|
|
155
|
-
id:
|
|
157
|
+
// The row's id as a string, whatever the database: MongoDB's `_id`, the column `id` on SQL
|
|
158
|
+
id: user._id?.toString() || (user.id as string),
|
|
156
159
|
} as BetterAuthenticatedUser;
|
|
157
160
|
}
|
|
158
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Where the app user is looked up: the SQL store when Better-Auth runs on SQL, MongoDB otherwise. Ids stay strings
|
|
164
|
+
* here — only the MongoDB lookup knows what an ObjectId is.
|
|
165
|
+
*/
|
|
166
|
+
protected users(): IamUserLookup | undefined {
|
|
167
|
+
return getBetterAuthSqlStore() ?? (this.connection ? new BetterAuthMongoUsers(this.connection) : undefined);
|
|
168
|
+
}
|
|
169
|
+
|
|
159
170
|
/**
|
|
160
171
|
* Loads a user from JWT payload using direct MongoDB query.
|
|
161
172
|
*
|
|
@@ -166,23 +177,14 @@ export class BetterAuthTokenService {
|
|
|
166
177
|
[key: string]: unknown;
|
|
167
178
|
sub: string;
|
|
168
179
|
}): Promise<BetterAuthenticatedUser | null> {
|
|
169
|
-
|
|
180
|
+
const users = this.users();
|
|
181
|
+
if (!users) {
|
|
170
182
|
return null;
|
|
171
183
|
}
|
|
172
184
|
|
|
173
185
|
try {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// Try to find by MongoDB _id first
|
|
178
|
-
if (Types.ObjectId.isValid(payload.sub)) {
|
|
179
|
-
user = await usersCollection.findOne({ _id: new Types.ObjectId(payload.sub) });
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// If not found, try by iamId
|
|
183
|
-
if (!user) {
|
|
184
|
-
user = await usersCollection.findOne({ iamId: payload.sub });
|
|
185
|
-
}
|
|
186
|
+
// By the row's id first, then by iamId
|
|
187
|
+
const user = (await users.findUser({ id: payload.sub })) ?? (await users.findUser({ iamId: payload.sub }));
|
|
186
188
|
|
|
187
189
|
if (!user) {
|
|
188
190
|
return null;
|
|
@@ -207,28 +209,17 @@ export class BetterAuthTokenService {
|
|
|
207
209
|
email?: string;
|
|
208
210
|
id?: string;
|
|
209
211
|
}): Promise<BetterAuthenticatedUser | null> {
|
|
210
|
-
|
|
212
|
+
const users = this.users();
|
|
213
|
+
if (!users || !sessionUser) {
|
|
211
214
|
return null;
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
try {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
user = await usersCollection.findOne({ email: sessionUser.email });
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// If not found by email, try by iamId
|
|
224
|
-
if (!user && sessionUser.id) {
|
|
225
|
-
user = await usersCollection.findOne({ iamId: sessionUser.id });
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// If still not found, try by _id (if the ID looks like a MongoDB ObjectId)
|
|
229
|
-
if (!user && sessionUser.id && Types.ObjectId.isValid(sessionUser.id)) {
|
|
230
|
-
user = await usersCollection.findOne({ _id: new Types.ObjectId(sessionUser.id) });
|
|
231
|
-
}
|
|
218
|
+
// By email (most reliable), then by iamId, then by the row's id
|
|
219
|
+
const user =
|
|
220
|
+
(await users.findUser({ email: sessionUser.email })) ??
|
|
221
|
+
(await users.findUser({ iamId: sessionUser.id })) ??
|
|
222
|
+
(await users.findUser({ id: sessionUser.id }));
|
|
232
223
|
|
|
233
224
|
if (!user) {
|
|
234
225
|
return null;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { passkey } from '@better-auth/passkey';
|
|
2
2
|
import { Logger } from '@nestjs/common';
|
|
3
3
|
import { betterAuth, BetterAuthPlugin } from 'better-auth';
|
|
4
|
-
import { mongodbAdapter } from 'better-auth/adapters/mongodb';
|
|
5
4
|
import { jwt, openAPI, twoFactor } from 'better-auth/plugins';
|
|
6
5
|
import * as crypto from 'crypto';
|
|
7
6
|
import * as fs from 'fs';
|
|
@@ -13,7 +12,9 @@ import { revalidateWsConnectionsOf } from '../../common/helpers/graphql-ws-conne
|
|
|
13
12
|
import { IBetterAuth, ICorsConfig } from '../../common/interfaces/server-options.interface.js';
|
|
14
13
|
import { ConfigService } from '../../common/services/config.service.js';
|
|
15
14
|
import { detectCookiePrefixDrift, resolveBetterAuthCookiePrefix } from './better-auth-cookie-prefix.helper.js';
|
|
15
|
+
import { withSqlStorage } from './better-auth-sql.helper.js';
|
|
16
16
|
import { projectProvidesOpenApiPlugin } from './core-better-auth-openapi.helper.js';
|
|
17
|
+
import { requireBetterAuthMongoAdapter } from '../../common/persistence/mongo/mongo-packages.js';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Type for better-auth instance with plugins
|
|
@@ -155,7 +156,7 @@ export interface CreateBetterAuthOptions {
|
|
|
155
156
|
* MongoDB database instance
|
|
156
157
|
* Note: Uses 'any' type to handle version incompatibilities between
|
|
157
158
|
* mongoose's bundled mongodb types and the project's mongodb package.
|
|
158
|
-
* At runtime, this is a mongodb.Db instance.
|
|
159
|
+
* At runtime, this is a mongodb.Db instance. Unused when `sqlPool` is set.
|
|
159
160
|
*/
|
|
160
161
|
db: any;
|
|
161
162
|
|
|
@@ -230,6 +231,13 @@ export interface CreateBetterAuthOptions {
|
|
|
230
231
|
* Used for local environment defaults.
|
|
231
232
|
*/
|
|
232
233
|
serverEnv?: string;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* The `pg` pool of the SQL data source the `users` table lives in (the application role's pool of the configured
|
|
237
|
+
* engine). Set, Better-Auth runs its built-in Kysely adapter on it instead of MongoDB, with the framework's ids and
|
|
238
|
+
* table and column names — see `withSqlStorage()`.
|
|
239
|
+
*/
|
|
240
|
+
sqlPool?: unknown;
|
|
233
241
|
}
|
|
234
242
|
|
|
235
243
|
/**
|
|
@@ -480,7 +488,31 @@ export interface CreateBetterAuthResult {
|
|
|
480
488
|
instance: BetterAuthInstance;
|
|
481
489
|
}
|
|
482
490
|
|
|
491
|
+
/** The options `createBetterAuthInstance()` builds, before Better-Auth is constructed from them */
|
|
492
|
+
export interface BetterAuthOptionsResult {
|
|
493
|
+
/** Resolved cookie domain for cross-subdomain cookies, or undefined if disabled */
|
|
494
|
+
cookieDomain: string | undefined;
|
|
495
|
+
/** What `betterAuth()` receives */
|
|
496
|
+
options: Record<string, unknown>;
|
|
497
|
+
}
|
|
498
|
+
|
|
483
499
|
export function createBetterAuthInstance(options: CreateBetterAuthOptions): CreateBetterAuthResult | null {
|
|
500
|
+
const built = buildBetterAuthOptions(options);
|
|
501
|
+
return built ? instantiateBetterAuth(built) : null;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/** Construct Better-Auth from built options — a separate step so a SQL schema can be brought up to date in between */
|
|
505
|
+
export function instantiateBetterAuth(built: BetterAuthOptionsResult): CreateBetterAuthResult {
|
|
506
|
+
// Type assertion needed for maximum flexibility - allows projects to use any Better-Auth option
|
|
507
|
+
return { cookieDomain: built.cookieDomain, instance: betterAuth(built.options as any) };
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Better-Auth's options as `createBetterAuthInstance()` builds them, without constructing Better-Auth: on a SQL data
|
|
512
|
+
* source its tables must exist before the instance does, because Better-Auth validates its schema as it starts and
|
|
513
|
+
* reports every missing table as an error.
|
|
514
|
+
*/
|
|
515
|
+
export function buildBetterAuthOptions(options: CreateBetterAuthOptions): BetterAuthOptionsResult | null {
|
|
484
516
|
const {
|
|
485
517
|
config,
|
|
486
518
|
db,
|
|
@@ -490,6 +522,7 @@ export function createBetterAuthInstance(options: CreateBetterAuthOptions): Crea
|
|
|
490
522
|
sendResetPasswordEmail,
|
|
491
523
|
sendVerificationEmail,
|
|
492
524
|
serverEnv,
|
|
525
|
+
sqlPool,
|
|
493
526
|
} = options;
|
|
494
527
|
|
|
495
528
|
// Return null only if better-auth is explicitly disabled
|
|
@@ -615,7 +648,7 @@ export function createBetterAuthInstance(options: CreateBetterAuthOptions): Crea
|
|
|
615
648
|
},
|
|
616
649
|
basePath,
|
|
617
650
|
baseURL: betterAuthBaseUrl,
|
|
618
|
-
database:
|
|
651
|
+
database: sqlPool ? undefined : (requireBetterAuthMongoAdapter()(db) as any),
|
|
619
652
|
// Enable email/password authentication by default (required by Better-Auth 1.x)
|
|
620
653
|
// Can be disabled by setting config.emailAndPassword.enabled = false
|
|
621
654
|
emailAndPassword: {
|
|
@@ -810,12 +843,14 @@ export function createBetterAuthInstance(options: CreateBetterAuthOptions): Crea
|
|
|
810
843
|
finalConfig = betterAuthConfig;
|
|
811
844
|
}
|
|
812
845
|
|
|
813
|
-
//
|
|
814
|
-
|
|
846
|
+
// On SQL the storage is applied last, so the naming also covers fields and plugins `config.options` added
|
|
847
|
+
if (sqlPool) {
|
|
848
|
+
finalConfig = withSqlStorage(finalConfig, sqlPool);
|
|
849
|
+
}
|
|
815
850
|
|
|
816
851
|
return {
|
|
817
852
|
cookieDomain: crossSubDomain.enabled ? crossSubDomain.domain : undefined,
|
|
818
|
-
|
|
853
|
+
options: finalConfig,
|
|
819
854
|
};
|
|
820
855
|
}
|
|
821
856
|
|
|
@@ -1037,7 +1072,8 @@ function buildPlugins(
|
|
|
1037
1072
|
passkeyOptions.userVerification = normalizedPasskey.userVerification;
|
|
1038
1073
|
}
|
|
1039
1074
|
if (normalizedPasskey.webAuthnChallengeCookie) {
|
|
1040
|
-
|
|
1075
|
+
// The plugin reads the name from `advanced`; a top-level option is ignored
|
|
1076
|
+
passkeyOptions.advanced = { webAuthnChallengeCookie: normalizedPasskey.webAuthnChallengeCookie };
|
|
1041
1077
|
}
|
|
1042
1078
|
|
|
1043
1079
|
plugins.push(passkey(passkeyOptions));
|
|
@@ -243,6 +243,17 @@ export class CoreBetterAuthApiMiddleware implements NestMiddleware {
|
|
|
243
243
|
return this.cookieHelper;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
+
/**
|
|
247
|
+
* The passkey challenge cookie as Better-Auth names it: the configured key under the instance's cookie prefix
|
|
248
|
+
* (`iam.better-auth-passkey` by default). Asked from Better-Auth itself, so the prefix the session cookie follows
|
|
249
|
+
* (`COOKIE_PREFIX`, the base path) applies here too.
|
|
250
|
+
*/
|
|
251
|
+
protected async passkeyChallengeCookieName(authInstance: unknown): Promise<string> {
|
|
252
|
+
const key = this.challengeService?.getCookieName() || 'better-auth-passkey';
|
|
253
|
+
const context = await (authInstance as { $context?: Promise<any> }).$context;
|
|
254
|
+
return context?.createAuthCookie?.(key)?.name ?? key;
|
|
255
|
+
}
|
|
256
|
+
|
|
246
257
|
/**
|
|
247
258
|
* Check if database challenge storage should be used.
|
|
248
259
|
* This is checked dynamically because the ChallengeService initializes in onModuleInit.
|
|
@@ -312,7 +323,8 @@ export class CoreBetterAuthApiMiddleware implements NestMiddleware {
|
|
|
312
323
|
|
|
313
324
|
// Get config for cookie signing
|
|
314
325
|
const config = this.betterAuthService.getConfig();
|
|
315
|
-
const cookieName =
|
|
326
|
+
const cookieName =
|
|
327
|
+
isPasskeyGenerate || isPasskeyVerify ? await this.passkeyChallengeCookieName(authInstance) : '';
|
|
316
328
|
|
|
317
329
|
// For passkey verify requests with DB storage, inject the verificationToken as a cookie
|
|
318
330
|
let challengeIdToDelete: string | undefined;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Injectable, Logger, OnModuleInit, Optional } from '@nestjs/common';
|
|
2
|
-
import { InjectConnection } from '
|
|
2
|
+
import { InjectConnection } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
3
3
|
import * as crypto from 'crypto';
|
|
4
|
-
import { Collection, Document } from 'mongodb';
|
|
4
|
+
import type { Collection, Document } from 'mongodb';
|
|
5
5
|
import type { Connection } from 'mongoose';
|
|
6
6
|
|
|
7
7
|
import { IBetterAuth } from '../../common/interfaces/server-options.interface.js';
|
|
8
8
|
import { ConfigService } from '../../common/services/config.service.js';
|
|
9
|
+
import { getBetterAuthSqlStore } from './core-better-auth-sql.registry.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* WebAuthn challenge mapping document structure.
|
|
@@ -104,8 +105,8 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
104
105
|
|
|
105
106
|
try {
|
|
106
107
|
if (!this.connection) {
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
// No MongoDB (PostgreSQL alone): the mappings are Better-Auth verification values on the SQL source, reached per
|
|
109
|
+
// call through getBetterAuthSqlStore() — isEnabled() answers from it
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
112
|
|
|
@@ -138,7 +139,7 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
138
139
|
* Check if database challenge storage is enabled
|
|
139
140
|
*/
|
|
140
141
|
isEnabled(): boolean {
|
|
141
|
-
return this.enabled && this.collection !== null;
|
|
142
|
+
return this.enabled && (this.collection !== null || !!getBetterAuthSqlStore());
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
/**
|
|
@@ -154,7 +155,8 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
154
155
|
userId: string,
|
|
155
156
|
type: 'authentication' | 'registration',
|
|
156
157
|
): Promise<string> {
|
|
157
|
-
|
|
158
|
+
const sql = getBetterAuthSqlStore();
|
|
159
|
+
if (!this.collection && !sql) {
|
|
158
160
|
throw new Error('Challenge storage not initialized');
|
|
159
161
|
}
|
|
160
162
|
|
|
@@ -164,6 +166,13 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
164
166
|
const now = new Date();
|
|
165
167
|
const expiresAt = new Date(now.getTime() + this.ttlSeconds * 1000);
|
|
166
168
|
|
|
169
|
+
if (sql) {
|
|
170
|
+
// On SQL as one of Better-Auth's verification values: short-lived, with an expiry, never sent to the client
|
|
171
|
+
await sql.storeChallenge(challengeId, { expiresAt, type, userId, verificationToken });
|
|
172
|
+
this.logger.debug(`Stored ${type} challenge mapping for user ${userId.substring(0, 8)}...`);
|
|
173
|
+
return challengeId;
|
|
174
|
+
}
|
|
175
|
+
|
|
167
176
|
await this.collection.insertOne({
|
|
168
177
|
challengeId,
|
|
169
178
|
createdAt: now,
|
|
@@ -185,11 +194,12 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
185
194
|
* @returns The verificationToken or null if not found/expired
|
|
186
195
|
*/
|
|
187
196
|
async getVerificationToken(challengeId: string): Promise<null | string> {
|
|
188
|
-
|
|
197
|
+
const sql = getBetterAuthSqlStore();
|
|
198
|
+
if (!this.collection && !sql) {
|
|
189
199
|
return null;
|
|
190
200
|
}
|
|
191
201
|
|
|
192
|
-
const doc = await this.collection.findOne({ challengeId });
|
|
202
|
+
const doc = sql ? await sql.findChallenge(challengeId) : await this.collection.findOne({ challengeId });
|
|
193
203
|
|
|
194
204
|
if (!doc) {
|
|
195
205
|
this.logger.debug(`Challenge mapping not found: ${challengeId.substring(0, 8)}...`);
|
|
@@ -211,11 +221,14 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
211
221
|
* @param challengeId - The challenge ID to delete
|
|
212
222
|
*/
|
|
213
223
|
async deleteChallengeMapping(challengeId: string): Promise<void> {
|
|
214
|
-
|
|
224
|
+
const sql = getBetterAuthSqlStore();
|
|
225
|
+
if (sql) {
|
|
226
|
+
await sql.deleteChallenge(challengeId);
|
|
227
|
+
} else if (!this.collection) {
|
|
215
228
|
return;
|
|
229
|
+
} else {
|
|
230
|
+
await this.collection.deleteOne({ challengeId });
|
|
216
231
|
}
|
|
217
|
-
|
|
218
|
-
await this.collection.deleteOne({ challengeId });
|
|
219
232
|
this.logger.debug(`Deleted challenge mapping: ${challengeId.substring(0, 8)}...`);
|
|
220
233
|
}
|
|
221
234
|
|
|
@@ -225,13 +238,16 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
225
238
|
* @param userId - User ID whose challenge mappings should be deleted
|
|
226
239
|
*/
|
|
227
240
|
async deleteUserChallengeMappings(userId: string): Promise<void> {
|
|
228
|
-
|
|
241
|
+
const sql = getBetterAuthSqlStore();
|
|
242
|
+
if (!this.collection && !sql) {
|
|
229
243
|
return;
|
|
230
244
|
}
|
|
231
245
|
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
this.
|
|
246
|
+
const deletedCount = sql
|
|
247
|
+
? await sql.deleteUserChallenges(userId)
|
|
248
|
+
: (await this.collection.deleteMany({ userId })).deletedCount;
|
|
249
|
+
if (deletedCount > 0) {
|
|
250
|
+
this.logger.debug(`Deleted ${deletedCount} challenge mappings for user ${userId.substring(0, 8)}...`);
|
|
235
251
|
}
|
|
236
252
|
}
|
|
237
253
|
|
|
@@ -243,14 +259,16 @@ export class CoreBetterAuthChallengeService implements OnModuleInit {
|
|
|
243
259
|
}
|
|
244
260
|
|
|
245
261
|
/**
|
|
246
|
-
*
|
|
262
|
+
* The key of Better-Auth's passkey challenge cookie (`passkey.webAuthnChallengeCookie`, default
|
|
263
|
+
* `better-auth-passkey`). Better-Auth puts its cookie prefix in front of it — the full name is
|
|
264
|
+
* `createAuthCookie(<key>).name` of the instance, as `CoreBetterAuthApiMiddleware` resolves it.
|
|
247
265
|
*/
|
|
248
266
|
getCookieName(): string {
|
|
249
267
|
if (!this.configService) {
|
|
250
|
-
return 'better-auth
|
|
268
|
+
return 'better-auth-passkey';
|
|
251
269
|
}
|
|
252
270
|
const config = this.configService.get<IBetterAuth>('betterAuth') || {};
|
|
253
271
|
const passkeyConfig = typeof config.passkey === 'object' ? config.passkey : null;
|
|
254
|
-
return passkeyConfig?.webAuthnChallengeCookie || 'better-auth
|
|
272
|
+
return passkeyConfig?.webAuthnChallengeCookie || 'better-auth-passkey';
|
|
255
273
|
}
|
|
256
274
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Connection } from 'mongoose';
|
|
2
|
+
|
|
3
|
+
import type { IamUserMatch } from './core-better-auth-sql.store.js';
|
|
4
|
+
import { isValidObjectId, newObjectId } from '../../common/persistence/mongo/mongoose-compat.js';
|
|
5
|
+
|
|
6
|
+
/** One way to look the app user up on the per-request auth path — by one key at a time */
|
|
7
|
+
export interface IamUserLookup {
|
|
8
|
+
findUser(match: IamUserMatch): Promise<null | Record<string, unknown>>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The app user on MongoDB for the per-request auth path (token service). The one place on that path that knows a
|
|
13
|
+
* MongoDB id is an ObjectId: the services ask by string, and only this class turns an id into a `_id` filter — a
|
|
14
|
+
* string that is no ObjectId finds nobody, as before. On a SQL source `BetterAuthSqlStore` answers instead.
|
|
15
|
+
*/
|
|
16
|
+
export class BetterAuthMongoUsers implements IamUserLookup {
|
|
17
|
+
constructor(protected readonly connection: Connection) {}
|
|
18
|
+
|
|
19
|
+
async findUser(match: IamUserMatch): Promise<null | Record<string, unknown>> {
|
|
20
|
+
const or: Record<string, unknown>[] = [];
|
|
21
|
+
if (match.email) {
|
|
22
|
+
or.push({ email: match.email });
|
|
23
|
+
}
|
|
24
|
+
if (match.iamId) {
|
|
25
|
+
or.push({ iamId: match.iamId });
|
|
26
|
+
}
|
|
27
|
+
if (match.id && isValidObjectId(match.id)) {
|
|
28
|
+
or.push({ _id: newObjectId(match.id) });
|
|
29
|
+
}
|
|
30
|
+
if (!or.length) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return this.connection.collection('users').findOne(or.length === 1 ? or[0] : { $or: or });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SQL store of Better-Auth's data while Better-Auth runs on a SQL source — `undefined` on MongoDB. Set by
|
|
3
|
+
* `CoreBetterAuthModule` when it creates the instance (every creation sets it, so an application on MongoDB booted
|
|
4
|
+
* after one on SQL in the same process reads `undefined`), read by the user mapper, the token and challenge services,
|
|
5
|
+
* the system setup and the API token service at call time.
|
|
6
|
+
*
|
|
7
|
+
* `import type` only — an import-free leaf, so none of those files imports the module (see
|
|
8
|
+
* `.claude/rules/better-auth.md` §6).
|
|
9
|
+
*/
|
|
10
|
+
import type { BetterAuthSqlStore } from './core-better-auth-sql.store.js';
|
|
11
|
+
|
|
12
|
+
let store: BetterAuthSqlStore | undefined;
|
|
13
|
+
|
|
14
|
+
export function setBetterAuthSqlStore(value: BetterAuthSqlStore | undefined): void {
|
|
15
|
+
store = value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getBetterAuthSqlStore(): BetterAuthSqlStore | undefined {
|
|
19
|
+
return store;
|
|
20
|
+
}
|