najm-auth 4.1.0 → 4.2.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/README.md CHANGED
@@ -561,6 +561,36 @@ export class ProductRepository {
561
561
 
562
562
  ### Composable ownership (4.1+)
563
563
 
564
+ For custom queries, the property form puts the rules and type together:
565
+
566
+ ```typescript
567
+ import { Owned, type OwnedWhere } from 'najm-auth';
568
+
569
+ @Repository('default')
570
+ export class ProductRepository {
571
+ @DB() db!: Database;
572
+
573
+ @Owned(Product, SharedProduct)
574
+ private ownedWhere!: OwnedWhere;
575
+
576
+ async getById(id: string) {
577
+ const [row] = await this.db.select().from(products)
578
+ .where(and(this.ownedWhere(), eq(products.id, id))).limit(1);
579
+ return row ?? null;
580
+ }
581
+ }
582
+ ```
583
+
584
+ Use any instance property name; `OwnedWhere` is the shared function type.
585
+ Resolve the repository through Najm's container before calling it. Context
586
+ injection installs the function after construction, including when TypeScript
587
+ emits native class fields. The function reads the current request on every call,
588
+ so a singleton repository can safely serve different actors. Multiple decorated
589
+ properties may use independent rules, including on inherited repositories.
590
+ The class form and its `ownershipCondition`, `findMany`, `findOne`, and
591
+ `scopedQuery` helpers remain available. The property form supplies only the
592
+ decorated predicate; it does not rewrite queries or add CRUD helpers.
593
+
564
594
  `@Owned(Product)` now provides `ownershipCondition()` for custom queries.
565
595
  It returns a parameterized `id IN (authorized IDs)` predicate; join-based rules
566
596
  do not multiply outer rows. Combine it with filters in one
package/dist/index.d.ts CHANGED
@@ -2856,8 +2856,11 @@ declare class ScopeContext {
2856
2856
  role: string;
2857
2857
  } | null;
2858
2858
  }
2859
- declare function Owned(token: OwnershipToken, ...alternatives: OwnershipToken[]): (target: Function) => void;
2859
+ /** Decorate a repository class, or an `ownedWhere!: OwnedWhere` property. */
2860
+ declare function Owned(token: OwnershipToken, ...alternatives: OwnershipToken[]): ClassDecorator & PropertyDecorator;
2860
2861
 
2862
+ /** Request-aware ownership predicate supplied by an @Owned property. */
2863
+ type OwnedWhere = () => SQL | undefined;
2861
2864
  /** Request context consumed by ownershipCondition; ScopeContext implements it. */
