@happyvertical/smrt-users 0.51.31 → 0.51.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/__tests__/helpers/oidc-test-server.d.ts +45 -0
  2. package/dist/__tests__/helpers/oidc-test-server.d.ts.map +1 -0
  3. package/dist/__tests__/helpers/postgres-rls-reset.d.ts +15 -0
  4. package/dist/__tests__/helpers/postgres-rls-reset.d.ts.map +1 -0
  5. package/dist/app-contract.d.ts +11 -1
  6. package/dist/chunks/{TerminalAuthService-COafLOPX.js → TerminalAuthService-CLDmxYuC.js} +2 -2
  7. package/dist/chunks/{TerminalAuthService-COafLOPX.js.map → TerminalAuthService-CLDmxYuC.js.map} +1 -1
  8. package/dist/collections/AccessRequestCollection.d.ts +10 -0
  9. package/dist/collections/CliAuthApproveLimitCollection.d.ts +5 -0
  10. package/dist/collections/CliAuthRequestCollection.d.ts +5 -0
  11. package/dist/collections/GroupCollection.d.ts +4 -0
  12. package/dist/collections/GroupMemberCollection.d.ts +4 -0
  13. package/dist/collections/GroupRoleCollection.d.ts +4 -0
  14. package/dist/collections/MagicLinkTokenCollection.d.ts +7 -0
  15. package/dist/collections/MembershipCollection.d.ts +4 -0
  16. package/dist/collections/MembershipOverrideCollection.d.ts +4 -0
  17. package/dist/collections/PermissionCollection.d.ts +4 -0
  18. package/dist/collections/ResourceGrantCollection.d.ts +1 -0
  19. package/dist/collections/RoleCollection.d.ts +5 -1
  20. package/dist/collections/RolePermissionCollection.d.ts +6 -2
  21. package/dist/collections/SessionCollection.d.ts +4 -0
  22. package/dist/collections/TenantCollection.d.ts +4 -0
  23. package/dist/collections/TenantIntegrationCollection.d.ts +6 -1
  24. package/dist/collections/TenantPermissionOverrideCollection.d.ts +4 -0
  25. package/dist/collections/UserCollection.d.ts +6 -2
  26. package/dist/index.d.ts +56 -0
  27. package/dist/index.js +3 -3
  28. package/dist/manifest.json +1 -1
  29. package/dist/migrations/backfillLegacyUserProfiles.d.ts +1 -1
  30. package/dist/migrations/backfillUserEmailKeys.d.ts +1 -1
  31. package/dist/migrations/materializeTenantHierarchy.d.ts +2 -2
  32. package/dist/models/AccessRequest.d.ts +22 -0
  33. package/dist/models/CliAuthApproveLimit.d.ts +5 -0
  34. package/dist/models/CliAuthRequest.d.ts +12 -0
  35. package/dist/models/Group.d.ts +5 -1
  36. package/dist/models/GroupMember.d.ts +5 -1
  37. package/dist/models/GroupRole.d.ts +5 -1
  38. package/dist/models/MagicLinkToken.d.ts +9 -1
  39. package/dist/models/Membership.d.ts +6 -2
  40. package/dist/models/MembershipOverride.d.ts +5 -1
  41. package/dist/models/Permission.d.ts +5 -1
  42. package/dist/models/ResourceGrant.d.ts +2 -1
  43. package/dist/models/Role.d.ts +6 -2
  44. package/dist/models/RolePermission.d.ts +5 -1
  45. package/dist/models/Session.d.ts +5 -1
  46. package/dist/models/Tenant.d.ts +6 -2
  47. package/dist/models/TenantIntegration.d.ts +10 -1
  48. package/dist/models/TenantPermissionOverride.d.ts +5 -1
  49. package/dist/models/User.d.ts +6 -2
  50. package/dist/models/tenant-hierarchy.d.ts +23 -0
  51. package/dist/services/AccessRequestService.d.ts +42 -6
  52. package/dist/services/MagicLinkService.d.ts +30 -1
  53. package/dist/services/MobileAuthService.d.ts +43 -5
  54. package/dist/services/OidcLoginService.d.ts +12 -2
  55. package/dist/services/OperationPermissionService.d.ts +7 -3
  56. package/dist/services/PermissionCatalogService.d.ts +5 -1
  57. package/dist/services/PermissionResolver.d.ts +8 -4
  58. package/dist/services/PostgresPermissionPolicies.d.ts +6 -2
  59. package/dist/services/ResourceGrantService.d.ts +4 -3
  60. package/dist/services/SessionPermissionContext.d.ts +8 -4
  61. package/dist/services/SessionService.d.ts +10 -6
  62. package/dist/services/TenantService.d.ts +8 -4
  63. package/dist/services/TerminalAuthService.d.ts +23 -4
  64. package/dist/services/authorization-read-options.d.ts +2 -1
  65. package/dist/smrt-knowledge.json +4 -4
  66. package/dist/sveltekit/index.d.ts +23 -5
  67. package/dist/sveltekit/mobile-handlers.d.ts +42 -2
  68. package/dist/sveltekit/resource-list-handler.d.ts +30 -4
  69. package/dist/sveltekit/types.d.ts +6 -2
  70. package/dist/sveltekit.js +1 -1
  71. package/dist/ui.d.ts +7 -1
  72. package/package.json +10 -10
@@ -1,3 +1,13 @@
1
+ /**
2
+ * AccessRequestCollection — query helpers for {@link AccessRequest} records.
3
+ *
4
+ * This is the low-level data accessor. Lifecycle orchestration (the public-safe
5
+ * create path, the state machine, capability gating, events, and graduation
6
+ * into a `User`) lives in {@link AccessRequestService} — prefer the service for
7
+ * application code.
8
+ *
9
+ * @packageDocumentation
10
+ */
1
11
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
12
  import { AccessRequest } from '../models/AccessRequest.js';
3
13
  import { AccessRequestStatus } from '../types/index.js';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Atomic shared-storage limiter for terminal device-code approvals.
3
+ *
4
+ * @packageDocumentation
5
+ */
1
6
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
7
  import { UsersCliAuthApproveLimit } from '../models/CliAuthApproveLimit.js';
3
8
  export type CliAuthApproveReservation = {
@@ -1,3 +1,8 @@
1
+ /**
2
+ * UsersCliAuthRequestCollection — lookups for the device-code grant flow.
3
+ *
4
+ * @packageDocumentation
5
+ */
1
6
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
7
  import { UsersCliAuthRequest } from '../models/CliAuthRequest.js';
3
8
  export interface ApprovePendingCliAuthRequestInput {
@@ -1,3 +1,7 @@
1
+ /**
2
+ * GroupCollection - Collection manager for Group objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { Group } from '../models/Group.js';
3
7
  /**
@@ -1,3 +1,7 @@
1
+ /**
2
+ * GroupMemberCollection - Collection manager for GroupMember objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { GroupMember } from '../models/GroupMember.js';
3
7
  /**
@@ -1,3 +1,7 @@
1
+ /**
2
+ * GroupRoleCollection - Collection manager for GroupRole objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { GroupRole } from '../models/GroupRole.js';
3
7
  /**
@@ -1,3 +1,10 @@
1
+ /**
2
+ * MagicLinkTokenCollection - Collection manager for MagicLinkToken objects
3
+ *
4
+ * Provides nonce lookup and single-use enforcement for magic link authentication.
5
+ *
6
+ * @packageDocumentation
7
+ */
1
8
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
9
  import { UsersMagicLinkToken } from '../models/MagicLinkToken.js';
3
10
  /**
@@ -1,3 +1,7 @@
1
+ /**
2
+ * MembershipCollection - Collection manager for Membership objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { Membership } from '../models/Membership.js';
3
7
  import { MembershipStatus } from '../types/index.js';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * MembershipOverrideCollection - Collection manager for MembershipOverride objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { MembershipOverride } from '../models/MembershipOverride.js';
3
7
  import { OverrideEffect } from '../types/index.js';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * PermissionCollection - Collection manager for Permission objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { Permission } from '../models/Permission.js';
3
7
  /**
@@ -1,3 +1,4 @@
1
+ /** Collection helpers for exact resource grants. @packageDocumentation */
1
2
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
3
  import { ResourceGrant } from '../models/ResourceGrant.js';
3
4
  export declare class ResourceGrantCollection extends SmrtCollection<ResourceGrant> {
@@ -1,6 +1,10 @@
1
+ /**
2
+ * RoleCollection - Collection manager for Role objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { Role } from '../models/Role.js';
3
- import { RolePermissionPatternMatrix, SeedRolePermissionsOptions } from './RolePermissionCollection.js';
7
+ import type { RolePermissionPatternMatrix, SeedRolePermissionsOptions } from './RolePermissionCollection.js';
4
8
  export interface SeedSystemRolesOptions extends Omit<SeedRolePermissionsOptions, 'catalog'> {
5
9
  permissionMatrix?: RolePermissionPatternMatrix;
6
10
  seedPermissions?: boolean;
@@ -1,7 +1,11 @@
1
+ /**
2
+ * RolePermissionCollection - Collection manager for RolePermission objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { RolePermission } from '../models/RolePermission.js';
3
- import { PermissionCatalog } from '../services/PermissionCatalogService.js';
4
- import { DefaultRoleSlug } from '../types/index.js';
7
+ import { type PermissionCatalog } from '../services/PermissionCatalogService.js';
8
+ import { type DefaultRoleSlug } from '../types/index.js';
5
9
  export type RolePermissionPatternMatrix = Partial<Record<string, readonly string[]>>;
6
10
  export interface SeedRolePermissionsOptions {
7
11
  catalog?: PermissionCatalog;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * SessionCollection - Collection manager for Session objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { Session } from '../models/Session.js';
3
7
  /**
@@ -1,3 +1,7 @@
1
+ /**
2
+ * TenantCollection - Collection manager for Tenant objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { Tenant } from '../models/Tenant.js';
3
7
  import { TenantHierarchyError } from '../models/tenant-hierarchy.js';
@@ -1,5 +1,10 @@
1
+ /**
2
+ * TenantIntegrationCollection - accessors for tenant integration rows.
3
+ *
4
+ * @packageDocumentation
5
+ */
1
6
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
- import { TenantIntegration, TenantIntegrationProvider } from '../models/TenantIntegration.js';
7
+ import { TenantIntegration, type TenantIntegrationProvider } from '../models/TenantIntegration.js';
3
8
  export declare class TenantIntegrationCollection extends SmrtCollection<TenantIntegration> {
4
9
  static readonly _itemClass: typeof TenantIntegration;
5
10
  listForTenant(tenantId: string): Promise<TenantIntegration[]>;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * TenantPermissionOverrideCollection - Collection manager for TenantPermissionOverride objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
6
  import { TenantPermissionOverride } from '../models/TenantPermissionOverride.js';
3
7
  import { TenantPermissionEffect } from '../types/index.js';
@@ -1,6 +1,10 @@
1
+ /**
2
+ * UserCollection - Collection manager for User objects
3
+ * @packageDocumentation
4
+ */
1
5
  import { SmrtCollection } from '@happyvertical/smrt-core';
2
- import { OidcIdentity, Profile } from '@happyvertical/smrt-profiles';
3
- import { getDatabase } from '@happyvertical/sql';
6
+ import { OidcIdentity, type Profile } from '@happyvertical/smrt-profiles';
7
+ import type { getDatabase } from '@happyvertical/sql';
4
8
  import { User } from '../models/User.js';
5
9
  import { UserStatus } from '../types/index.js';
6
10
  type DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,59 @@
1
+ /**
2
+ * @happyvertical/smrt-users
3
+ *
4
+ * Multi-tenant user management for the SMRT framework.
5
+ * Provides users, tenants, roles, permissions, and groups.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import {
10
+ * User,
11
+ * UserCollection,
12
+ * Tenant,
13
+ * TenantCollection,
14
+ * Role,
15
+ * RoleCollection,
16
+ * Permission,
17
+ * PermissionCollection,
18
+ * Membership,
19
+ * MembershipCollection,
20
+ * PermissionResolver,
21
+ * UserStatus,
22
+ * MembershipStatus,
23
+ * } from '@happyvertical/smrt-users';
24
+ *
25
+ * // Create collections
26
+ * const users = await UserCollection.create({
27
+ * persistence: { type: 'sql', url: 'app.db' }
28
+ * });
29
+ *
30
+ * // Seed system roles
31
+ * const roles = await RoleCollection.create({ persistence: { type: 'sql', url: 'app.db' } });
32
+ * await roles.seedSystemRoles();
33
+ *
34
+ * // Resolve permissions
35
+ * const resolver = await PermissionResolver.create({ persistence: { type: 'sql', url: 'app.db' } });
36
+ * const hasAccess = await resolver.hasPermission(user.id, tenant.id, 'articles.create');
37
+ *
38
+ * // Sync manifest-derived permissions into the Permission table
39
+ * const syncResult = await syncPermissionCatalog({
40
+ * db: { type: 'postgres', url: process.env.DATABASE_URL! }
41
+ * });
42
+ * console.log(syncResult.created);
43
+ *
44
+ * // Generate or apply Postgres RLS policies
45
+ * const sql = generatePostgresPermissionSql({
46
+ * db: { type: 'postgres', url: process.env.DATABASE_URL! }
47
+ * });
48
+ * console.log(sql.targets);
49
+ * await applyPostgresPermissionPolicies({
50
+ * db: { type: 'postgres', url: process.env.DATABASE_URL! }
51
+ * });
52
+ * ```
53
+ *
54
+ * @packageDocumentation
55
+ */
56
+ import './__smrt-register__.js';
1
57
  export { AccessRequestCollection, type CliAuthApproveReservation, CliAuthRequestCollection, type CreateChildTenantOptions, type CreateSessionOptions, DEFAULT_ROLE_PERMISSION_PATTERNS, type GetOrCreateFromOidcOptions, GroupCollection, GroupMemberCollection, GroupRoleCollection, MagicLinkTokenCollection, MembershipCollection, MembershipOverrideCollection, type NormalizedOidcClaims, type OidcClaims, type OidcIdentityResult, type OidcProfileOwnerAuthorization, type OidcProfileOwnerAuthorizer, type OidcProfileOwnerAuthorizerContext, type OidcProfileResolver, type OidcProfileResolverContext, OidcProvisioningError, type OidcProvisioningErrorCode, PermissionCollection, ResourceGrantCollection, RoleCollection, RolePermissionCollection, type RolePermissionPatternMatrix, type SeedRolePermissionsOptions, type SeedRolePermissionsResult, type SeedSystemRolesOptions, SessionCollection, TenantCollection, TenantHierarchyError, TenantIntegrationCollection, TenantPermissionOverrideCollection, type TenantPermissionOverrideResult, UserCollection, UsersCliAuthApproveLimitCollection, UsersCliAuthRequestCollection, UsersMagicLinkTokenCollection, } from './collections/index.js';
2
58
  export { type BackfillLegacyUserProfilesResult, backfillLegacyUserProfiles, LEGACY_USER_PROFILE_BACKFILL_NAME, LegacyUserProfileBackfillError, type LegacyUserProfileBackfillErrorCode, } from './migrations/backfillLegacyUserProfiles.js';
3
59
  export { type BackfillUserEmailKeysResult, backfillUserEmailKeys, type DuplicateUserEmailKey, UserEmailKeyBackfillError, type UserEmailKeyBackfillErrorCode, } from './migrations/backfillUserEmailKeys.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as deriveOperationPermissionSlug, A as DEFAULT_ANCESTOR_READ_MAX_DEPTH, B as TenantPermissionOverride, C as OidcLoginService, Ct as UsersCliAuthRequestCollection, D as resolveOidcProviderConfig, Dt as generateSessionId, E as getUsersOidcConfig, Et as Session, F as UserCollection, G as applyTenantHierarchyUpdates, H as Tenant, J as recordTenantHierarchyChanges, K as assertTenantTableName, L as UserEmailKeyBackfillError, M as isAncestorReadableSlug, N as normalizeAncestorReadPolicy, Ot as UsersCliAuthRequest, P as OidcProvisioningError, Q as deriveOperationPermissionCollectionName, R as backfillUserEmailKeys, S as OidcLoginError, St as normalizeEmail, T as encodeOidcTransaction, Tt as DEFAULT_SESSION_TTL, U as MAX_TENANT_HIERARCHY_DEPTH, V as TenantCollection, W as TenantHierarchyError, X as RolePermissionCollection, Y as DEFAULT_ROLE_PERMISSION_PATTERNS, Z as PermissionCatalogService, _ as readMobileBearerToken, _t as Group, a as TerminalAuthRateLimitError, at as Role, b as PermissionResolver, bt as User, c as assertOperationPermission, ct as MembershipOverrideCollection, d as getCurrentSessionPermissionContext, dt as Membership, et as normalizeOperationPermissionAction, f as getRequestScopedDatabase, ft as GroupRoleCollection, g as MobileAuthService, gt as GroupCollection, h as MobileAuthError, ht as GroupMember, i as TerminalAuthError, it as RoleCollection, j as getConfiguredAncestorReadPolicy, k as ANCESTOR_READ_ACTION, l as checkOperationPermission, lt as MembershipOverride, m as withSessionPermissionContext, mt as GroupMemberCollection, n as DEFAULT_CLI_AUTH_REQUEST_TTL_SECONDS, nt as syncPermissionCatalog, o as TerminalAuthService, ot as PermissionCollection, p as withPrincipalPermissionContext, pt as GroupRole, q as planTenantHierarchy, r as DEFAULT_CLI_SESSION_TTL_SECONDS, rt as RolePermission, s as OperationPermissionError, st as Permission, t as DEFAULT_CLI_AUTH_POLL_INTERVAL_SECONDS, tt as registerPermissionDefinitions, u as hasOperationPermission, ut as MembershipCollection, v as validateMobileRedirectUri, vt as UsersCliAuthApproveLimitCollection, w as decodeOidcTransaction, wt as SessionCollection, x as withoutListBounds, xt as isValidEmail, y as SessionService, yt as UsersCliAuthApproveLimit, z as TenantPermissionOverrideCollection } from "./chunks/TerminalAuthService-COafLOPX.js";
1
+ import { $ as deriveOperationPermissionSlug, A as DEFAULT_ANCESTOR_READ_MAX_DEPTH, B as TenantPermissionOverride, C as OidcLoginService, Ct as UsersCliAuthRequestCollection, D as resolveOidcProviderConfig, Dt as generateSessionId, E as getUsersOidcConfig, Et as Session, F as UserCollection, G as applyTenantHierarchyUpdates, H as Tenant, J as recordTenantHierarchyChanges, K as assertTenantTableName, L as UserEmailKeyBackfillError, M as isAncestorReadableSlug, N as normalizeAncestorReadPolicy, Ot as UsersCliAuthRequest, P as OidcProvisioningError, Q as deriveOperationPermissionCollectionName, R as backfillUserEmailKeys, S as OidcLoginError, St as normalizeEmail, T as encodeOidcTransaction, Tt as DEFAULT_SESSION_TTL, U as MAX_TENANT_HIERARCHY_DEPTH, V as TenantCollection, W as TenantHierarchyError, X as RolePermissionCollection, Y as DEFAULT_ROLE_PERMISSION_PATTERNS, Z as PermissionCatalogService, _ as readMobileBearerToken, _t as Group, a as TerminalAuthRateLimitError, at as Role, b as PermissionResolver, bt as User, c as assertOperationPermission, ct as MembershipOverrideCollection, d as getCurrentSessionPermissionContext, dt as Membership, et as normalizeOperationPermissionAction, f as getRequestScopedDatabase, ft as GroupRoleCollection, g as MobileAuthService, gt as GroupCollection, h as MobileAuthError, ht as GroupMember, i as TerminalAuthError, it as RoleCollection, j as getConfiguredAncestorReadPolicy, k as ANCESTOR_READ_ACTION, l as checkOperationPermission, lt as MembershipOverride, m as withSessionPermissionContext, mt as GroupMemberCollection, n as DEFAULT_CLI_AUTH_REQUEST_TTL_SECONDS, nt as syncPermissionCatalog, o as TerminalAuthService, ot as PermissionCollection, p as withPrincipalPermissionContext, pt as GroupRole, q as planTenantHierarchy, r as DEFAULT_CLI_SESSION_TTL_SECONDS, rt as RolePermission, s as OperationPermissionError, st as Permission, t as DEFAULT_CLI_AUTH_POLL_INTERVAL_SECONDS, tt as registerPermissionDefinitions, u as hasOperationPermission, ut as MembershipCollection, v as validateMobileRedirectUri, vt as UsersCliAuthApproveLimitCollection, w as decodeOidcTransaction, wt as SessionCollection, x as withoutListBounds, xt as isValidEmail, y as SessionService, yt as UsersCliAuthApproveLimit, z as TenantPermissionOverrideCollection } from "./chunks/TerminalAuthService-CLDmxYuC.js";
2
2
  import { a as MembershipStatus, c as TenantPermissionEffect, i as DEFAULT_TENANT_POLICY, l as TenantStatus, n as DEFAULT_ROLES, o as OverrideEffect, r as DEFAULT_ROLE_SLUGS, s as SessionStatus, t as AccessRequestStatus, u as UserStatus } from "./chunks/types-DFqeph0R.js";
3
3
  import { ObjectRegistry, SmrtCollection, SmrtObject, field, findManifestEntryByQualifiedName, foreignKey, isUniqueViolationError, registerRetentionTask, smrt, unregisterRetentionTask } from "@happyvertical/smrt-core";
4
4
  import { PROFILE_EMAIL_KEY_BACKFILL_NAME, Person, ProfileCollection, ProfileTypeCollection, normalizeIdentityEmail } from "@happyvertical/smrt-profiles";
@@ -1194,7 +1194,7 @@ var MagicLinkService = class MagicLinkService {
1194
1194
  * The caller is responsible for emailing the token to the user.
1195
1195
  */
1196
1196
  async generate(email) {
1197
- const { SignJWT } = await import("./chunks/TerminalAuthService-COafLOPX.js").then((n) => n.O);
1197
+ const { SignJWT } = await import("./chunks/TerminalAuthService-CLDmxYuC.js").then((n) => n.O);
1198
1198
  const key = await this.getSigningKey();
1199
1199
  const nonce = crypto.randomUUID();
1200
1200
  const normalizedEmail = normalizeEmail(email);
@@ -1223,7 +1223,7 @@ var MagicLinkService = class MagicLinkService {
1223
1223
  * @throws {MagicLinkError} If the token is invalid, expired, or already used
1224
1224
  */
1225
1225
  async verify(token) {
1226
- const { jwtVerify, errors } = await import("./chunks/TerminalAuthService-COafLOPX.js").then((n) => n.O);
1226
+ const { jwtVerify, errors } = await import("./chunks/TerminalAuthService-CLDmxYuC.js").then((n) => n.O);
1227
1227
  const key = await this.getSigningKey();
1228
1228
  let payload;
1229
1229
  try {
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-users",
5
- "packageVersion": "0.51.31",
5
+ "packageVersion": "0.51.33",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-users:AccessRequestCollection": {
8
8
  "name": "accessrequestcollection",
@@ -1,4 +1,4 @@
1
- import { getDatabase } from '@happyvertical/sql';
1
+ import type { getDatabase } from '@happyvertical/sql';
2
2
  type DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;
3
3
  export declare const LEGACY_USER_PROFILE_BACKFILL_NAME = "@happyvertical/smrt-users:legacy-user-profiles:v1";
4
4
  export interface BackfillLegacyUserProfilesResult {
@@ -1,4 +1,4 @@
1
- import { getDatabase } from '@happyvertical/sql';
1
+ import type { getDatabase } from '@happyvertical/sql';
2
2
  type DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;
3
3
  export declare const USER_EMAIL_KEY_BACKFILL_NAME = "@happyvertical/smrt-users:user-email-keys:v1";
4
4
  export interface DuplicateUserEmailKey {
@@ -1,5 +1,5 @@
1
- import { getDatabase } from '@happyvertical/sql';
2
- import { TenantHierarchyPlan, TenantHierarchyProblem } from '../models/tenant-hierarchy.js';
1
+ import type { getDatabase } from '@happyvertical/sql';
2
+ import { type TenantHierarchyPlan, type TenantHierarchyProblem } from '../models/tenant-hierarchy.js';
3
3
  type DatabaseInterface = Awaited<ReturnType<typeof getDatabase>>;
4
4
  /** Options for {@link materializeTenantHierarchy}. */
5
5
  export interface MaterializeTenantHierarchyOptions {
@@ -1,3 +1,25 @@
1
+ /**
2
+ * AccessRequest model — the "request access / join the waitlist" identity
3
+ * primitive.
4
+ *
5
+ * Captures a prospective user from a public form *before* they are a real
6
+ * {@link User}: an operator triages the record, then either declines it or
7
+ * approves and **graduates** it into a `User` (optionally attached to a
8
+ * tenant). This keeps the `User` table clean — unverified/spam signups live as
9
+ * requests, not users — while still giving operators a triage queue.
10
+ *
11
+ * The generated REST/MCP/CLI surface is intentionally CLOSED (`include: []`):
12
+ * every read and mutation must go through {@link AccessRequestService} so the
13
+ * public-safe creation path (email normalization + dedup), the lifecycle state
14
+ * machine, capability gating, and event emission can never be bypassed by a
15
+ * generated CRUD route. Creation is meant to be exposed *unauthenticated* by
16
+ * consuming apps via their own rate-limited endpoint calling
17
+ * `createAccessRequest`. The model is still registered (and its table created
18
+ * via the consumer's normal migrate flow) regardless of the empty generation
19
+ * config.
20
+ *
21
+ * @packageDocumentation
22
+ */
1
23
  import { SmrtObject } from '@happyvertical/smrt-core';
2
24
  import { AccessRequestStatus } from '../types/index.js';
3
25
  /**
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Durable per-user failed-approval budget for terminal device codes.
3
+ *
4
+ * @packageDocumentation
5
+ */
1
6
  import { SmrtObject } from '@happyvertical/smrt-core';
2
7
  /** Private database arbiter shared by every terminal-auth process. */
3
8
  export declare class UsersCliAuthApproveLimit extends SmrtObject {
@@ -1,3 +1,15 @@
1
+ /**
2
+ * UsersCliAuthRequest model — device-code grant for terminal/CLI logins.
3
+ *
4
+ * Backs the "browser approves a terminal" flow: a CLI starts a request, the
5
+ * server returns a short user code, the user signs in on a browser and
6
+ * approves the code, then the CLI polls and gets back a session token bound
7
+ * to the approving user. Records are short-lived (TTL is enforced by
8
+ * `expiresAt`) and store only a hash of the device code so the raw device
9
+ * code is never recoverable from the database.
10
+ *
11
+ * @packageDocumentation
12
+ */
1
13
  import { SmrtObject } from '@happyvertical/smrt-core';
2
14
  /**
3
15
  * CLI auth request lifecycle states.
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * Group model - team within a tenant
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  /**
3
7
  * Constructor options for {@link Group}.
4
8
  */
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * GroupMember model - User belongs to Group (join table)
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  /**
3
7
  * Constructor options for {@link GroupMember}.
4
8
  */
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * GroupRole model - Group has Role (join table)
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  /**
3
7
  * Constructor options for {@link GroupRole}.
4
8
  */
@@ -1,4 +1,12 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * MagicLinkToken model - replay protection for magic link authentication
3
+ *
4
+ * Stores nonces embedded in magic link JWTs to prevent replay attacks.
5
+ * Each nonce can only be used once within its expiry window.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
10
  /**
3
11
  * Default magic link token expiry: 10 minutes in seconds
4
12
  */
@@ -1,5 +1,9 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
2
- import { Membership as MembershipContract } from '@happyvertical/smrt-types';
1
+ /**
2
+ * Membership model - User belongs to Tenant with a Role
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
6
+ import type { Membership as MembershipContract } from '@happyvertical/smrt-types';
3
7
  import { MembershipStatus } from '../types/index.js';
4
8
  /**
5
9
  * Constructor options for {@link Membership}.
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * MembershipOverride model - per-user permission grant/deny
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  import { OverrideEffect } from '../types/index.js';
3
7
  /**
4
8
  * Constructor options for {@link MembershipOverride}.
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * Permission model - named capability in the system
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  /**
3
7
  * Parsed permission slug components
4
8
  */
@@ -1,4 +1,5 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /** Resource-scoped authorization grants. @packageDocumentation */
2
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
3
  export type ResourceGrantEffect = 'grant' | 'deny';
3
4
  export interface ResourceGrantOptions extends SmrtObjectOptions {
4
5
  tenantId?: string;
@@ -1,5 +1,9 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
2
- import { Role as RoleContract } from '@happyvertical/smrt-types';
1
+ /**
2
+ * Role model - permission template
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
6
+ import type { Role as RoleContract } from '@happyvertical/smrt-types';
3
7
  /**
4
8
  * Constructor options for {@link Role}.
5
9
  */
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * RolePermission model - Role has Permission (join table)
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  /**
3
7
  * Constructor options for {@link RolePermission}.
4
8
  */
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * Session model - Server-side session management for authenticated users
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  import { SessionStatus } from '../types/index.js';
3
7
  /**
4
8
  * Constructor options for {@link Session}.
@@ -1,5 +1,9 @@
1
- import { SmrtObject, SmrtObjectOptions, SmrtSaveOptions } from '@happyvertical/smrt-core';
2
- import { Tenant as TenantContract } from '@happyvertical/smrt-types';
1
+ /**
2
+ * Tenant model - organizational boundary for multi-tenancy
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions, type SmrtSaveOptions } from '@happyvertical/smrt-core';
6
+ import type { Tenant as TenantContract } from '@happyvertical/smrt-types';
3
7
  import { TenantStatus } from '../types/index.js';
4
8
  /**
5
9
  * Constructor options for {@link Tenant}.
@@ -1,4 +1,13 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * TenantIntegration model - per-tenant external integration provisioning state.
3
+ *
4
+ * One row per (tenantId, provider) tuple. Stores provider identifiers and
5
+ * health/provisioning metadata only; callers must keep secrets in a dedicated
6
+ * secret store such as @happyvertical/smrt-secrets.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
11
  /**
3
12
  * Built-in provider names. The string type is intentionally open so apps can
4
13
  * add providers without a model migration.
@@ -1,4 +1,8 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
1
+ /**
2
+ * TenantPermissionOverride model - tenant-level permission grant/deny/inherit
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
2
6
  import { TenantPermissionEffect } from '../types/index.js';
3
7
  /**
4
8
  * Constructor options for {@link TenantPermissionOverride}.
@@ -1,5 +1,9 @@
1
- import { SmrtObject, SmrtObjectOptions } from '@happyvertical/smrt-core';
2
- import { User as UserContract } from '@happyvertical/smrt-types';
1
+ /**
2
+ * User model - authenticated identity linked to a Profile
3
+ * @packageDocumentation
4
+ */
5
+ import { SmrtObject, type SmrtObjectOptions } from '@happyvertical/smrt-core';
6
+ import type { User as UserContract } from '@happyvertical/smrt-types';
3
7
  import { UserStatus } from '../types/index.js';
4
8
  /**
5
9
  * Constructor options for {@link User}.
@@ -1,3 +1,26 @@
1
+ /**
2
+ * Framework-maintained tenant hierarchy materialization (smrt#3036).
3
+ *
4
+ * `Tenant.hierarchyPath` / `hierarchyLevel` are DERIVED from the
5
+ * `parentTenantId` chain. They are an authorization source — the permission
6
+ * resolver walks them for `inheritsToDescendants` and for the declared
7
+ * ancestor-read policy — so the framework, not the consumer, keeps them
8
+ * current:
9
+ *
10
+ * - {@link Tenant.save} recomputes them from the real parent chain on every
11
+ * save of any Tenant (including STI subclasses and rows created without the
12
+ * collection helpers) and re-materializes descendants when they change.
13
+ * - {@link materializeTenantHierarchy} (exposed as the
14
+ * `smrt db:materialize-tenant-hierarchy` CLI command) backfills rows written
15
+ * before this was framework-maintained.
16
+ *
17
+ * Everything here reads and writes raw rows on the tenants table. That is
18
+ * deliberate: descendants may be STI subclasses, and re-saving them through a
19
+ * base-class instance could clobber subclass columns, while only the two
20
+ * derived columns ever change.
21
+ *
22
+ * @packageDocumentation
23
+ */
1
24
  import { bumpChangeFeed } from '@happyvertical/smrt-core';
2
25
  /**
3
26
  * Maximum allowed depth for tenant hierarchy.