2862
2865
  interface OwnershipReadContext {
2863
2866
  hasActiveContext(): boolean;
@@ -3203,4 +3206,4 @@ declare const authSeed: (config: AuthSeedConfig) => Record<string, SeedEntry>;
3203
3206
  */
3204
3207
  declare function seedAuthData(config: SeedAuthDataConfig): Promise<SeedAuthDataResult>;
3205
3208
 
3206
- export { AUTH_CONFIG, AUTH_CORE_MODULE, en as AUTH_EN, AUTH_LOCALES, AUTH_LOGIN_RATE_LIMIT_ENV, AUTH_MODULE, AUTH_PERMISSIONS, AUTH_ROLE, AUTH_SCHEMA, AUTH_SUPPORTED_LANGUAGES, AUTH_USER, type AdministrativeDelivery, type AssignPermissionDto, type AssignRoleDto, type AssignRoleParams, type AuthConfig, AuthController, AuthGuard, type AuthLoginRateLimitConfig, type AuthPluginConfig, AuthQueries, type AuthRateLimitEnvironment, AuthResolver, type AuthSchema, type AuthSeedConfig, AuthService, AuthSessionService, type AuthUser, CREDENTIAL_SETUP_CODES, CREDENTIAL_SETUP_MODULE, Can, CanCreate, CanDelete, CanList, CanRead, CanUpdate, type ChainableGuard, type ChangePasswordDto, type CheckPermissionDto, type ConfiguredOwnership, type ConfirmResetPasswordDto, type ConsumedSetPasswordToken, CookieManager, type CreatePermissionDto, type CreateRoleDto, type CreateTokenDto, type CreateUserDto, type CredentialSetupChangeDto, type CredentialSetupCode, type CredentialSetupConfig, CredentialSetupController, type CredentialSetupOptions, type CredentialSetupPasswordOptions, type CredentialSetupPending, CredentialSetupRepository, CredentialSetupRequirementRepository, type CredentialSetupRequirementRow, CredentialSetupRequirementService, CredentialSetupService, type CredentialSetupSessionInfo, type CredentialSetupStarted, DEFAULT_AUTH_LOGIN_RATE_LIMIT, DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME, DEFAULT_CREDENTIAL_SETUP_TTL_MS, type DefineRolesOptions, type EmailParam, EncryptionService, type GitHubOAuthConfig, type GoogleOAuthConfig, IdentityConfig, type IdentityResolver, type InviteUserDto, type JwtConfig, type JwtPayload, type LanguageParam, type LoginDto, type LoginResult, NewPermission, NewRoleEntity, NewUser, type OAuthConfig, type OAuthProvider, Owned, type OwnedMethods, type OwnershipConditionMethods, type OwnershipConfig, type OwnershipProvider, type OwnershipReadContext, type OwnershipRule, OwnershipToken, type OwnershipTokenOptions, PASSWORD_SETUP_PURPOSE, PUBLIC_REGISTRATION_MODULE, PasswordSetupService, Permission, PermissionController, PermissionGuard, type PermissionIdParam, PermissionRepository, PermissionService, PermissionValidator, Policy, type ProvisionUserInput, type ProvisionUserWithPasswordInput, type ProvisionUserWithSetupInput, ROLES, ROLE_GROUPS, type RefreshTokenDto, type RegisterDto, RegistrationController, type ResetPasswordDto, type ResolvedCredentialSetupConfig, ResolvedIdentityConfig, type ResourceAccessor, type ResourceGuards, type ResourceGuardsOptions, type RevokeTokenDto, Role, RoleController, RoleEntity, RoleGuard, type RoleIdParam, type RoleInput, RolePermission, RoleRepository, RoleService, type RoleType, RoleValidator, type RunAsUser, type SanitizedUser, ScopeContext, type ScopeResult, type SeedAuthDataConfig, type SeedAuthDataResult, type SeedUserConfig, type SessionCookieData, SessionInvalidationService, type SetPasswordToken, type SetPasswordTokenType, TOKEN_STATUS, TOKEN_TYPE, TemporaryCredentialInput, type TemporaryCredentialReset, type TokenIdParam, type TokenPair, TokenRepository, TokenService, USER_STATUS, type UpdatePermissionDto, type UpdateRoleDto, type UpdateTokenDto, type UpdateUserDto, User, UserController, type UserIdInParam, type UserIdParam, type UserListQuery, UserRepository, UserService, UserValidator, type UserWithPermissions, type VerifyTokenDto, assignPermissionDto, assignRoleDto, assignRoleParams, auth$1 as auth, authEmailRateLimitKey, authIdentityRateLimitKey, authSeed, avatarsPath, calculateAge, calculateYearsOfExperience, changePasswordDto, checkPermissionDto, clean, configureOwnership, confirmResetPasswordDto, createIdentityResolver, createPermissionDto, createRoleDto, createTokenDto, createUserDto, credentialSetupChangeDto, credentialSetupError, defaultCredentialSetupPasswordSchema, defineRoles, emailParam, formatDate, getAuthLocale, getAvatarFile, inviteUserDto, isAdmin, isAdministrator, isAuth, isEmailIdentifier, isEmpty, isFile, isPath, join, languageParam, loginDto, normalizeAuthIdentifier, normalizeSetupPurpose, own, ownershipCondition, parseSchema, permissionIdParam, pickProps, refreshTokenDto, registerDto, resetPasswordDto, resolveAuthLoginRateLimitConfig, revokeTokenDto, roleIdParam, runAsUser, seedAuthData, tokenIdParam, updatePermissionDto, updateRoleDto, updateTokenDto, updateUserDto, userIdInParam, userIdParam, userListQuery, verifyTokenDto, where };
3209
+ export { AUTH_CONFIG, AUTH_CORE_MODULE, en as AUTH_EN, AUTH_LOCALES, AUTH_LOGIN_RATE_LIMIT_ENV, AUTH_MODULE, AUTH_PERMISSIONS, AUTH_ROLE, AUTH_SCHEMA, AUTH_SUPPORTED_LANGUAGES, AUTH_USER, type AdministrativeDelivery, type AssignPermissionDto, type AssignRoleDto, type AssignRoleParams, type AuthConfig, AuthController, AuthGuard, type AuthLoginRateLimitConfig, type AuthPluginConfig, AuthQueries, type AuthRateLimitEnvironment, AuthResolver, type AuthSchema, type AuthSeedConfig, AuthService, AuthSessionService, type AuthUser, CREDENTIAL_SETUP_CODES, CREDENTIAL_SETUP_MODULE, Can, CanCreate, CanDelete, CanList, CanRead, CanUpdate, type ChainableGuard, type ChangePasswordDto, type CheckPermissionDto, type ConfiguredOwnership, type ConfirmResetPasswordDto, type ConsumedSetPasswordToken, CookieManager, type CreatePermissionDto, type CreateRoleDto, type CreateTokenDto, type CreateUserDto, type CredentialSetupChangeDto, type CredentialSetupCode, type CredentialSetupConfig, CredentialSetupController, type CredentialSetupOptions, type CredentialSetupPasswordOptions, type CredentialSetupPending, CredentialSetupRepository, CredentialSetupRequirementRepository, type CredentialSetupRequirementRow, CredentialSetupRequirementService, CredentialSetupService, type CredentialSetupSessionInfo, type CredentialSetupStarted, DEFAULT_AUTH_LOGIN_RATE_LIMIT, DEFAULT_CREDENTIAL_SETUP_COOKIE_NAME, DEFAULT_CREDENTIAL_SETUP_TTL_MS, type DefineRolesOptions, type EmailParam, EncryptionService, type GitHubOAuthConfig, type GoogleOAuthConfig, IdentityConfig, type IdentityResolver, type InviteUserDto, type JwtConfig, type JwtPayload, type LanguageParam, type LoginDto, type LoginResult, NewPermission, NewRoleEntity, NewUser, type OAuthConfig, type OAuthProvider, Owned, type OwnedMethods, type OwnedWhere, type OwnershipConditionMethods, type OwnershipConfig, type OwnershipProvider, type OwnershipReadContext, type OwnershipRule, OwnershipToken, type OwnershipTokenOptions, PASSWORD_SETUP_PURPOSE, PUBLIC_REGISTRATION_MODULE, PasswordSetupService, Permission, PermissionController, PermissionGuard, type PermissionIdParam, PermissionRepository, PermissionService, PermissionValidator, Policy, type ProvisionUserInput, type ProvisionUserWithPasswordInput, type ProvisionUserWithSetupInput, ROLES, ROLE_GROUPS, type RefreshTokenDto, type RegisterDto, RegistrationController, type ResetPasswordDto, type ResolvedCredentialSetupConfig, ResolvedIdentityConfig, type ResourceAccessor, type ResourceGuards, type ResourceGuardsOptions, type RevokeTokenDto, Role, RoleController, RoleEntity, RoleGuard, type RoleIdParam, type RoleInput, RolePermission, RoleRepository, RoleService, type RoleType, RoleValidator, type RunAsUser, type SanitizedUser, ScopeContext, type ScopeResult, type SeedAuthDataConfig, type SeedAuthDataResult, type SeedUserConfig, type SessionCookieData, SessionInvalidationService, type SetPasswordToken, type SetPasswordTokenType, TOKEN_STATUS, TOKEN_TYPE, TemporaryCredentialInput, type TemporaryCredentialReset, type TokenIdParam, type TokenPair, TokenRepository, TokenService, USER_STATUS, type UpdatePermissionDto, type UpdateRoleDto, type UpdateTokenDto, type UpdateUserDto, User, UserController, type UserIdInParam, type UserIdParam, type UserListQuery, UserRepository, UserService, UserValidator, type UserWithPermissions, type VerifyTokenDto, assignPermissionDto, assignRoleDto, assignRoleParams, auth$1 as auth, authEmailRateLimitKey, authIdentityRateLimitKey, authSeed, avatarsPath, calculateAge, calculateYearsOfExperience, changePasswordDto, checkPermissionDto, clean, configureOwnership, confirmResetPasswordDto, createIdentityResolver, createPermissionDto, createRoleDto, createTokenDto, createUserDto, credentialSetupChangeDto, credentialSetupError, defaultCredentialSetupPasswordSchema, defineRoles, emailParam, formatDate, getAuthLocale, getAvatarFile, inviteUserDto, isAdmin, isAdministrator, isAuth, isEmailIdentifier, isEmpty, isFile, isPath, join, languageParam, loginDto, normalizeAuthIdentifier, normalizeSetupPurpose, own, ownershipCondition, parseSchema, permissionIdParam, pickProps, refreshTokenDto, registerDto, resetPasswordDto, resolveAuthLoginRateLimitConfig, revokeTokenDto, roleIdParam, runAsUser, seedAuthData, tokenIdParam, updatePermissionDto, updateRoleDto, updateTokenDto, updateUserDto, userIdInParam, userIdParam, userListQuery, verifyTokenDto, where };
package/dist/index.js CHANGED
@@ -6435,6 +6435,43 @@ var __metadata33 = function(k, v) {
6435
6435
  };
6436
6436
  var _a21;
6437
6437
  var OWNED_META = Symbol.for("najm:owned");
6438
+ var OWNED_PROPERTIES = Symbol.for("najm:owned-properties");
6439
+ var propertyContexts = /* @__PURE__ */ new WeakMap();
6440
+ function ownedProperty(proto, key, tokens) {
6441
+ const inherited = Reflect.getMetadata(OWNED_PROPERTIES, proto) ?? [];
6442
+ const properties = [...inherited.filter((property) => property.key !== key), { key, tokens }];
6443
+ Reflect.defineMetadata(OWNED_PROPERTIES, properties, proto);
6444
+ Object.defineProperty(proto, key, {
6445
+ value() {
6446
+ return ownershipCondition(this.db, tokens, this._scopeCtx);
6447
+ },
6448
+ configurable: true,
6449
+ enumerable: false
6450
+ });
6451
+ if (!Reflect.hasOwnMetadata(OWNED_PROPERTIES, proto, "_scopeCtx")) {
6452
+ Inject17(ScopeContext)(proto, "_scopeCtx");
6453
+ Reflect.defineMetadata(OWNED_PROPERTIES, true, proto, "_scopeCtx");
6454
+ Object.defineProperty(proto, "_scopeCtx", {
6455
+ get() {
6456
+ return propertyContexts.get(this);
6457
+ },
6458
+ set(context) {
6459
+ propertyContexts.set(this, context);
6460
+ const properties2 = Reflect.getMetadata(OWNED_PROPERTIES, this) ?? [];
6461
+ for (const property of properties2) {
6462
+ Object.defineProperty(this, property.key, {
6463
+ value: /* @__PURE__ */ __name(() => ownershipCondition(this.db, property.tokens, this._scopeCtx), "value"),
6464
+ configurable: true,
6465
+ enumerable: false
6466
+ });
6467
+ }
6468
+ },
6469
+ configurable: true,
6470
+ enumerable: false
6471
+ });
6472
+ }
6473
+ }
6474
+ __name(ownedProperty, "ownedProperty");
6438
6475
  var ScopeContext = class ScopeContext2 {
6439
6476
  static {
6440
6477
  __name(this, "ScopeContext");
@@ -6475,7 +6512,15 @@ ScopeContext = __decorate33([
6475
6512
  function Owned(token, ...alternatives) {
6476
6513
  const tokens = [token, ...alternatives];
6477
6514
  validateOwnershipAlternatives(tokens);
6478
- return function(target) {
6515
+ return function(target, propertyKey) {
6516
+ if (propertyKey !== void 0) {
6517
+ if (typeof target === "function")
6518
+ throw new Error("@Owned requires an instance property");
6519
+ ownedProperty(target, propertyKey, tokens);
6520
+ return;
6521
+ }
6522
+ if (typeof target !== "function")
6523
+ throw new Error("@Owned requires a repository class");
6479
6524
  Reflect.defineMetadata(OWNED_META, token, target);
6480
6525
  const proto = target.prototype;
6481
6526
  Inject17(ScopeContext)(proto, "_scopeCtx");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-auth",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "Authentication and authorization library for najm framework",
5
5
  "type": "module",
6
6
  "files": [
@@ -92,7 +92,7 @@
92
92
  "dependencies": {
93
93
  "bcryptjs": "^3.0.2",
94
94
  "najm-cookies": "^2.0.2",
95
- "najm-core": "^2.0.6",
95
+ "najm-core": "^2.1.0",
96
96
  "najm-database": "^2.0.4",
97
97
  "najm-guard": "^2.0.2",
98
98
  "najm-i18n": "^2.1.2",