@h-ai/iam 0.1.0-alpha5

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/iam-config.ts","../messages/en-US.json","../messages/zh-CN.json","../src/iam-i18n.ts","../src/iam-types.ts","../src/authn/apikey/iam-authn-apikey-repository.ts","../src/user/iam-user-repository-user.ts","../src/user/iam-user-utils.ts","../src/authn/iam-authn-utils.ts","../src/authn/apikey/iam-authn-apikey-strategy.ts","../src/authn/ldap/iam-authn-ldap-strategy.ts","../src/authn/otp/iam-authn-otp-repository-otp.ts","../src/authn/otp/iam-authn-otp-strategy.ts","../src/authn/password/iam-authn-password-strategy.ts","../src/authn/iam-authn-functions.ts","../src/authz/iam-authz-repository-permission.ts","../src/authz/iam-authz-repository-relation.ts","../src/authz/iam-authz-repository-role.ts","../src/authz/iam-authz-functions.ts","../src/iam-seed.ts","../src/session/iam-session-utils.ts","../src/session/iam-session-repository-cache.ts","../src/session/iam-session-functions.ts","../src/user/iam-user-repository-reset-token.ts","../src/user/iam-user-functions.ts","../src/iam-main.ts"],"names":["core","TABLE_NAME","reldb","BaseReldbCrudRepository","err","ok","haiCrypto","logger","mapRepositoryError","cache","crypto"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @h-ai/iam — 配置 Schema\n *\n * 本文件定义 IAM 模块的配置结构,使用 Zod 进行运行时校验。\n * @module iam-config\n */\n\nimport { z } from 'zod'\n\n// ─── 认证策略配置 ───\n\n/**\n * 认证策略类型\n *\n * 支持的认证方式:\n * - `password` - 用户名/邮箱 + 密码\n * - `otp` - 邮箱/短信 + 验证码\n * - `ldap` - LDAP 目录认证\n */\nexport const AuthStrategyTypeSchema = z.enum(['password', 'otp', 'ldap', 'apikey'])\n\n/** 认证策略类型 */\nexport type AuthStrategyType = z.infer<typeof AuthStrategyTypeSchema>\n\n/**\n * 密码配置 Schema\n */\nexport const PasswordConfigSchema = z.object({\n /** 最小长度(默认 8) */\n minLength: z.number().int().min(1).default(8),\n /** 最大长度(默认 128) */\n maxLength: z.number().int().max(256).default(128),\n /** 需要大写字母 */\n requireUppercase: z.boolean().default(true),\n /** 需要小写字母 */\n requireLowercase: z.boolean().default(true),\n /** 需要数字 */\n requireNumber: z.boolean().default(true),\n /** 需要特殊字符 */\n requireSpecialChar: z.boolean().default(false),\n /** 密码过期天数(0 表示不过期) */\n expirationDays: z.number().int().min(0).default(0),\n})\n\n/** 密码配置类型 */\nexport type PasswordConfig = z.infer<typeof PasswordConfigSchema>\n\n/**\n * OTP 配置 Schema\n */\nexport const OtpConfigSchema = z.object({\n /** 验证码长度(默认 6) */\n length: z.number().int().min(4).max(8).default(6),\n /** 验证码过期时间(秒,默认 300) */\n expiresIn: z.number().int().min(60).default(300),\n /** 最大重试次数(默认 3) */\n maxAttempts: z.number().int().min(1).default(3),\n /** 发送间隔(秒,默认 60) */\n resendInterval: z.number().int().min(30).default(60),\n})\n\n/** OTP 配置类型 */\nexport type OtpConfig = z.infer<typeof OtpConfigSchema>\n\n/**\n * 密码重置配置 Schema\n */\nexport const PasswordResetConfigSchema = z.object({\n /** 重置令牌有效期(秒,默认 3600 = 1小时) */\n tokenExpiresIn: z.number().int().min(300).default(3600),\n /** 最大验证尝试次数(默认 3) */\n maxAttempts: z.number().int().min(1).default(3),\n})\n\n/** 密码重置配置类型 */\nexport type PasswordResetConfig = z.infer<typeof PasswordResetConfigSchema>\n\n/**\n * LDAP 配置 Schema\n */\nexport const LdapConfigSchema = z.object({\n /** LDAP 服务器 URL */\n url: z.string().url(),\n /** 绑定 DN */\n bindDn: z.string(),\n /** 绑定密码 */\n bindPassword: z.string(),\n /** 搜索基础 DN */\n searchBase: z.string(),\n /** 搜索过滤器(默认使用 uid) */\n searchFilter: z.string().default('(uid={{username}})'),\n /** 用户名属性 */\n usernameAttribute: z.string().default('uid'),\n /** 邮箱属性 */\n emailAttribute: z.string().default('mail'),\n /** 显示名称属性 */\n displayNameAttribute: z.string().default('cn'),\n /** 启用 TLS */\n useTls: z.boolean().default(false),\n /** 连接超时(毫秒) */\n connectTimeout: z.number().int().min(1000).default(5000),\n})\n\n/** LDAP 配置类型 */\nexport type LdapConfig = z.infer<typeof LdapConfigSchema>\n\n/**\n * API Key 配置 Schema\n */\nexport const ApiKeyConfigSchema = z.object({\n /** 单用户最大 API Key 数量(默认 10) */\n maxKeysPerUser: z.number().int().min(1).default(10),\n /** API Key 默认有效期(天,0 表示永不过期,默认 0) */\n defaultExpirationDays: z.number().int().min(0).default(0),\n /** API Key 前缀(默认 'hai_') */\n prefix: z.string().default('hai_'),\n})\n\n/** API Key 配置类型 */\nexport type ApiKeyConfig = z.infer<typeof ApiKeyConfigSchema>\n\n// ─── 登录/注册与安全策略配置 ───\n\n/** 登录类型启用配置 */\nexport const LoginConfigSchema = z.object({\n /** 是否启用密码登录 */\n password: z.boolean().default(true),\n /** 是否启用 OTP 登录 */\n otp: z.boolean().default(true),\n /** 是否启用 LDAP 登录 */\n ldap: z.boolean().default(true),\n /** 是否启用 API Key 登录 */\n apikey: z.boolean().default(false),\n})\n\nexport type LoginConfig = z.infer<typeof LoginConfigSchema>\n\n/** 注册配置 */\nexport const RegisterConfigSchema = z.object({\n /** 是否启用注册 */\n enabled: z.boolean().default(true),\n /** 新注册用户是否默认启用 */\n defaultEnabled: z.boolean().default(true),\n})\n\nexport type RegisterConfig = z.infer<typeof RegisterConfigSchema>\n\n/** 安全策略配置 */\nexport const SecurityConfigSchema = z.object({\n /** 最大登录失败次数(默认 5) */\n maxLoginAttempts: z.number().int().min(1).default(5),\n /** 锁定时长(秒,默认 900) */\n lockoutDuration: z.number().int().min(60).default(900),\n})\n\nexport type SecurityConfig = z.infer<typeof SecurityConfigSchema>\n\n/** 协议展示配置 */\nexport const AgreementConfigSchema = z.object({\n /** 用户协议 URL */\n userAgreementUrl: z.url().optional(),\n /** 隐私协议 URL */\n privacyPolicyUrl: z.url().optional(),\n /** 注册时展示协议 */\n showOnRegister: z.boolean().default(true),\n /** 登录时展示协议 */\n showOnLogin: z.boolean().default(false),\n})\n\nexport type AgreementConfig = z.infer<typeof AgreementConfigSchema>\n\n// ─── 会话配置 ───\n\n/**\n * 会话配置 Schema\n */\nexport const SessionConfigSchema = z.object({\n /** 会话超时时间(秒,默认 86400 = 24小时) */\n maxAge: z.number().int().min(60).default(86400),\n /** 是否滑动窗口(每次访问刷新过期时间) */\n sliding: z.boolean().default(true),\n /** 单设备登录(踢掉其他设备) */\n singleDevice: z.boolean().default(false),\n /** refreshToken 过期时间(秒,默认 604800 = 7天) */\n refreshTokenMaxAge: z.number().int().min(3600).default(604800),\n})\n\n/** 会话配置类型 */\nexport type SessionConfig = z.infer<typeof SessionConfigSchema>\n\n// ─── RBAC 配置 ───\n\n/**\n * RBAC 配置 Schema\n */\nexport const RbacConfigSchema = z.object({\n /** 是否启用 RBAC */\n enabled: z.boolean().default(true),\n /** 超级管理员角色代码 */\n superAdminRole: z.string().default('super_admin'),\n /** 默认用户角色 */\n defaultRole: z.string().default('user'),\n})\n\n/** RBAC 配置类型 */\nexport type RbacConfig = z.infer<typeof RbacConfigSchema>\n\n// ─── 统一配置 ───\n\n/**\n * IAM 统一配置 Schema\n *\n * @example\n * ```ts\n * const config: IamConfig = {\n * password: { minLength: 8 },\n * session: {\n * maxAge: 86400,\n * sliding: true\n * },\n * login: { password: true, otp: true },\n * register: { enabled: true, defaultEnabled: true },\n * rbac: { enabled: true }\n * }\n * ```\n */\nexport const IamConfigSchema = z.object({\n // ─── 认证策略配置 ───\n\n /** 密码配置 */\n password: PasswordConfigSchema.optional(),\n\n /** OTP 配置 */\n otp: OtpConfigSchema.optional(),\n\n /** LDAP 配置 */\n ldap: LdapConfigSchema.optional(),\n\n /** API Key 配置 */\n apikey: ApiKeyConfigSchema.optional(),\n\n /** 密码重置配置 */\n passwordReset: PasswordResetConfigSchema.optional(),\n\n /** 登录启用配置 */\n login: LoginConfigSchema.default({\n password: true,\n otp: true,\n ldap: true,\n apikey: false,\n }),\n\n /** 注册配置 */\n register: RegisterConfigSchema.default({\n enabled: true,\n defaultEnabled: true,\n }),\n\n /** 协议展示配置 */\n agreements: AgreementConfigSchema.default({\n showOnRegister: true,\n showOnLogin: false,\n }),\n\n /** 安全策略配置 */\n security: SecurityConfigSchema.default({\n maxLoginAttempts: 5,\n lockoutDuration: 900,\n }),\n\n // ─── 会话配置 ───\n\n /** 会话配置 */\n session: SessionConfigSchema.optional(),\n\n // ─── 授权配置 ───\n\n /** RBAC 配置 */\n rbac: RbacConfigSchema.optional(),\n\n // ─── 运行时选项 ───\n\n /** 是否初始化默认角色和权限(默认 true) */\n seedDefaultData: z.boolean().default(true),\n})\n\n/** IAM 配置类型 */\nexport type IamConfig = z.infer<typeof IamConfigSchema>\n\n/**\n * IAM 配置设置输入类型(仅设置字段,不含运行时依赖)\n *\n * 说明:Zod 的 default 会让输入端字段可省略,但输出端字段为必填。\n */\nexport type IamConfigSettingsInput = z.input<typeof IamConfigSchema>\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"iam_passwordMinLength\": \"Password must be at least {minLength} characters\",\n \"iam_passwordMaxLength\": \"Password cannot exceed {maxLength} characters\",\n \"iam_passwordNeedUppercase\": \"Password must contain uppercase letters\",\n \"iam_passwordNeedLowercase\": \"Password must contain lowercase letters\",\n \"iam_passwordNeedNumber\": \"Password must contain numbers\",\n \"iam_passwordNeedSpecialChar\": \"Password must contain special characters\",\n \"iam_credentialTypeMismatch\": \"Credential type mismatch\",\n \"iam_userNotExist\": \"User does not exist\",\n \"iam_accountDisabled\": \"Account is disabled\",\n \"iam_accountLocked\": \"Account is locked, please try again later\",\n \"iam_accountNoPassword\": \"Account has no password set\",\n \"iam_passwordWrong\": \"Incorrect password\",\n \"iam_passwordExpired\": \"Password has expired, please change your password\",\n \"iam_otpNotExistOrExpired\": \"Verification code does not exist or has expired\",\n \"iam_otpInvalid\": \"Verification code is invalid, please request a new one\",\n \"iam_otpWrong\": \"Incorrect verification code\",\n \"iam_otpResendTooFast\": \"Please wait {seconds} seconds before requesting another code\",\n \"iam_identifierTypeNotSupported\": \"Unsupported identifier type or delivery method not configured\",\n \"iam_loginDisabled\": \"Login via {type} is disabled\",\n \"iam_registerDisabled\": \"Registration is disabled\",\n \"iam_otpStrategyRequired\": \"OTP authentication requires OTP strategy configuration\",\n \"iam_otpStrategyRequiredForSend\": \"OTP requires OTP strategy configuration\",\n \"iam_userNotExistNoAutoRegister\": \"User does not exist and auto-registration is not enabled\",\n \"iam_refreshTokenFailed\": \"Failed to refresh token\",\n \"iam_refreshTokenExpired\": \"Refresh token has expired\",\n \"iam_refreshTokenRequestFailed\": \"Refresh token request failed\",\n \"iam_ldapConnectionFailed\": \"Unable to connect to LDAP server\",\n \"iam_ldapAdminBindFailed\": \"LDAP admin bind failed\",\n \"iam_ldapSearchFailed\": \"LDAP search failed\",\n \"iam_ldapStrategyRequired\": \"LDAP authentication requires LDAP strategy configuration\",\n \"iam_tokenExpired\": \"Token has expired\",\n \"iam_tokenInvalid\": \"Invalid token\",\n \"iam_createSessionFailed\": \"Failed to create session\",\n \"iam_sessionExpired\": \"Session has expired\",\n \"iam_invalidRefreshToken\": \"Invalid refresh token\",\n \"iam_sessionNotExist\": \"Session does not exist\",\n \"iam_usernameAlreadyExist\": \"Username already exists\",\n \"iam_emailAlreadyUsed\": \"Email is already in use\",\n \"iam_originalPasswordWrong\": \"Original password is incorrect\",\n \"iam_featureNotImplemented\": \"Feature not implemented\",\n \"iam_userAlreadyExist\": \"User already exists\",\n \"iam_parseSessionDataFailed\": \"Failed to parse session data\",\n \"iam_roleAlreadyExist\": \"Role already exists\",\n \"iam_roleNotExist\": \"Role does not exist\",\n \"iam_cannotDeleteSystemRole\": \"Cannot delete system role\",\n \"iam_permissionAlreadyExist\": \"Permission already exists\",\n \"iam_permissionNotExist\": \"Permission does not exist\",\n \"iam_notInitialized\": \"Not initialized, please call iam.init() first\",\n \"iam_initFailed\": \"Initialization failed\",\n \"iam_depsNotInitialized\": \"Dependency {dep} is not initialized, please call {dep}.init() before iam.init()\",\n \"iam_initInProgress\": \"IAM initialization is already in progress\",\n \"iam_cacheRequired\": \"Cache service is required for session management\",\n \"iam_initComponentFailed\": \"Failed to initialize component\",\n \"iam_initSeedDataFailed\": \"Failed to initialize seed data\",\n \"iam_createUserTableFailed\": \"Failed to create user table: {message}\",\n \"iam_queryUserFailed\": \"Failed to query user: {message}\",\n \"iam_createUserFailed\": \"Failed to create user: {message}\",\n \"iam_queryUserListFailed\": \"Failed to query user list: {message}\",\n \"iam_updateUserFailed\": \"Failed to update user: {message}\",\n \"iam_deleteUserFailed\": \"Failed to delete user: {message}\",\n \"iam_createSessionTableFailed\": \"Failed to create session table: {message}\",\n \"iam_createSessionIndexFailed\": \"Failed to create session index: {message}\",\n \"iam_createSessionRecordFailed\": \"Failed to create session record: {message}\",\n \"iam_querySessionFailed\": \"Failed to query session: {message}\",\n \"iam_updateSessionFailed\": \"Failed to update session: {message}\",\n \"iam_deleteSessionFailed\": \"Failed to delete session: {message}\",\n \"iam_cleanupSessionFailed\": \"Failed to cleanup session: {message}\",\n \"iam_createSessionStoreTableFailed\": \"Failed to create session store table: {message}\",\n \"iam_createTokenMappingTableFailed\": \"Failed to create token mapping table: {message}\",\n \"iam_createUserSessionTableFailed\": \"Failed to create user session table: {message}\",\n \"iam_createSessionStoreIndexFailed\": \"Failed to create session index: {message}\",\n \"iam_saveSessionFailed\": \"Failed to save session: {message}\",\n \"iam_queryTokenMappingFailed\": \"Failed to query token mapping: {message}\",\n \"iam_saveTokenMappingFailed\": \"Failed to save token mapping: {message}\",\n \"iam_deleteTokenMappingFailed\": \"Failed to delete token mapping: {message}\",\n \"iam_deleteUserSessionMappingFailed\": \"Failed to delete user session mapping: {message}\",\n \"iam_queryUserSessionFailed\": \"Failed to query user session: {message}\",\n \"iam_addUserSessionMappingFailed\": \"Failed to add user session mapping: {message}\",\n \"iam_createRoleTableFailed\": \"Failed to create role table: {message}\",\n \"iam_queryRoleFailed\": \"Failed to query role: {message}\",\n \"iam_queryRoleListFailed\": \"Failed to query role list: {message}\",\n \"iam_createRoleFailed\": \"Failed to create role: {message}\",\n \"iam_updateRoleFailed\": \"Failed to update role: {message}\",\n \"iam_deleteRoleFailed\": \"Failed to delete role: {message}\",\n \"iam_createRolePermissionTableFailed\": \"Failed to create role-permission table: {message}\",\n \"iam_createRolePermissionIndexFailed\": \"Failed to create role-permission index: {message}\",\n \"iam_assignPermissionFailed\": \"Failed to assign permission: {message}\",\n \"iam_removePermissionFailed\": \"Failed to remove permission: {message}\",\n \"iam_createUserRoleTableFailed\": \"Failed to create user-role table: {message}\",\n \"iam_createUserRoleIndexFailed\": \"Failed to create user-role index: {message}\",\n \"iam_assignRoleFailed\": \"Failed to assign role: {message}\",\n \"iam_removeRoleFailed\": \"Failed to remove role: {message}\",\n \"iam_syncRolesFailed\": \"Failed to sync roles: {message}\",\n \"iam_createPermissionTableFailed\": \"Failed to create permission table: {message}\",\n \"iam_createPermissionFailed\": \"Failed to create permission: {message}\",\n \"iam_queryPermissionFailed\": \"Failed to query permission: {message}\",\n \"iam_queryPermissionListFailed\": \"Failed to query permission list: {message}\",\n \"iam_deletePermissionFailed\": \"Failed to delete permission: {message}\",\n \"iam_queryPermissionCacheFailed\": \"Failed to query permission cache: {message}\",\n \"iam_setPermissionCacheFailed\": \"Failed to set permission cache: {message}\",\n \"iam_clearPermissionCacheFailed\": \"Failed to clear permission cache: {message}\",\n \"iam_queryOtpCacheFailed\": \"Failed to query OTP cache: {message}\",\n \"iam_saveOtpCacheFailed\": \"Failed to save OTP cache: {message}\",\n \"iam_updateOtpCacheFailed\": \"Failed to update OTP cache: {message}\",\n \"iam_deleteOtpCacheFailed\": \"Failed to delete OTP cache: {message}\",\n \"iam_querySessionMappingCacheFailed\": \"Failed to query session mapping cache: {message}\",\n \"iam_saveSessionMappingCacheFailed\": \"Failed to save session mapping cache: {message}\",\n \"iam_deleteSessionMappingCacheFailed\": \"Failed to delete session mapping cache: {message}\",\n \"iam_queryTokenMappingCacheFailed\": \"Failed to query token mapping cache: {message}\",\n \"iam_saveTokenMappingCacheFailed\": \"Failed to save token mapping cache: {message}\",\n \"iam_deleteTokenMappingCacheFailed\": \"Failed to delete token mapping cache: {message}\",\n \"iam_queryUserSessionCacheFailed\": \"Failed to query user session cache: {message}\",\n \"iam_saveUserSessionCacheFailed\": \"Failed to save user session cache: {message}\",\n \"iam_deleteUserSessionCacheFailed\": \"Failed to delete user session cache: {message}\",\n \"iam_createOtpTableFailed\": \"Failed to create OTP table: {message}\",\n \"iam_saveOtpFailed\": \"Failed to save OTP: {message}\",\n \"iam_queryOtpFailed\": \"Failed to query OTP: {message}\",\n \"iam_updateOtpAttemptsFailed\": \"Failed to update OTP attempts: {message}\",\n \"iam_deleteOtpFailed\": \"Failed to delete OTP: {message}\",\n \"iam_otpSendFailed\": \"Failed to send OTP: {message}\",\n \"iam_resetTokenInvalid\": \"Invalid or expired password reset token\",\n \"iam_resetTokenMaxAttempts\": \"Too many verification attempts, please request a new reset token\",\n \"iam_saveResetTokenFailed\": \"Failed to save password reset token: {message}\",\n \"iam_hashResetTokenFailed\": \"Failed to hash reset token: {message}\",\n \"iam_queryResetTokenFailed\": \"Failed to query password reset token: {message}\",\n \"iam_passwordResetNotConfigured\": \"Password reset is not configured\",\n \"iam_clientFetchNotAvailable\": \"Fetch is not available in the current environment\",\n \"iam_clientRequestFailed\": \"Request failed: {status}\",\n \"iam_clientNetworkError\": \"Network request failed\",\n \"iam_clientNetworkErrorWithDetail\": \"Network request failed: {message}\",\n \"iam_seedRoleAdminName\": \"Administrator\",\n \"iam_seedRoleAdminDesc\": \"System administrator with all permissions\",\n \"iam_seedRoleUserName\": \"User\",\n \"iam_seedRoleUserDesc\": \"Standard user\",\n \"iam_seedRoleGuestName\": \"Guest\",\n \"iam_seedRoleGuestDesc\": \"Guest with read-only access\",\n \"iam_seedPermUserRead\": \"View Users\",\n \"iam_seedPermUserCreate\": \"Create Users\",\n \"iam_seedPermUserUpdate\": \"Update Users\",\n \"iam_seedPermUserDelete\": \"Delete Users\",\n \"iam_seedPermUserList\": \"List Users API\",\n \"iam_seedPermUserApiCreate\": \"Create User API\",\n \"iam_seedPermUserApiUpdate\": \"Update User API\",\n \"iam_seedPermUserApiDelete\": \"Delete User API\",\n \"iam_seedPermRoleRead\": \"View Roles\",\n \"iam_seedPermRoleCreate\": \"Create Roles\",\n \"iam_seedPermRoleUpdate\": \"Update Roles\",\n \"iam_seedPermRoleDelete\": \"Delete Roles\",\n \"iam_seedPermRoleList\": \"List Roles API\",\n \"iam_seedPermRoleApiCreate\": \"Create Role API\",\n \"iam_seedPermRoleApiUpdate\": \"Update Role API\",\n \"iam_seedPermRoleApiDelete\": \"Delete Role API\",\n \"iam_seedPermPermRead\": \"View Permissions\",\n \"iam_seedPermPermManage\": \"Manage Permissions\",\n \"iam_seedPermPermCreate\": \"Create Permissions\",\n \"iam_seedPermPermDelete\": \"Delete Permissions\",\n \"iam_seedPermPermList\": \"List Permissions API\",\n \"iam_seedPermPermApiCreate\": \"Create Permission API\",\n \"iam_seedPermPermApiDelete\": \"Delete Permission API\",\n \"iam_seedPermSystemSettings\": \"System Settings\",\n \"iam_seedPermSystemLogs\": \"View Logs\",\n \"iam_seedPermSystemModules\": \"Module Management\",\n \"iam_seedPermDashboardView\": \"Dashboard\",\n \"iam_seedPermProfileRead\": \"Profile\",\n \"iam_seedPermAuditRead\": \"Audit Logs\",\n \"iam_configError\": \"IAM config validation failed: {error}\",\n \"iam_apikeyInvalid\": \"Invalid API Key\",\n \"iam_apikeyExpired\": \"API Key has expired\",\n \"iam_apikeyDisabled\": \"API Key is disabled\",\n \"iam_apikeyMaxKeysReached\": \"Maximum number of API Keys ({max}) reached\",\n \"iam_apikeyCreateFailed\": \"Failed to create API Key: {message}\",\n \"iam_apikeyUpdateFailed\": \"Failed to update API Key: {message}\",\n \"iam_apikeyDeleteFailed\": \"Failed to delete API Key: {message}\",\n \"iam_apikeyQueryFailed\": \"Failed to query API Key: {message}\",\n \"iam_apikeyStrategyRequired\": \"API Key authentication requires API Key strategy configuration\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"iam_passwordMinLength\": \"密码长度至少为 {minLength} 个字符\",\n \"iam_passwordMaxLength\": \"密码长度不能超过 {maxLength} 个字符\",\n \"iam_passwordNeedUppercase\": \"密码必须包含大写字母\",\n \"iam_passwordNeedLowercase\": \"密码必须包含小写字母\",\n \"iam_passwordNeedNumber\": \"密码必须包含数字\",\n \"iam_passwordNeedSpecialChar\": \"密码必须包含特殊字符\",\n \"iam_credentialTypeMismatch\": \"凭证类型不匹配\",\n \"iam_userNotExist\": \"用户不存在\",\n \"iam_accountDisabled\": \"账户已禁用\",\n \"iam_accountLocked\": \"账户已锁定,请稍后重试\",\n \"iam_accountNoPassword\": \"账户未设置密码\",\n \"iam_passwordWrong\": \"密码错误\",\n \"iam_passwordExpired\": \"密码已过期,请修改密码\",\n \"iam_otpNotExistOrExpired\": \"验证码不存在或已过期\",\n \"iam_otpInvalid\": \"验证码已失效,请重新获取\",\n \"iam_otpWrong\": \"验证码错误\",\n \"iam_otpResendTooFast\": \"请等待 {seconds} 秒后再获取验证码\",\n \"iam_identifierTypeNotSupported\": \"不支持的标识符类型或发送方式未配置\",\n \"iam_loginDisabled\": \"{type} 登录已禁用\",\n \"iam_registerDisabled\": \"注册功能已禁用\",\n \"iam_otpStrategyRequired\": \"OTP 认证需要配置 OTP 策略\",\n \"iam_otpStrategyRequiredForSend\": \"OTP 需要配置 OTP 策略\",\n \"iam_userNotExistNoAutoRegister\": \"用户不存在且未启用自动注册\",\n \"iam_refreshTokenFailed\": \"刷新令牌失败\",\n \"iam_refreshTokenExpired\": \"刷新令牌已过期\",\n \"iam_refreshTokenRequestFailed\": \"刷新令牌请求失败\",\n \"iam_ldapConnectionFailed\": \"无法连接到 LDAP 服务器\",\n \"iam_ldapAdminBindFailed\": \"LDAP 管理员绑定失败\",\n \"iam_ldapSearchFailed\": \"LDAP 搜索失败\",\n \"iam_ldapStrategyRequired\": \"LDAP 认证需要配置 LDAP 策略\",\n \"iam_tokenExpired\": \"令牌已过期\",\n \"iam_tokenInvalid\": \"令牌无效\",\n \"iam_createSessionFailed\": \"创建会话失败\",\n \"iam_sessionExpired\": \"会话已失效\",\n \"iam_invalidRefreshToken\": \"无效的刷新令牌\",\n \"iam_sessionNotExist\": \"会话不存在\",\n \"iam_usernameAlreadyExist\": \"用户名已存在\",\n \"iam_emailAlreadyUsed\": \"邮箱已被使用\",\n \"iam_originalPasswordWrong\": \"原密码错误\",\n \"iam_featureNotImplemented\": \"功能暂未实现\",\n \"iam_userAlreadyExist\": \"用户已存在\",\n \"iam_parseSessionDataFailed\": \"解析会话数据失败\",\n \"iam_roleAlreadyExist\": \"角色已存在\",\n \"iam_roleNotExist\": \"角色不存在\",\n \"iam_cannotDeleteSystemRole\": \"不能删除系统角色\",\n \"iam_permissionAlreadyExist\": \"权限已存在\",\n \"iam_permissionNotExist\": \"权限不存在\",\n \"iam_notInitialized\": \"未初始化,请先调用 iam.init()\",\n \"iam_initFailed\": \"初始化失败\",\n \"iam_depsNotInitialized\": \"依赖 {dep} 未初始化,请在 iam.init() 之前调用 {dep}.init()\",\n \"iam_initInProgress\": \"IAM 初始化正在进行中\",\n \"iam_cacheRequired\": \"会话管理需要提供缓存服务\",\n \"iam_initComponentFailed\": \"初始化组件失败\",\n \"iam_initSeedDataFailed\": \"初始化种子数据失败\",\n \"iam_createUserTableFailed\": \"创建用户表失败: {message}\",\n \"iam_queryUserFailed\": \"查询用户失败: {message}\",\n \"iam_createUserFailed\": \"创建用户失败: {message}\",\n \"iam_queryUserListFailed\": \"查询用户列表失败: {message}\",\n \"iam_updateUserFailed\": \"更新用户失败: {message}\",\n \"iam_deleteUserFailed\": \"删除用户失败: {message}\",\n \"iam_createSessionTableFailed\": \"创建会话表失败: {message}\",\n \"iam_createSessionIndexFailed\": \"创建会话索引失败: {message}\",\n \"iam_createSessionRecordFailed\": \"创建会话失败: {message}\",\n \"iam_querySessionFailed\": \"查询会话失败: {message}\",\n \"iam_updateSessionFailed\": \"更新会话失败: {message}\",\n \"iam_deleteSessionFailed\": \"删除会话失败: {message}\",\n \"iam_cleanupSessionFailed\": \"清理会话失败: {message}\",\n \"iam_createSessionStoreTableFailed\": \"创建会话存储表失败: {message}\",\n \"iam_createTokenMappingTableFailed\": \"创建令牌映射表失败: {message}\",\n \"iam_createUserSessionTableFailed\": \"创建用户会话表失败: {message}\",\n \"iam_createSessionStoreIndexFailed\": \"创建会话索引失败: {message}\",\n \"iam_saveSessionFailed\": \"保存会话失败: {message}\",\n \"iam_queryTokenMappingFailed\": \"查询令牌映射失败: {message}\",\n \"iam_saveTokenMappingFailed\": \"保存令牌映射失败: {message}\",\n \"iam_deleteTokenMappingFailed\": \"删除令牌映射失败: {message}\",\n \"iam_deleteUserSessionMappingFailed\": \"删除用户会话映射失败: {message}\",\n \"iam_queryUserSessionFailed\": \"查询用户会话失败: {message}\",\n \"iam_addUserSessionMappingFailed\": \"添加用户会话映射失败: {message}\",\n \"iam_createRoleTableFailed\": \"创建角色表失败: {message}\",\n \"iam_queryRoleFailed\": \"查询角色失败: {message}\",\n \"iam_queryRoleListFailed\": \"查询角色列表失败: {message}\",\n \"iam_createRoleFailed\": \"创建角色失败: {message}\",\n \"iam_updateRoleFailed\": \"更新角色失败: {message}\",\n \"iam_deleteRoleFailed\": \"删除角色失败: {message}\",\n \"iam_createRolePermissionTableFailed\": \"创建角色-权限关联表失败: {message}\",\n \"iam_createRolePermissionIndexFailed\": \"创建角色-权限索引失败: {message}\",\n \"iam_assignPermissionFailed\": \"分配权限失败: {message}\",\n \"iam_removePermissionFailed\": \"移除权限失败: {message}\",\n \"iam_createUserRoleTableFailed\": \"创建用户-角色关联表失败: {message}\",\n \"iam_createUserRoleIndexFailed\": \"创建用户-角色索引失败: {message}\",\n \"iam_assignRoleFailed\": \"分配角色失败: {message}\",\n \"iam_removeRoleFailed\": \"移除角色失败: {message}\",\n \"iam_syncRolesFailed\": \"同步角色失败: {message}\",\n \"iam_createPermissionTableFailed\": \"创建权限表失败: {message}\",\n \"iam_createPermissionFailed\": \"创建权限失败: {message}\",\n \"iam_queryPermissionFailed\": \"查询权限失败: {message}\",\n \"iam_queryPermissionListFailed\": \"查询权限列表失败: {message}\",\n \"iam_deletePermissionFailed\": \"删除权限失败: {message}\",\n \"iam_queryPermissionCacheFailed\": \"查询权限缓存失败: {message}\",\n \"iam_setPermissionCacheFailed\": \"设置权限缓存失败: {message}\",\n \"iam_clearPermissionCacheFailed\": \"清除权限缓存失败: {message}\",\n \"iam_queryOtpCacheFailed\": \"查询 OTP 缓存失败: {message}\",\n \"iam_saveOtpCacheFailed\": \"保存 OTP 缓存失败: {message}\",\n \"iam_updateOtpCacheFailed\": \"更新 OTP 缓存失败: {message}\",\n \"iam_deleteOtpCacheFailed\": \"删除 OTP 缓存失败: {message}\",\n \"iam_querySessionMappingCacheFailed\": \"查询会话映射缓存失败: {message}\",\n \"iam_saveSessionMappingCacheFailed\": \"保存会话映射缓存失败: {message}\",\n \"iam_deleteSessionMappingCacheFailed\": \"删除会话映射缓存失败: {message}\",\n \"iam_queryTokenMappingCacheFailed\": \"查询令牌映射缓存失败: {message}\",\n \"iam_saveTokenMappingCacheFailed\": \"保存令牌映射缓存失败: {message}\",\n \"iam_deleteTokenMappingCacheFailed\": \"删除令牌映射缓存失败: {message}\",\n \"iam_queryUserSessionCacheFailed\": \"查询用户会话缓存失败: {message}\",\n \"iam_saveUserSessionCacheFailed\": \"保存用户会话缓存失败: {message}\",\n \"iam_deleteUserSessionCacheFailed\": \"删除用户会话缓存失败: {message}\",\n \"iam_createOtpTableFailed\": \"创建 OTP 表失败: {message}\",\n \"iam_saveOtpFailed\": \"保存 OTP 失败: {message}\",\n \"iam_queryOtpFailed\": \"查询 OTP 失败: {message}\",\n \"iam_updateOtpAttemptsFailed\": \"更新 OTP 尝试次数失败: {message}\",\n \"iam_deleteOtpFailed\": \"删除 OTP 失败: {message}\",\n \"iam_otpSendFailed\": \"验证码发送失败: {message}\",\n \"iam_resetTokenInvalid\": \"密码重置令牌无效或已过期\",\n \"iam_resetTokenMaxAttempts\": \"验证次数过多,请重新申请重置令牌\",\n \"iam_saveResetTokenFailed\": \"保存密码重置令牌失败: {message}\",\n \"iam_hashResetTokenFailed\": \"密码重置令牌哈希失败: {message}\",\n \"iam_queryResetTokenFailed\": \"查询密码重置令牌失败: {message}\",\n \"iam_passwordResetNotConfigured\": \"密码重置功能未配置\",\n \"iam_clientFetchNotAvailable\": \"当前环境不支持 Fetch\",\n \"iam_clientRequestFailed\": \"请求失败: {status}\",\n \"iam_clientNetworkError\": \"网络请求失败\",\n \"iam_clientNetworkErrorWithDetail\": \"网络请求失败: {message}\",\n \"iam_seedRoleAdminName\": \"管理员\",\n \"iam_seedRoleAdminDesc\": \"系统管理员,拥有所有权限\",\n \"iam_seedRoleUserName\": \"普通用户\",\n \"iam_seedRoleUserDesc\": \"普通用户\",\n \"iam_seedRoleGuestName\": \"访客\",\n \"iam_seedRoleGuestDesc\": \"访客,只读权限\",\n \"iam_seedPermUserRead\": \"查看用户\",\n \"iam_seedPermUserCreate\": \"创建用户\",\n \"iam_seedPermUserUpdate\": \"更新用户\",\n \"iam_seedPermUserDelete\": \"删除用户\",\n \"iam_seedPermUserList\": \"用户列表 API\",\n \"iam_seedPermUserApiCreate\": \"创建用户 API\",\n \"iam_seedPermUserApiUpdate\": \"更新用户 API\",\n \"iam_seedPermUserApiDelete\": \"删除用户 API\",\n \"iam_seedPermRoleRead\": \"查看角色\",\n \"iam_seedPermRoleCreate\": \"创建角色\",\n \"iam_seedPermRoleUpdate\": \"更新角色\",\n \"iam_seedPermRoleDelete\": \"删除角色\",\n \"iam_seedPermRoleList\": \"角色列表 API\",\n \"iam_seedPermRoleApiCreate\": \"创建角色 API\",\n \"iam_seedPermRoleApiUpdate\": \"更新角色 API\",\n \"iam_seedPermRoleApiDelete\": \"删除角色 API\",\n \"iam_seedPermPermRead\": \"查看权限\",\n \"iam_seedPermPermManage\": \"管理权限\",\n \"iam_seedPermPermCreate\": \"创建权限\",\n \"iam_seedPermPermDelete\": \"删除权限\",\n \"iam_seedPermPermList\": \"权限列表 API\",\n \"iam_seedPermPermApiCreate\": \"创建权限 API\",\n \"iam_seedPermPermApiDelete\": \"删除权限 API\",\n \"iam_seedPermSystemSettings\": \"系统设置\",\n \"iam_seedPermSystemLogs\": \"查看日志\",\n \"iam_seedPermSystemModules\": \"模块管理\",\n \"iam_seedPermDashboardView\": \"仪表盘\",\n \"iam_seedPermProfileRead\": \"个人中心\",\n \"iam_seedPermAuditRead\": \"审计日志\",\n \"iam_configError\": \"IAM 配置校验失败:{error}\",\n \"iam_apikeyInvalid\": \"API Key 无效\",\n \"iam_apikeyExpired\": \"API Key 已过期\",\n \"iam_apikeyDisabled\": \"API Key 已禁用\",\n \"iam_apikeyMaxKeysReached\": \"API Key 数量已达上限({max})\",\n \"iam_apikeyCreateFailed\": \"创建 API Key 失败:{message}\",\n \"iam_apikeyUpdateFailed\": \"更新 API Key 失败:{message}\",\n \"iam_apikeyDeleteFailed\": \"删除 API Key 失败:{message}\",\n \"iam_apikeyQueryFailed\": \"查询 API Key 失败:{message}\",\n \"iam_apikeyStrategyRequired\": \"API Key 认证需要 API Key 策略配置\"\n}\n","/**\n * @h-ai/iam — i18n\n *\n * 本文件提供 IAM 模块的 i18n 文案访问入口。 模块内部使用,不对外导出。\n * @module iam-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n// ─── i18n ───\n\n/**\n * IAM 模块文案 Key 类型\n */\ntype IamMessageKey = keyof typeof messagesZhCN\n\n/**\n * 获取 IAM 模块文案。\n * @param key - 文案 Key\n * @param options - 插值参数与格式化选项\n * @returns 本地化后的文案字符串\n * @remarks 具体参数结构与 core.i18n.createMessageGetter 保持一致。\n * 模块内部使用,不对外导出。\n * @internal\n */\nexport const iamM = core.i18n.createMessageGetter<IamMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n})\n","/**\n * @h-ai/iam — 公共类型定义\n *\n * 包含:\n * - 错误类型(IamError)\n * - 函数接口(IamFunctions)\n * - 初始化配置(IamConfigInput)\n * - 子功能类型 re-export\n * @module iam-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\n\nimport type { ApiKeyOperations } from './authn/apikey/iam-authn-apikey-types.js'\nimport type { AuthnOperations } from './authn/iam-authn-types.js'\nimport type { LdapClientFactory } from './authn/ldap/iam-authn-ldap-strategy.js'\nimport type { AuthzOperations } from './authz/iam-authz-types.js'\nimport type { IamConfig, IamConfigSettingsInput } from './iam-config.js'\nimport type { SessionOperations } from './session/iam-session-types.js'\nimport type { User, UserOperations } from './user/iam-user-types.js'\nimport { core } from '@h-ai/core'\n\n// ─── 错误定义(照 @h-ai/core 范式) ───\n\nconst IamErrorInfo = {\n AUTH_FAILED: '001:401',\n INVALID_CREDENTIALS: '002:401',\n USER_NOT_FOUND: '003:404',\n USER_DISABLED: '004:403',\n USER_LOCKED: '005:403',\n USER_ALREADY_EXISTS: '006:409',\n PASSWORD_EXPIRED: '007:401',\n PASSWORD_POLICY_VIOLATION: '008:400',\n OTP_INVALID: '009:400',\n OTP_EXPIRED: '010:400',\n OTP_RESEND_TOO_FAST: '011:429',\n LOGIN_DISABLED: '012:400',\n REGISTER_DISABLED: '013:403',\n STRATEGY_NOT_SUPPORTED: '014:400',\n APIKEY_INVALID: '015:401',\n APIKEY_EXPIRED: '016:401',\n APIKEY_DISABLED: '017:403',\n APIKEY_NOT_FOUND: '018:404',\n RESET_TOKEN_INVALID: '019:400',\n RESET_TOKEN_EXPIRED: '020:400',\n RESET_TOKEN_MAX_ATTEMPTS: '021:429',\n\n SESSION_NOT_FOUND: '101:401',\n SESSION_EXPIRED: '102:401',\n SESSION_INVALID: '103:401',\n SESSION_CREATE_FAILED: '104:500',\n TOKEN_EXPIRED: '105:401',\n TOKEN_INVALID: '106:401',\n TOKEN_REFRESH_FAILED: '107:401',\n\n PERMISSION_DENIED: '201:403',\n ROLE_NOT_FOUND: '202:404',\n PERMISSION_NOT_FOUND: '203:404',\n ROLE_ALREADY_EXISTS: '204:409',\n PERMISSION_ALREADY_EXISTS: '205:409',\n\n LDAP_CONNECTION_FAILED: '301:500',\n LDAP_BIND_FAILED: '302:401',\n LDAP_SEARCH_FAILED: '303:500',\n\n REPOSITORY_ERROR: '401:500',\n NOT_FOUND: '402:404',\n CONFLICT: '403:409',\n\n FORBIDDEN: '501:403',\n INVALID_ARGUMENT: '502:400',\n\n CONFIG_ERROR: '901:500',\n NOT_INITIALIZED: '910:500',\n INTERNAL_ERROR: '999:500',\n} as const satisfies ErrorInfo\n\nexport const HaiIamError = core.error.buildHaiErrorsDef('iam', IamErrorInfo)\n\n// ─── 初始化配置 ───\n\n/**\n * IAM 初始化配置\n *\n * 包含 Zod 校验的设置字段和运行时依赖。\n * 传入 `iam.init()` 的唯一参数。\n */\nexport interface IamConfigInput extends IamConfigSettingsInput {\n /** LDAP 客户端工厂(启用 LDAP 登录时必填) */\n ldapClientFactory?: LdapClientFactory\n /** LDAP 用户同步开关(默认 true) */\n ldapSyncUser?: boolean\n /**\n * 密码重置令牌回调(可选)\n *\n * 当用户请求密码重置时,框架生成令牌后通过此回调通知业务层,\n * 业务层负责将令牌通过邮件/短信等渠道发送给用户。\n * 若未提供此回调,requestPasswordReset 将仅记录日志不发送通知。\n *\n * @param user - 请求重置的用户信息\n * @param token - 重置令牌(明文,需发送给用户)\n * @param expiresAt - 令牌过期时间\n */\n onPasswordResetRequest?: (user: User, token: string, expiresAt: Date) => Promise<void>\n\n /**\n * OTP 邮件验证码发送回调(可选)\n *\n * 当用户请求 OTP 验证码时,框架生成验证码后通过此回调通知业务层,\n * 业务层负责将验证码通过邮件发送给用户。\n * 若未提供此回调,sendOtp 将返回\"发送方式未配置\"错误。\n *\n * @param email - 目标邮箱\n * @param code - 验证码\n */\n onOtpSendEmail?: (email: string, code: string) => Promise<void>\n\n /**\n * OTP 短信验证码发送回调(可选)\n *\n * 当用户请求 OTP 验证码时,框架生成验证码后通过此回调通知业务层,\n * 业务层负责将验证码通过短信发送给用户。\n * 若未提供此回调,sendOtp 将返回\"发送方式未配置\"错误。\n *\n * @param phone - 目标手机号\n * @param code - 验证码\n */\n onOtpSendSms?: (phone: string, code: string) => Promise<void>\n}\n\n// ─── 函数接口 ───\n\n/**\n * IAM 函数接口\n *\n * 统一聚合所有 IAM 功能。\n */\nexport interface IamFunctions {\n /**\n * 初始化 IAM 服务\n *\n * 幂等操作:已初始化时直接返回成功。\n * 内部按依赖顺序创建 session → authz → authn → user 子功能,\n * 并可选执行种子数据初始化。\n *\n * @param config - IAM 初始化配置(可选 session/password/LDAP 等策略配置)\n * @returns 成功返回 `ok(undefined)`;失败返回含错误码的 `err`\n *\n * @example\n * ```ts\n * const result = await iam.init({ session: { maxAge: 86400 } })\n * if (!result.success) {\n * console.error(result.error.message)\n * }\n * ```\n */\n init: (config: IamConfigInput) => Promise<HaiResult<void>>\n\n /**\n * 关闭 IAM 服务\n *\n * 释放所有内部子功能引用,将模块恢复到未初始化状态。\n * 关闭后访问 `iam.auth` 等属性将返回未初始化错误。\n */\n close: () => Promise<void>\n\n /** 当前配置(未初始化时为 null) */\n readonly config: IamConfig | null\n /** 是否已初始化 */\n readonly isInitialized: boolean\n /** 注册功能是否启用(未初始化或未配置时默认启用) */\n readonly isRegisterEnabled: boolean\n /** 认证操作(登录、登出、令牌验证等) */\n readonly auth: AuthnOperations\n /** 用户管理(注册、查询、更新、密码管理等) */\n readonly user: UserOperations\n /** 授权管理(角色/权限 CRUD、用户角色分配、权限检查) */\n readonly authz: AuthzOperations\n /** 会话管理(创建、查询、验证、删除会话) */\n readonly session: SessionOperations\n /** API Key 管理(创建、列表、吐销、验证),未启用 apikey 登录时返回未初始化代理 */\n readonly apiKey: ApiKeyOperations\n}\n\n// ─── 子功能类型 re-export ───\n\nexport type { ApiKey, ApiKeyOperations, CreateApiKeyOptions, CreateApiKeyResult } from './authn/apikey/iam-authn-apikey-types.js'\nexport type { ApiKeyCredentials, AuthnOperations, AuthStrategy, Credentials, LdapCredentials, OtpCredentials, PasswordCredentials } from './authn/iam-authn-types.js'\nexport type { LdapClientFactory } from './authn/ldap/iam-authn-ldap-strategy.js'\nexport type { AuthzOperations, Permission, PermissionQueryOptions, PermissionType, Role } from './authz/iam-authz-types.js'\nexport type { AuthResult, CreateSessionOptions, Session, SessionData, SessionFieldUpdates, SessionOperations, TokenPair } from './session/iam-session-types.js'\nexport type { AgreementDisplay, ListUsersOptions, RegisterOptions, RegisterResult, StoredUser, UpdateCurrentUserInput, User, UserOperations } from './user/iam-user-types.js'\n","/**\n * @h-ai/iam — API Key 存储实现\n *\n * 基于 @h-ai/reldb 的 API Key CRUD 存储。\n * @module iam-authn-apikey-repository\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations, ReldbCrudFieldDefinition } from '@h-ai/reldb'\nimport type { StoredApiKey } from './iam-authn-apikey-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { BaseReldbCrudRepository, reldb } from '@h-ai/reldb'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\n\n// ─── API Key 存储接口 ───\n\n/**\n * API Key 存储接口\n */\nexport interface ApiKeyRepository {\n /** 插入 API Key */\n insert: (data: StoredApiKey, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n /** 根据 ID 获取(不存在时返回 null) */\n findOneById: (id: string, tx?: DmlWithTxOperations) => Promise<HaiResult<StoredApiKey | null>>\n /** 根据密钥前缀查找(用于快速匹配候选项) */\n findByKeyPrefix: (prefix: string, tx?: DmlWithTxOperations) => Promise<HaiResult<StoredApiKey[]>>\n /** 列出用户所有 API Key */\n findByUserId: (userId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<StoredApiKey[]>>\n /** 统计用户 API Key 数量 */\n countByUserId: (userId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<number>>\n /** 根据 ID 更新(部分字段) */\n updateFields: (id: string, data: Partial<StoredApiKey>, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n /** 根据 ID 删除 */\n removeById: (id: string, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n}\n\n// ─── 字段定义 ───\n\nconst TABLE_NAME = 'hai_iam_api_keys'\n\nconst API_KEY_FIELDS: ReldbCrudFieldDefinition[] = [\n {\n fieldName: 'id',\n columnName: 'id',\n def: { type: 'TEXT' as const, primaryKey: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'userId',\n columnName: 'user_id',\n def: { type: 'TEXT' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'name',\n columnName: 'name',\n def: { type: 'TEXT' as const, notNull: true },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'keyHash',\n columnName: 'key_hash',\n def: { type: 'TEXT' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'keyPrefix',\n columnName: 'key_prefix',\n def: { type: 'TEXT' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'enabled',\n columnName: 'enabled',\n def: { type: 'BOOLEAN' as const, notNull: true, defaultValue: 1 },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'expiresAt',\n columnName: 'expires_at',\n def: { type: 'TIMESTAMP' as const },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'createdAt',\n columnName: 'created_at',\n def: { type: 'TIMESTAMP' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'lastUsedAt',\n columnName: 'last_used_at',\n def: { type: 'TIMESTAMP' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'scopes',\n columnName: 'scopes',\n def: { type: 'JSON' as const },\n select: true,\n create: true,\n update: true,\n },\n]\n\n// ─── 单例管理 ───\n\nlet apiKeyRepoInstance: ApiKeyRepository | null = null\nlet apiKeyRepoDbConfig: unknown = null\n\n/**\n * 重置 API Key 存储单例\n */\nexport function resetApiKeyRepoSingleton(): void {\n apiKeyRepoInstance = null\n apiKeyRepoDbConfig = null\n}\n\n/**\n * 创建基于数据库的 API Key 存储实例\n *\n * @returns API Key 存储接口实现\n */\nexport async function createDbApiKeyRepository(): Promise<ApiKeyRepository> {\n if (apiKeyRepoInstance && apiKeyRepoDbConfig === reldb.config)\n return apiKeyRepoInstance\n\n const repo = new DbApiKeyRepository()\n await repo.count()\n apiKeyRepoInstance = repo\n apiKeyRepoDbConfig = reldb.config\n return repo\n}\n\n// ─── 存储实现 ───\n\nclass DbApiKeyRepository extends BaseReldbCrudRepository<StoredApiKey> implements ApiKeyRepository {\n constructor() {\n super(reldb, {\n table: TABLE_NAME,\n fields: API_KEY_FIELDS,\n })\n }\n\n async insert(data: StoredApiKey, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const result = await this.create(data as unknown as Record<string, unknown>, tx)\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_apikeyCreateFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n }\n\n async findOneById(id: string, tx?: DmlWithTxOperations): Promise<HaiResult<StoredApiKey | null>> {\n const result = await this.findById(id, tx)\n if (!result.success) {\n return this.buildQueryError(result.error)\n }\n return ok(result.data)\n }\n\n async findByKeyPrefix(prefix: string, tx?: DmlWithTxOperations): Promise<HaiResult<StoredApiKey[]>> {\n const result = await this.findAll({ where: 'key_prefix = ?', params: [prefix] }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error)\n }\n return ok(result.data)\n }\n\n async findByUserId(userId: string, tx?: DmlWithTxOperations): Promise<HaiResult<StoredApiKey[]>> {\n const result = await this.findAll({ where: 'user_id = ?', params: [userId] }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error)\n }\n return ok(result.data)\n }\n\n async countByUserId(userId: string, tx?: DmlWithTxOperations): Promise<HaiResult<number>> {\n const result = await this.count({ where: 'user_id = ?', params: [userId] }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error)\n }\n return ok(result.data)\n }\n\n async updateFields(id: string, data: Partial<StoredApiKey>, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const result = await this.updateById(id, data as unknown as Record<string, unknown>, tx)\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_apikeyUpdateFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n }\n\n async removeById(id: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const result = await this.deleteById(id, tx)\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_apikeyDeleteFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n }\n\n private buildQueryError(error: { message: string }): HaiResult<never> {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_apikeyQueryFailed', { params: { message: error.message } }),\n error,\n )\n }\n}\n","/**\n * @h-ai/iam — 用户存储实现\n *\n * 基于 @h-ai/reldb 的用户存储实现。\n * @module iam-user-repository-user\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations, ReldbCrudFieldDefinition, ReldbCrudRepository } from '@h-ai/reldb'\nimport type { StoredUser } from './iam-user-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { BaseReldbCrudRepository, reldb } from '@h-ai/reldb'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n// ─── 用户存储接口 ───\n\n/**\n * 用户存储接口\n */\nexport interface UserRepository extends ReldbCrudRepository<StoredUser> {\n /**\n * 根据用户名获取用户\n */\n findByUsername: (username: string, tx?: DmlWithTxOperations) => Promise<HaiResult<StoredUser | null>>\n\n /**\n * 根据邮箱获取用户\n */\n findByEmail: (email: string, tx?: DmlWithTxOperations) => Promise<HaiResult<StoredUser | null>>\n\n /**\n * 根据手机号获取用户\n */\n findByPhone: (phone: string, tx?: DmlWithTxOperations) => Promise<HaiResult<StoredUser | null>>\n\n /**\n * 根据标识符获取用户(用户名/邮箱/手机号)\n */\n findByIdentifier: (identifier: string, tx?: DmlWithTxOperations) => Promise<HaiResult<StoredUser | null>>\n\n /**\n * 检查用户名是否存在\n */\n existsByUsername: (username: string, tx?: DmlWithTxOperations) => Promise<HaiResult<boolean>>\n\n /**\n * 检查邮箱是否存在\n */\n existsByEmail: (email: string, tx?: DmlWithTxOperations) => Promise<HaiResult<boolean>>\n\n}\n\n// ─── 用户存储实现 ───\n\n/**\n * 用户表名\n */\nconst TABLE_NAME = 'hai_iam_users'\n\n/**\n * 用户字段定义\n */\nconst USER_FIELDS: ReldbCrudFieldDefinition[] = [\n {\n fieldName: 'id',\n columnName: 'id',\n def: { type: 'TEXT' as const, primaryKey: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'username',\n columnName: 'username',\n def: { type: 'TEXT' as const, notNull: true, unique: true },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'email',\n columnName: 'email',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'phone',\n columnName: 'phone',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'displayName',\n columnName: 'display_name',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'avatarUrl',\n columnName: 'avatar_url',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'enabled',\n columnName: 'enabled',\n def: { type: 'BOOLEAN' as const, notNull: true, defaultValue: 1 },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'emailVerified',\n columnName: 'email_verified',\n def: { type: 'BOOLEAN' as const, defaultValue: 0 },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'phoneVerified',\n columnName: 'phone_verified',\n def: { type: 'BOOLEAN' as const, defaultValue: 0 },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'passwordHash',\n columnName: 'password_hash',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'passwordUpdatedAt',\n columnName: 'password_updated_at',\n def: { type: 'TIMESTAMP' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'loginFailedCount',\n columnName: 'login_failed_count',\n def: { type: 'INTEGER' as const, defaultValue: 0 },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'lastLoginFailedAt',\n columnName: 'last_login_failed_at',\n def: { type: 'TIMESTAMP' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'lockedUntil',\n columnName: 'locked_until',\n def: { type: 'TIMESTAMP' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'metadata',\n columnName: 'metadata',\n def: { type: 'JSON' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'createdAt',\n columnName: 'created_at',\n def: { type: 'TIMESTAMP' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'updatedAt',\n columnName: 'updated_at',\n def: { type: 'TIMESTAMP' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n]\n\n/** 用户存储单例缓存(通过 reldb.config 引用比较检测 db 重新初始化) */\nlet userRepoInstance: UserRepository | null = null\nlet userRepoDbConfig: unknown = null\n\n/**\n * 重置用户存储单例\n *\n * 在 iam.close() 时调用,释放对旧 db 实例的引用。\n */\nexport function resetUserRepoSingleton(): void {\n userRepoInstance = null\n userRepoDbConfig = null\n}\n\n/**\n * 创建基于数据库的用户存储实例\n *\n * 单例模式:同一 db 生命周期内重复调用返回缓存实例,\n * db 重新初始化后自动创建新实例。\n *\n * @returns 用户存储接口实现\n */\nexport async function createDbUserRepository(): Promise<UserRepository> {\n if (userRepoInstance && userRepoDbConfig === reldb.config)\n return userRepoInstance\n\n const repo = new DbUserRepository()\n // 确保底层表创建完成(BaseReldbCrudRepository 的表创建是异步的)\n await repo.count()\n userRepoInstance = repo\n userRepoDbConfig = reldb.config\n return repo\n}\n\n/**\n * 基于数据库的用户存储实现\n *\n * 继承 BaseReldbCrudRepository,提供按用户名/邮箱/手机号/标识符的查询能力。\n */\nclass DbUserRepository extends BaseReldbCrudRepository<StoredUser> implements UserRepository {\n constructor() {\n super(reldb, {\n table: TABLE_NAME,\n fields: USER_FIELDS,\n })\n }\n\n /** 根据用户名查找用户 */\n async findByUsername(username: string, tx?: DmlWithTxOperations): Promise<HaiResult<StoredUser | null>> {\n return this.findOneBy('username = ?', [username], tx)\n }\n\n /** 根据邮箱查找用户 */\n async findByEmail(email: string, tx?: DmlWithTxOperations): Promise<HaiResult<StoredUser | null>> {\n return this.findOneBy('email = ?', [email], tx)\n }\n\n /** 根据手机号查找用户 */\n async findByPhone(phone: string, tx?: DmlWithTxOperations): Promise<HaiResult<StoredUser | null>> {\n return this.findOneBy('phone = ?', [phone], tx)\n }\n\n /** 根据标识符查找用户(同时匹配用户名、邮箱、手机号) */\n async findByIdentifier(identifier: string, tx?: DmlWithTxOperations): Promise<HaiResult<StoredUser | null>> {\n return this.findOneBy('username = ? OR email = ? OR phone = ?', [identifier, identifier, identifier], tx)\n }\n\n /** 检查用户名是否已存在 */\n async existsByUsername(username: string, tx?: DmlWithTxOperations): Promise<HaiResult<boolean>> {\n return this.existsBy('username = ?', [username], tx)\n }\n\n /** 检查邮箱是否已存在 */\n async existsByEmail(email: string, tx?: DmlWithTxOperations): Promise<HaiResult<boolean>> {\n return this.existsBy('email = ?', [email], tx)\n }\n\n /**\n * 构建查询错误响应\n *\n * @param error - 原始错误对象\n * @param error.message - 错误消息\n * @param cause - 错误原因\n */\n private buildQueryError(error: { message: string }, cause: unknown): HaiResult<never> {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryUserFailed', { params: { message: error.message } }),\n cause,\n )\n }\n\n /**\n * 按条件检查是否存在\n *\n * @param where - SQL WHERE 条件\n * @param params - 绑定参数\n * @param tx - 可选事务句柄\n */\n private async existsBy(where: string, params: unknown[], tx?: DmlWithTxOperations): Promise<HaiResult<boolean>> {\n const result = await this.exists({ where, params }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error, result.error)\n }\n return ok(result.data)\n }\n\n /**\n * 按条件查找单条记录\n *\n * @param where - SQL WHERE 条件\n * @param params - 绑定参数\n * @param tx - 可选事务句柄\n * @returns 单条用户记录,或 null\n */\n private async findOneBy(where: string, params: unknown[], tx?: DmlWithTxOperations): Promise<HaiResult<StoredUser | null>> {\n const result = await this.findAll({ where, params, limit: 1 }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error, result.error)\n }\n return ok(result.data[0] ?? null)\n }\n}\n","/**\n * @h-ai/iam — 用户工具函数\n *\n * 提供用户实体的转换与去敏处理能力。\n * @module iam-user-utils\n */\n\nimport type { StoredUser, User } from './iam-user-types.js'\n\n/**\n * 将 StoredUser 转换为 User(移除敏感信息)\n *\n * 去除密码哈希、登录失败计数、锁定时间等内部字段,\n * 仅保留前端安全的用户信息。\n *\n * @param storedUser - 包含敏感信息的内部用户数据\n * @returns 去敏后的用户信息\n */\nexport function toUser(storedUser: StoredUser): User {\n return {\n id: storedUser.id,\n username: storedUser.username,\n email: storedUser.email,\n phone: storedUser.phone,\n displayName: storedUser.displayName,\n avatarUrl: storedUser.avatarUrl,\n enabled: storedUser.enabled,\n emailVerified: storedUser.emailVerified,\n phoneVerified: storedUser.phoneVerified,\n createdAt: storedUser.createdAt,\n updatedAt: storedUser.updatedAt,\n metadata: storedUser.metadata,\n }\n}\n","/**\n * @h-ai/iam — 认证通用工具\n *\n * 提供认证策略中的通用校验与工具函数。\n * @module iam-authn-utils\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { UserRepository } from '../user/iam-user-repository-user.js'\nimport type { StoredUser } from '../user/iam-user-types.js'\nimport type { Credentials } from './iam-authn-types.js'\nimport { err, ok } from '@h-ai/core'\n\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n/**\n * 校验凭证类型并进行类型收窄\n *\n * 确保传入的凭证对象的 type 字段与预期匹配,\n * 匹配成功后通过 TypeScript 类型收窄返回具体凭证类型。\n *\n * @param credentials - 统一凭证对象\n * @param type - 预期的凭证类型('password' | 'otp' | 'ldap')\n * @returns 类型匹配返回收窄后的凭证;不匹配返回 INVALID_CREDENTIALS 错误\n */\nexport function ensureCredentialType<TType extends Credentials['type']>(\n credentials: Credentials,\n type: TType,\n): HaiResult<Extract<Credentials, { type: TType }>> {\n if (credentials.type !== type) {\n return err(\n HaiIamError.INVALID_CREDENTIALS,\n iamM('iam_credentialTypeMismatch'),\n )\n }\n return ok(credentials as Extract<Credentials, { type: TType }>)\n}\n\n/**\n * 登录失败策略\n */\nexport interface LoginFailurePolicy {\n /** 最大登录失败次数 */\n maxLoginAttempts: number\n /** 锁定时长(秒) */\n lockoutDuration: number\n}\n\n/**\n * 判断账户是否被锁定\n *\n * @param user - 内部用户数据(含 lockedUntil 字段)\n * @returns 锁定中返回 true;未设置或已到期返回 false\n */\nexport function isAccountLocked(user: StoredUser): boolean {\n if (!user.lockedUntil) {\n return false\n }\n return new Date() < user.lockedUntil\n}\n\n/**\n * 记录登录失败并根据策略锁定账户\n *\n * 累加失败计数,达到阈值时设置锁定截止时间。\n *\n * @param userRepository - 用户存储实例\n * @param user - 当前用户数据\n * @param policy - 登录失败策略(最大次数和锁定时长)\n */\nexport async function recordLoginFailure(\n userRepository: UserRepository,\n user: StoredUser,\n policy: LoginFailurePolicy,\n): Promise<void> {\n const failedCount = (user.loginFailedCount || 0) + 1\n const updateData: Partial<StoredUser> = {\n loginFailedCount: failedCount,\n lastLoginFailedAt: new Date(),\n }\n\n if (failedCount >= policy.maxLoginAttempts) {\n updateData.lockedUntil = new Date(Date.now() + policy.lockoutDuration * 1000)\n }\n\n await userRepository.updateById(user.id, updateData)\n}\n\n/**\n * 重置登录失败计数\n *\n * 登录成功后调用,将失败计数、最后失败时间和锁定截止时间清零。\n * 若用户没有失败记录则跳过更新。\n *\n * @param userRepository - 用户存储实例\n * @param user - 当前用户数据\n */\nexport async function resetLoginFailures(\n userRepository: UserRepository,\n user: StoredUser,\n): Promise<void> {\n if (user.loginFailedCount && user.loginFailedCount > 0) {\n await userRepository.updateById(user.id, {\n loginFailedCount: 0,\n lastLoginFailedAt: undefined,\n lockedUntil: undefined,\n })\n }\n}\n","/**\n * @h-ai/iam — API Key 认证策略\n *\n * 基于 API Key 的无状态认证方式,适用于服务间调用、CI/CD 等场景。\n * @module iam-authn-apikey-strategy\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ApiKeyConfig } from '../../iam-config.js'\nimport type { UserRepository } from '../../user/iam-user-repository-user.js'\nimport type { User } from '../../user/iam-user-types.js'\nimport type { AuthStrategy, Credentials } from '../iam-authn-types.js'\nimport type { ApiKeyRepository } from './iam-authn-apikey-repository.js'\nimport type { ApiKey, ApiKeyOperations, CreateApiKeyOptions, CreateApiKeyResult } from './iam-authn-apikey-types.js'\nimport { randomBytes } from 'node:crypto'\nimport { core, err, ok } from '@h-ai/core'\nimport { crypto as haiCrypto } from '@h-ai/crypto'\n\nimport { ApiKeyConfigSchema } from '../../iam-config.js'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\nimport { toUser } from '../../user/iam-user-utils.js'\nimport { ensureCredentialType } from '../iam-authn-utils.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'apikey-strategy' })\n\n/**\n * API Key 策略配置\n */\nexport interface ApiKeyStrategyConfig {\n /** API Key 配置 */\n apikeyConfig?: ApiKeyConfig\n /** 用户存储 */\n userRepository: UserRepository\n /** API Key 存储 */\n apiKeyRepository: ApiKeyRepository\n}\n\n/**\n * API Key 策略工厂返回值\n */\nexport interface ApiKeyStrategyResult {\n /** 认证策略(用于通用登录流程) */\n strategy: AuthStrategy\n /** API Key 管理操作(用于 CRUD) */\n apiKeyFunctions: ApiKeyOperations\n}\n\n/**\n * API Key 的前缀长度(用于存储和快速匹配)\n *\n * 例如密钥为 'hai_abc123def456...' 时,前缀为 'hai_abc123de'\n */\nconst KEY_PREFIX_LENGTH = 12\n\n/**\n * 生成随机 API Key\n *\n * 格式:{prefix}{randomHex},总长度约 48 字符\n */\nfunction generateRawKey(prefix: string): string {\n const hex = randomBytes(32).toString('hex')\n return `${prefix}${hex}`\n}\n\n/**\n * 从明文 API Key 中提取前缀(用于数据库索引匹配)\n */\nfunction extractKeyPrefix(rawKey: string): string {\n return rawKey.slice(0, KEY_PREFIX_LENGTH)\n}\n\n/**\n * 将 StoredApiKey 转换为对外展示的 ApiKey(去除 keyHash)\n */\nfunction toApiKey(stored: { id: string, userId: string, name: string, keyPrefix: string, enabled: boolean, expiresAt: Date | null, createdAt: Date, lastUsedAt: Date | null, scopes: string[] }): ApiKey {\n return {\n id: stored.id,\n userId: stored.userId,\n name: stored.name,\n keyPrefix: stored.keyPrefix,\n enabled: stored.enabled,\n expiresAt: stored.expiresAt,\n createdAt: stored.createdAt,\n lastUsedAt: stored.lastUsedAt,\n scopes: stored.scopes,\n }\n}\n\n/**\n * 创建 API Key 认证策略及管理操作\n */\nexport function createApiKeyStrategy(config: ApiKeyStrategyConfig): ApiKeyStrategyResult {\n const apikeyConfig = config.apikeyConfig\n ? ApiKeyConfigSchema.parse(config.apikeyConfig)\n : ApiKeyConfigSchema.parse({})\n\n const { userRepository, apiKeyRepository } = config\n const passwordOps = haiCrypto.password\n\n /**\n * 内部:验证明文 API Key 并返回 ApiKey 实体\n */\n async function verifyRawKey(rawKey: string): Promise<HaiResult<ApiKey>> {\n const prefix = extractKeyPrefix(rawKey)\n\n // 根据前缀缩小候选范围\n const candidatesResult = await apiKeyRepository.findByKeyPrefix(prefix)\n if (!candidatesResult.success) {\n return candidatesResult as HaiResult<ApiKey>\n }\n\n // 遍历候选项验证哈希\n for (const candidate of candidatesResult.data) {\n const verifyResult = passwordOps.verify(rawKey, candidate.keyHash)\n if (!verifyResult.success)\n continue\n if (!verifyResult.data)\n continue\n\n // 检查是否启用\n if (!candidate.enabled) {\n return err(HaiIamError.APIKEY_DISABLED, iamM('iam_apikeyDisabled'))\n }\n\n // 检查是否过期\n if (candidate.expiresAt && new Date() > candidate.expiresAt) {\n return err(HaiIamError.APIKEY_EXPIRED, iamM('iam_apikeyExpired'))\n }\n\n // 更新最后使用时间(异步,不阻塞认证)\n apiKeyRepository.updateFields(candidate.id, { lastUsedAt: new Date() }).catch(() => {\n logger.warn('Failed to update API Key lastUsedAt', { keyId: candidate.id })\n })\n\n return ok(toApiKey(candidate))\n }\n\n return err(HaiIamError.APIKEY_INVALID, iamM('iam_apikeyInvalid'))\n }\n\n // ─── AuthStrategy 实现 ───\n\n const strategy: AuthStrategy = {\n type: 'apikey',\n name: 'apikey-strategy',\n\n async authenticate(credentials: Credentials): Promise<HaiResult<User>> {\n const credentialResult = ensureCredentialType(credentials, 'apikey')\n if (!credentialResult.success) {\n return credentialResult as HaiResult<User>\n }\n\n const { key } = credentialResult.data\n\n // 验证 API Key\n const verifyResult = await verifyRawKey(key)\n if (!verifyResult.success) {\n return verifyResult as HaiResult<User>\n }\n\n const apiKey = verifyResult.data\n\n // 通过用户 ID 查找关联用户\n const userResult = await userRepository.findById(apiKey.userId)\n if (!userResult.success) {\n return err(HaiIamError.REPOSITORY_ERROR, userResult.error.message, userResult.error)\n }\n if (!userResult.data) {\n return err(HaiIamError.USER_NOT_FOUND, iamM('iam_userNotExist'))\n }\n if (!userResult.data.enabled) {\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n }\n\n logger.info('API Key authentication succeeded', { userId: userResult.data.id, keyId: apiKey.id })\n return ok(toUser(userResult.data))\n },\n }\n\n // ─── API Key 管理操作 ───\n\n const apiKeyFunctions: ApiKeyOperations = {\n async createApiKey(userId: string, options: CreateApiKeyOptions): Promise<HaiResult<CreateApiKeyResult>> {\n try {\n // 检查用户 API Key 数量限制\n const countResult = await apiKeyRepository.countByUserId(userId)\n if (!countResult.success)\n return countResult as HaiResult<CreateApiKeyResult>\n\n if (countResult.data >= apikeyConfig.maxKeysPerUser) {\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_apikeyMaxKeysReached', { params: { max: apikeyConfig.maxKeysPerUser } }))\n }\n\n // 生成明文密钥和哈希\n const rawKey = generateRawKey(apikeyConfig.prefix)\n const hashResult = passwordOps.hash(rawKey)\n if (!hashResult.success) {\n return err(HaiIamError.INTERNAL_ERROR, hashResult.error.message)\n }\n\n // 计算过期时间\n const expirationDays = options.expirationDays ?? apikeyConfig.defaultExpirationDays\n const expiresAt = expirationDays > 0\n ? new Date(Date.now() + expirationDays * 86400000)\n : null\n\n const id = core.id.generate()\n const now = new Date()\n\n const storedApiKey = {\n id,\n userId,\n name: options.name,\n keyHash: hashResult.data,\n keyPrefix: extractKeyPrefix(rawKey),\n enabled: true,\n expiresAt,\n createdAt: now,\n lastUsedAt: null,\n scopes: options.scopes ?? [],\n }\n\n const insertResult = await apiKeyRepository.insert(storedApiKey)\n if (!insertResult.success)\n return insertResult as HaiResult<CreateApiKeyResult>\n\n logger.info('API Key created', { userId, keyId: id, name: options.name })\n return ok({ apiKey: toApiKey(storedApiKey), rawKey })\n }\n catch (error) {\n return err(HaiIamError.INTERNAL_ERROR, iamM('iam_apikeyCreateFailed', { params: { message: String(error) } }), error)\n }\n },\n\n async listApiKeys(userId: string): Promise<HaiResult<ApiKey[]>> {\n const result = await apiKeyRepository.findByUserId(userId)\n if (!result.success)\n return result as HaiResult<ApiKey[]>\n return ok(result.data.map(toApiKey))\n },\n\n async getApiKey(keyId: string): Promise<HaiResult<ApiKey | null>> {\n const result = await apiKeyRepository.findOneById(keyId)\n if (!result.success)\n return result as HaiResult<ApiKey | null>\n return ok(result.data ? toApiKey(result.data) : null)\n },\n\n async revokeApiKey(keyId: string): Promise<HaiResult<void>> {\n const result = await apiKeyRepository.removeById(keyId)\n if (!result.success)\n return result\n logger.info('API Key revoked', { keyId })\n return ok(undefined)\n },\n\n async verifyApiKey(rawKey: string): Promise<HaiResult<ApiKey>> {\n return verifyRawKey(rawKey)\n },\n }\n\n return { strategy, apiKeyFunctions }\n}\n","/**\n * @h-ai/iam — LDAP 认证策略\n *\n * LDAP 目录认证方式\n * @module iam-authn-ldap-strategy\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { LdapConfig } from '../../iam-config.js'\nimport type { UserRepository } from '../../user/iam-user-repository-user.js'\nimport type { StoredUser, User } from '../../user/iam-user-types.js'\nimport type { AuthStrategy, Credentials } from '../iam-authn-types.js'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\nimport { toUser } from '../../user/iam-user-utils.js'\nimport { ensureCredentialType, isAccountLocked, recordLoginFailure, resetLoginFailures } from '../iam-authn-utils.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'ldap-strategy' })\n\n/**\n * 转义 LDAP 搜索过滤器中的特殊字符(RFC 4515)\n *\n * 防止 LDAP 注入攻击:将用户输入中的特殊字符转义为 `\\xx` 形式。\n * 需转义字符:`*`、`(`、`)`、`\\`、NUL(`\\0`)。\n *\n * @param value - 用户输入值\n * @returns 转义后的安全字符串\n */\nexport function escapeLdapFilterValue(value: string): string {\n return value.replace(/[\\\\*()/\\0]/g, (ch) => {\n const hex = ch.charCodeAt(0).toString(16).padStart(2, '0')\n return `\\\\${hex}`\n })\n}\n\n/**\n * LDAP 客户端接口\n */\nexport interface LdapClient {\n /**\n * 绑定(认证)\n */\n bind: (dn: string, password: string) => Promise<HaiResult<void>>\n\n /**\n * 搜索用户\n */\n search: (base: string, filter: string, attributes: string[]) => Promise<HaiResult<LdapSearchEntry[]>>\n\n /**\n * 解除绑定\n */\n unbind: () => Promise<HaiResult<void>>\n}\n\n/**\n * LDAP 搜索结果条目\n */\nexport interface LdapSearchEntry {\n /** DN */\n dn: string\n /** 属性 */\n attributes: Record<string, string | string[]>\n}\n\n/**\n * LDAP 客户端工厂\n */\nexport type LdapClientFactory = (config: LdapConfig) => Promise<HaiResult<LdapClient>>\n\n/**\n * LDAP 认证策略配置\n */\nexport interface LdapStrategyConfig {\n /** LDAP 配置 */\n ldapConfig: LdapConfig\n /** 用户存储 */\n userRepository: UserRepository\n /** LDAP 客户端工厂 */\n ldapClientFactory: LdapClientFactory\n /** 是否同步用户到本地数据库 */\n syncUser?: boolean\n /** 最大登录失败次数(默认 5) */\n maxLoginAttempts?: number\n /** 锁定时间(秒,默认 900 = 15分钟) */\n lockoutDuration?: number\n /**\n * 用户自动注册后的回调\n *\n * LDAP 同步创建本地新用户后调用,用于分配默认角色等后处理操作。\n *\n * @param userId - 新创建的用户 ID\n */\n onUserAutoRegistered?: (userId: string) => Promise<void>\n}\n\n/**\n * 创建 LDAP 认证策略\n *\n * 通过 LDAP 目录服务进行用户认证。\n * 支持用户同步到本地数据库、登录失败锁定等能力。\n *\n * @param config - LDAP 策略配置(LDAP 配置、用户存储、客户端工厂等)\n * @returns 认证策略实例\n */\nexport function createLdapStrategy(config: LdapStrategyConfig): AuthStrategy {\n const {\n ldapConfig,\n userRepository,\n ldapClientFactory,\n syncUser = true,\n maxLoginAttempts = 5,\n lockoutDuration = 900,\n } = config\n\n /**\n * 获取 LDAP 搜索结果中的属性值\n *\n * 支持单值和多值属性,多值时返回第一个。\n *\n * @param entry - LDAP 搜索结果条目\n * @param attr - 属性名\n * @returns 属性值,或 undefined\n */\n function getAttributeValue(entry: LdapSearchEntry, attr: string): string | undefined {\n const value = entry.attributes[attr]\n if (Array.isArray(value)) {\n return value[0]\n }\n return value\n }\n\n /**\n * 构建 LDAP 用户信息对象\n *\n * 用于未开启用户同步时,直接返回 LDAP 目录中的用户信息。\n *\n * @param entry - LDAP 搜索结果条目\n * @param ldapUsername - 用户名\n * @param ldapEmail - 邮箱(可选)\n * @param ldapDisplayName - 显示名称(可选)\n * @returns User 对象(ID 为 LDAP DN)\n */\n function buildLdapUser(entry: LdapSearchEntry, ldapUsername: string, ldapEmail?: string, ldapDisplayName?: string): User {\n const now = new Date()\n return {\n id: entry.dn,\n username: ldapUsername,\n email: ldapEmail,\n displayName: ldapDisplayName,\n enabled: true,\n createdAt: now,\n updatedAt: now,\n metadata: {\n ldapDn: entry.dn,\n authSource: 'ldap',\n },\n }\n }\n\n return {\n type: 'ldap',\n name: 'ldap-strategy',\n\n async authenticate(credentials: Credentials): Promise<HaiResult<User>> {\n // 类型检查\n const credentialResult = ensureCredentialType(credentials, 'ldap')\n if (!credentialResult.success) {\n return credentialResult as HaiResult<User>\n }\n\n const { username, password } = credentialResult.data\n\n // 创建 LDAP 客户端\n const clientResult = await ldapClientFactory(ldapConfig)\n if (!clientResult.success) {\n return err(\n HaiIamError.LDAP_CONNECTION_FAILED,\n iamM('iam_ldapConnectionFailed'),\n clientResult.error,\n )\n }\n\n const client = clientResult.data\n\n try {\n // 先用管理员账号绑定\n const adminBindResult = await client.bind(ldapConfig.bindDn, ldapConfig.bindPassword)\n if (!adminBindResult.success) {\n return err(\n HaiIamError.LDAP_BIND_FAILED,\n iamM('iam_ldapAdminBindFailed'),\n adminBindResult.error,\n )\n }\n\n // 搜索用户(转义用户输入,防止 LDAP 注入)\n const searchFilter = ldapConfig.searchFilter.replace('{{username}}', escapeLdapFilterValue(username))\n const searchResult = await client.search(\n ldapConfig.searchBase,\n searchFilter,\n [ldapConfig.usernameAttribute, ldapConfig.emailAttribute, ldapConfig.displayNameAttribute],\n )\n\n if (!searchResult.success) {\n return err(\n HaiIamError.LDAP_SEARCH_FAILED,\n iamM('iam_ldapSearchFailed'),\n searchResult.error,\n )\n }\n\n const entries = searchResult.data\n if (entries.length === 0) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n const entry = entries[0]\n\n // 提取用户信息\n const ldapUsername = getAttributeValue(entry, ldapConfig.usernameAttribute) || username\n const ldapEmail = getAttributeValue(entry, ldapConfig.emailAttribute)\n const ldapDisplayName = getAttributeValue(entry, ldapConfig.displayNameAttribute)\n\n // 查找本地用户(用于状态判断与失败计数)\n const localUserResult = await userRepository.findByUsername(ldapUsername)\n if (!localUserResult.success) {\n return localUserResult as HaiResult<User>\n }\n\n let storedUser = localUserResult.data as StoredUser | null\n\n if (storedUser) {\n if (!storedUser.enabled) {\n return err(\n HaiIamError.USER_DISABLED,\n iamM('iam_accountDisabled'),\n )\n }\n\n if (isAccountLocked(storedUser)) {\n return err(\n HaiIamError.USER_LOCKED,\n iamM('iam_accountLocked'),\n )\n }\n }\n\n // 用用户的 DN 进行绑定验证密码\n const userBindResult = await client.bind(entry.dn, password)\n if (!userBindResult.success) {\n if (storedUser) {\n await recordLoginFailure(userRepository, storedUser, { maxLoginAttempts, lockoutDuration })\n }\n logger.warn('LDAP authentication failed', { username })\n return err(\n HaiIamError.INVALID_CREDENTIALS,\n iamM('iam_passwordWrong'),\n )\n }\n\n if (!storedUser && syncUser) {\n // 创建本地用户\n const createResult = await userRepository.create({\n username: ldapUsername,\n email: ldapEmail,\n displayName: ldapDisplayName,\n enabled: true,\n emailVerified: !!ldapEmail,\n metadata: {\n ldapDn: entry.dn,\n authSource: 'ldap',\n },\n })\n if (!createResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createUserFailed', { params: { message: createResult.error.message } }),\n createResult.error,\n )\n }\n\n const createdResult = await userRepository.findByUsername(ldapUsername)\n if (!createdResult.success) {\n return createdResult as HaiResult<User>\n }\n storedUser = createdResult.data\n\n // LDAP 新用户同步后回调(分配默认角色等)\n if (storedUser && config.onUserAutoRegistered) {\n try {\n await config.onUserAutoRegistered(storedUser.id)\n }\n catch (callbackError) {\n logger.warn('onUserAutoRegistered callback failed', { userId: storedUser?.id, error: callbackError })\n }\n }\n }\n else if (storedUser && syncUser) {\n // 更新本地用户信息\n const updateResult = await userRepository.updateById(storedUser.id, {\n email: ldapEmail || storedUser.email,\n displayName: ldapDisplayName || storedUser.displayName,\n metadata: {\n ...storedUser.metadata,\n ldapDn: entry.dn,\n authSource: 'ldap',\n },\n })\n if (updateResult.success) {\n const refreshed = await userRepository.findByUsername(ldapUsername)\n if (refreshed.success) {\n storedUser = refreshed.data ?? storedUser\n }\n }\n }\n\n if (!storedUser) {\n // 如果不同步用户,直接返回 LDAP 用户信息\n const ldapUser = buildLdapUser(entry, ldapUsername, ldapEmail, ldapDisplayName)\n return ok(ldapUser)\n }\n\n await resetLoginFailures(userRepository, storedUser)\n logger.info('LDAP authentication succeeded', { userId: storedUser.id })\n\n return ok(toUser(storedUser))\n }\n finally {\n // 确保解除绑定\n await client.unbind()\n }\n },\n }\n}\n","/**\n * @h-ai/iam — OTP 存储实现\n *\n * 基于 @h-ai/cache 的 OTP 存储实现。\n * @module iam-authn-otp-repository-otp\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport { cache } from '@h-ai/cache'\nimport { err, ok } from '@h-ai/core'\n\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\n\n// ─── OTP 存储接口与类型 ───\n\n/**\n * OTP 记录\n */\nexport interface OtpRecord {\n /** 标识符(邮箱/手机号) */\n identifier: string\n /** 验证码 */\n code: string\n /** 过期时间 */\n expiresAt: Date\n /** 尝试次数 */\n attempts: number\n /** 创建时间 */\n createdAt: Date\n}\n\n/**\n * OTP 存储接口\n */\nexport interface OtpRepository {\n /**\n * 存储验证码\n */\n saveOtp: (identifier: string, code: string, expiresIn: number) => Promise<HaiResult<void>>\n\n /**\n * 获取验证码\n */\n fetchOtp: (identifier: string) => Promise<HaiResult<OtpRecord | null>>\n\n /**\n * 增加尝试次数\n */\n incrementOtpAttempts: (identifier: string) => Promise<HaiResult<number>>\n\n /**\n * 删除验证码\n */\n removeOtp: (identifier: string) => Promise<HaiResult<void>>\n}\n\n// ─── 缓存键构建 ───\n\n/** OTP 缓存键前缀 */\nconst OTP_KEY_PREFIX = 'hai:iam:otp:'\n\n/**\n * 构建 OTP 缓存 key\n *\n * @param identifier - 标识符(邮箱/手机号)\n * @returns 格式:`iam:otp:{identifier}`\n */\nfunction buildOtpKey(identifier: string): string {\n return `${OTP_KEY_PREFIX}${identifier}`\n}\n\n/**\n * 修复从缓存反序列化后的日期字段\n *\n * 缓存存储后日期可能为字符串,需要重新转为 Date 对象。\n */\nfunction restoreOtpDates(record: OtpRecord): OtpRecord {\n return {\n ...record,\n expiresAt: record.expiresAt instanceof Date ? record.expiresAt : new Date(record.expiresAt),\n createdAt: record.createdAt instanceof Date ? record.createdAt : new Date(record.createdAt),\n }\n}\n\n// ─── 缓存实现 ───\n\n/** OTP 存储单例缓存 */\nlet otpRepoInstance: OtpRepository | null = null\n\n/**\n * 重置 OTP 存储单例\n *\n * 在 iam.close() 时调用,释放对旧 cache 实例的引用。\n */\nexport function resetOtpRepoSingleton(): void {\n otpRepoInstance = null\n}\n\n/**\n * 创建基于缓存的 OTP 存储实例\n *\n * 单例模式:重复调用返回缓存实例。\n *\n * @returns OTP 存储接口实现\n */\nexport function createCacheOtpRepository(): OtpRepository {\n if (otpRepoInstance)\n return otpRepoInstance\n\n const repo: OtpRepository = {\n async saveOtp(identifier, code, expiresIn): Promise<HaiResult<void>> {\n const now = Date.now()\n const record: OtpRecord = {\n identifier,\n code,\n expiresAt: new Date(now + expiresIn * 1000),\n attempts: 0,\n createdAt: new Date(now),\n }\n\n // 直接 set 覆盖(cache 天然支持 upsert 语义)\n const result = await cache.kv.set(buildOtpKey(identifier), record, { ex: expiresIn })\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveOtpFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(undefined)\n },\n\n async fetchOtp(identifier): Promise<HaiResult<OtpRecord | null>> {\n const result = await cache.kv.get<OtpRecord>(buildOtpKey(identifier))\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryOtpFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n if (!result.data) {\n return ok(null)\n }\n\n return ok(restoreOtpDates(result.data))\n },\n\n async incrementOtpAttempts(identifier): Promise<HaiResult<number>> {\n const otpKey = buildOtpKey(identifier)\n const current = await cache.kv.get<OtpRecord>(otpKey)\n if (!current.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryOtpFailed', { params: { message: current.error.message } }),\n current.error,\n )\n }\n\n if (!current.data) {\n return ok(0)\n }\n\n const record = restoreOtpDates(current.data)\n const nextAttempts = record.attempts + 1\n\n // 获取剩余 TTL,保持原有过期时间\n const ttlResult = await cache.kv.ttl(otpKey)\n const ttl = ttlResult.success && ttlResult.data > 0 ? ttlResult.data : 1\n\n const updateResult = await cache.kv.set(otpKey, { ...record, attempts: nextAttempts }, { ex: ttl })\n if (!updateResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_updateOtpAttemptsFailed', { params: { message: updateResult.error.message } }),\n updateResult.error,\n )\n }\n\n return ok(nextAttempts)\n },\n\n async removeOtp(identifier): Promise<HaiResult<void>> {\n const result = await cache.kv.del(buildOtpKey(identifier))\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_deleteOtpFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n },\n }\n\n otpRepoInstance = repo\n return repo\n}\n","/**\n * @h-ai/iam — OTP 认证策略\n *\n * 邮箱/短信 + 验证码的认证方式\n * @module iam-authn-otp-strategy\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { OtpConfig, RegisterConfig } from '../../iam-config.js'\nimport type { UserRepository } from '../../user/iam-user-repository-user.js'\nimport type { StoredUser, User } from '../../user/iam-user-types.js'\nimport type { AuthStrategy, Credentials } from '../iam-authn-types.js'\nimport type { OtpRepository } from './iam-authn-otp-repository-otp.js'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { OtpConfigSchema } from '../../iam-config.js'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\nimport { toUser } from '../../user/iam-user-utils.js'\nimport {\n ensureCredentialType,\n isAccountLocked,\n recordLoginFailure,\n resetLoginFailures,\n} from '../iam-authn-utils.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'otp-strategy' })\n\n/**\n * OTP 认证策略配置\n */\nexport interface OtpStrategyConfig {\n /** OTP 配置 */\n otpConfig?: OtpConfig\n /** 用户存储 */\n userRepository: UserRepository\n /** OTP 存储 */\n otpRepository: OtpRepository\n /** 是否允许自动注册新用户 */\n autoRegister?: boolean\n /** 注册配置(用于自动注册场景) */\n registerConfig?: RegisterConfig\n /** 最大登录失败次数(默认 5) */\n maxLoginAttempts?: number\n /** 锁定时间(秒,默认 900 = 15分钟) */\n lockoutDuration?: number\n /**\n * 用户自动注册后的回调\n *\n * 用于分配默认角色等后处理操作。\n *\n * @param userId - 新创建的用户 ID\n */\n onUserAutoRegistered?: (userId: string) => Promise<void>\n /** OTP 邮件发送回调(由业务层注入) */\n onOtpSendEmail?: (email: string, code: string) => Promise<void>\n /** OTP 短信发送回调(由业务层注入) */\n onOtpSendSms?: (phone: string, code: string) => Promise<void>\n}\n\n/**\n * 生成随机数字验证码\n *\n * 使用 `crypto.getRandomValues` 生成加密安全的随机数字串。\n *\n * @param length - 验证码长度\n * @returns 纯数字验证码字符串\n */\nfunction generateOtpCode(length: number): string {\n let code = ''\n // 使用拒绝采样消除模偏(256 % 10 = 6,前 250 个值均匀映射到 0-9)\n const threshold = 250\n while (code.length < length) {\n const randomValues = new Uint8Array(length - code.length)\n crypto.getRandomValues(randomValues)\n for (const byte of randomValues) {\n if (byte < threshold && code.length < length) {\n code += String(byte % 10)\n }\n }\n }\n return code\n}\n\n/**\n * 判断标识符类型\n *\n * 通过简单规则推断标识符是邮箱、手机号还是未知类型。\n *\n * @param identifier - 用户标识符(邮箱/手机号)\n * @returns 标识符类型:'email' | 'phone' | 'unknown'\n */\nfunction identifierType(identifier: string): 'email' | 'phone' | 'unknown' {\n // 简单邮箱检测\n if (identifier.includes('@')) {\n return 'email'\n }\n // 简单手机号检测(以数字开头,长度大于 8)\n if (/^\\+?\\d{8,}$/.test(identifier.replace(/[\\s-]/g, ''))) {\n return 'phone'\n }\n return 'unknown'\n}\n\n/**\n * OTP 策略工厂返回值\n */\nexport interface OtpStrategyResult {\n /** 认证策略(用于通用登录流程) */\n strategy: AuthStrategy\n /** 发起认证挑战(发送验证码) */\n challenge: (identifier: string) => Promise<HaiResult<{ expiresAt: Date }>>\n}\n\n/**\n * 创建 OTP 认证策略\n *\n * 支持验证码登录、自动注册新用户、发送频率限制、登录失败锁定等能力。\n *\n * @param config - OTP 策略配置(包含用户存储、OTP 存储、自动注册开关等)\n * @returns OTP 策略结果,包含认证策略和 challenge 方法\n */\nexport function createOtpStrategy(config: OtpStrategyConfig): OtpStrategyResult {\n const otpConfig = config.otpConfig\n ? OtpConfigSchema.parse(config.otpConfig)\n : OtpConfigSchema.parse({})\n const maxLoginAttempts = config.maxLoginAttempts ?? 5\n const lockoutDuration = config.lockoutDuration ?? 900\n const registerConfig = config.registerConfig\n const allowAutoRegister = registerConfig?.enabled ?? config.autoRegister ?? false\n const defaultEnabled = registerConfig?.defaultEnabled ?? true\n\n /**\n * 构建挑战响应结果\n *\n * @param expiresAt - 验证码过期时间\n * @returns 包含过期时间的结果对象\n */\n function buildChallengeResult(expiresAt: Date): { expiresAt: Date } {\n return { expiresAt }\n }\n\n const strategy: AuthStrategy = {\n type: 'otp',\n name: 'otp-strategy',\n\n async authenticate(credentials: Credentials): Promise<HaiResult<User>> {\n // 类型检查\n const credentialResult = ensureCredentialType(credentials, 'otp')\n if (!credentialResult.success) {\n return credentialResult as HaiResult<User>\n }\n\n const { identifier, code } = credentialResult.data\n\n // 预先加载用户用于账户状态判断\n const userResult = await config.userRepository.findByIdentifier(identifier)\n if (!userResult.success) {\n return userResult as HaiResult<User>\n }\n\n let storedUser = userResult.data as StoredUser | null\n\n if (storedUser) {\n if (!storedUser.enabled) {\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n }\n\n if (isAccountLocked(storedUser)) {\n return err(HaiIamError.USER_LOCKED, iamM('iam_accountLocked'))\n }\n }\n\n // 获取存储的验证码\n const storedOtpResult = await config.otpRepository.fetchOtp(identifier)\n if (!storedOtpResult.success) {\n return storedOtpResult as HaiResult<User>\n }\n\n const storedOtp = storedOtpResult.data\n if (!storedOtp) {\n return err(HaiIamError.OTP_INVALID, iamM('iam_otpNotExistOrExpired'))\n }\n\n // 检查尝试次数\n if (storedOtp.attempts >= otpConfig.maxAttempts) {\n await config.otpRepository.removeOtp(identifier)\n if (storedUser) {\n await recordLoginFailure(config.userRepository, storedUser, { maxLoginAttempts, lockoutDuration })\n }\n return err(HaiIamError.OTP_INVALID, iamM('iam_otpInvalid'))\n }\n\n // 验证验证码(时间安全比较,防止时序攻击)\n if (!core.string.constantTimeEqual(storedOtp.code, code)) {\n await config.otpRepository.incrementOtpAttempts(identifier)\n if (storedUser) {\n await recordLoginFailure(config.userRepository, storedUser, { maxLoginAttempts, lockoutDuration })\n }\n return err(HaiIamError.OTP_INVALID, iamM('iam_otpWrong'))\n }\n\n // 验证成功,删除验证码\n await config.otpRepository.removeOtp(identifier)\n\n // 如果用户不存在且允许自动注册\n if (!storedUser && allowAutoRegister) {\n const type = identifierType(identifier)\n const createResult = await config.userRepository.create({\n username: identifier,\n email: type === 'email' ? identifier : undefined,\n phone: type === 'phone' ? identifier : undefined,\n enabled: defaultEnabled,\n emailVerified: type === 'email',\n phoneVerified: type === 'phone',\n })\n if (!createResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createUserFailed', { params: { message: createResult.error.message } }),\n createResult.error,\n )\n }\n\n const createdResult = await config.userRepository.findByIdentifier(identifier)\n if (!createdResult.success) {\n return createdResult as HaiResult<User>\n }\n storedUser = createdResult.data\n\n // 自动注册后回调(分配默认角色等)\n if (storedUser && config.onUserAutoRegistered) {\n try {\n await config.onUserAutoRegistered(storedUser.id)\n }\n catch (callbackError) {\n logger.warn('onUserAutoRegistered callback failed', { userId: storedUser.id, error: callbackError })\n }\n }\n }\n\n if (!storedUser) {\n return err(HaiIamError.USER_NOT_FOUND, iamM('iam_userNotExist'))\n }\n\n // 登录成功,重置失败计数\n await resetLoginFailures(config.userRepository, storedUser)\n logger.info('OTP authentication succeeded', { userId: storedUser.id })\n\n return ok(toUser(storedUser))\n },\n }\n\n // ─── challenge ───\n\n async function challenge(identifier: string): Promise<HaiResult<{ expiresAt: Date }>> {\n // 发送频率限制\n const existingResult = await config.otpRepository.fetchOtp(identifier)\n if (existingResult.success && existingResult.data) {\n const elapsedSeconds = Math.floor((Date.now() - existingResult.data.createdAt.getTime()) / 1000)\n if (elapsedSeconds < otpConfig.resendInterval) {\n return err(\n HaiIamError.OTP_RESEND_TOO_FAST,\n iamM('iam_otpResendTooFast', { params: { seconds: otpConfig.resendInterval - elapsedSeconds } }),\n )\n }\n }\n\n // 生成验证码\n const code = generateOtpCode(otpConfig.length)\n const expiresAt = new Date(Date.now() + otpConfig.expiresIn * 1000)\n\n // 存储验证码\n const storeResult = await config.otpRepository.saveOtp(identifier, code, otpConfig.expiresIn)\n if (!storeResult.success) {\n return storeResult as HaiResult<{ expiresAt: Date }>\n }\n\n // 通过业务层回调发送验证码\n const type = identifierType(identifier)\n if (type === 'email' && config.onOtpSendEmail) {\n try {\n await config.onOtpSendEmail(identifier, code)\n }\n catch (error) {\n return err(\n HaiIamError.INTERNAL_ERROR,\n iamM('iam_otpSendFailed', { params: { message: String(error) } }),\n error,\n )\n }\n }\n else if (type === 'phone' && config.onOtpSendSms) {\n try {\n await config.onOtpSendSms(identifier, code)\n }\n catch (error) {\n return err(\n HaiIamError.INTERNAL_ERROR,\n iamM('iam_otpSendFailed', { params: { message: String(error) } }),\n error,\n )\n }\n }\n else {\n return err(\n HaiIamError.INTERNAL_ERROR,\n iamM('iam_identifierTypeNotSupported'),\n )\n }\n\n const result = buildChallengeResult(expiresAt)\n logger.debug('OTP challenge sent', { identifier, expiresAt })\n return ok(result)\n }\n\n return { strategy, challenge }\n}\n","/**\n * @h-ai/iam — 密码认证策略\n *\n * 用户名/邮箱 + 密码的认证方式\n * @module iam-authn-password-strategy\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { PasswordConfig } from '../../iam-config.js'\nimport type { UserRepository } from '../../user/iam-user-repository-user.js'\nimport type { StoredUser, User } from '../../user/iam-user-types.js'\nimport type { AuthStrategy, Credentials } from '../iam-authn-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { crypto as haiCrypto } from '@h-ai/crypto'\n\nimport { PasswordConfigSchema } from '../../iam-config.js'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\nimport { toUser } from '../../user/iam-user-utils.js'\nimport { ensureCredentialType, isAccountLocked, recordLoginFailure, resetLoginFailures } from '../iam-authn-utils.js'\n\n/**\n * 密码认证策略配置\n */\nexport interface PasswordStrategyConfig {\n /** 密码策略 */\n passwordConfig?: PasswordConfig\n /** 用户存储 */\n userRepository: UserRepository\n /** 最大登录失败次数(默认 5) */\n maxLoginAttempts?: number\n /** 锁定时间(秒,默认 900 = 15分钟) */\n lockoutDuration?: number\n}\n\n/**\n * 密码策略工厂返回值\n */\nexport interface PasswordStrategyResult {\n /** 认证策略(用于通用登录流程) */\n strategy: AuthStrategy\n /** 验证密码强度 */\n validatePassword: (password: string) => HaiResult<void>\n /** 密码哈希 */\n hashPassword: (password: string) => HaiResult<string>\n /** 密码策略配置 */\n passwordConfig: PasswordConfig\n}\n\nconst logger = core.logger.child({ module: 'iam', scope: 'password-strategy' })\n\n/**\n * 创建密码认证策略\n */\nexport function createPasswordStrategy(config: PasswordStrategyConfig): PasswordStrategyResult {\n const passwordConfig = config.passwordConfig\n ? PasswordConfigSchema.parse(config.passwordConfig)\n : PasswordConfigSchema.parse({})\n\n const maxLoginAttempts = config.maxLoginAttempts ?? 5\n const lockoutDuration = config.lockoutDuration ?? 900\n const passwordOps = haiCrypto.password\n\n function mapPasswordError(message: string): HaiResult<never> {\n return err(\n HaiIamError.INTERNAL_ERROR,\n message,\n )\n }\n\n /**\n * 验证密码强度\n */\n function validatePasswordStrength(password: string): HaiResult<void> {\n if (password.length < passwordConfig.minLength) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordMinLength', { params: { minLength: passwordConfig.minLength } }),\n )\n }\n\n if (password.length > passwordConfig.maxLength) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordMaxLength', { params: { maxLength: passwordConfig.maxLength } }),\n )\n }\n\n if (passwordConfig.requireUppercase && !/[A-Z]/.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedUppercase'),\n )\n }\n\n if (passwordConfig.requireLowercase && !/[a-z]/.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedLowercase'),\n )\n }\n\n if (passwordConfig.requireNumber && !/\\d/.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedNumber'),\n )\n }\n\n if (passwordConfig.requireSpecialChar && !/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedSpecialChar'),\n )\n }\n\n return ok(undefined)\n }\n\n /**\n * 检查密码是否过期\n */\n function isPasswordExpired(user: StoredUser): boolean {\n if (passwordConfig.expirationDays <= 0 || !user.passwordUpdatedAt) {\n return false\n }\n const expirationDate = new Date(user.passwordUpdatedAt)\n expirationDate.setDate(expirationDate.getDate() + passwordConfig.expirationDays)\n return new Date() > expirationDate\n }\n\n /**\n * 校验账户状态(启用、锁定)\n */\n function checkAccountStatus(user: StoredUser): HaiResult<void> {\n if (!user.enabled) {\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n }\n if (isAccountLocked(user)) {\n return err(HaiIamError.USER_LOCKED, iamM('iam_accountLocked'))\n }\n return ok(undefined)\n }\n\n /**\n * 验证用户密码\n */\n async function verifyUserPassword(user: StoredUser, password: string): Promise<HaiResult<void>> {\n if (!user.passwordHash) {\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_accountNoPassword'))\n }\n const verifyResult = passwordOps.verify(password, user.passwordHash)\n if (!verifyResult.success) {\n return mapPasswordError(verifyResult.error.message)\n }\n\n if (!verifyResult.data) {\n await recordLoginFailure(config.userRepository, user, { maxLoginAttempts, lockoutDuration })\n logger.warn('Password verification failed', { userId: user.id })\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n }\n\n return ok(undefined)\n }\n\n const strategy: AuthStrategy = {\n type: 'password',\n name: 'password-strategy',\n\n async authenticate(credentials: Credentials): Promise<HaiResult<User>> {\n const credentialResult = ensureCredentialType(credentials, 'password')\n if (!credentialResult.success) {\n return credentialResult as HaiResult<User>\n }\n\n const { identifier, password } = credentialResult.data\n\n // 查找用户\n const userResult = await config.userRepository.findByIdentifier(identifier)\n if (!userResult.success)\n return userResult\n\n const storedUser = userResult.data\n if (!storedUser) {\n // 防止用户枚举:执行伪哈希验证以消除时序差异,统一返回 INVALID_CREDENTIALS\n await passwordOps.hash('dummy-password-to-prevent-timing-leak')\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n }\n\n // 校验账户状态\n const statusResult = checkAccountStatus(storedUser)\n if (!statusResult.success)\n return statusResult as HaiResult<User>\n\n // 验证密码\n const pwResult = await verifyUserPassword(storedUser, password)\n if (!pwResult.success)\n return pwResult as HaiResult<User>\n\n // 检查密码是否过期\n if (isPasswordExpired(storedUser)) {\n return err(HaiIamError.PASSWORD_EXPIRED, iamM('iam_passwordExpired'))\n }\n\n // 登录成功,重置失败计数\n await resetLoginFailures(config.userRepository, storedUser)\n logger.info('Password authentication succeeded', { userId: storedUser.id })\n\n return ok(toUser(storedUser))\n },\n }\n\n function hashPassword(password: string): HaiResult<string> {\n const hashResult = passwordOps.hash(password)\n if (!hashResult.success) {\n return mapPasswordError(hashResult.error.message)\n }\n return ok(hashResult.data)\n }\n\n return {\n strategy,\n validatePassword: validatePasswordStrength,\n hashPassword,\n passwordConfig,\n }\n}\n","/**\n * @h-ai/iam — 认证子功能工厂\n *\n * 创建认证策略(密码/OTP/LDAP),组装成统一的认证操作接口。\n * @module iam-authn-functions\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type { AuthzOperations } from '../authz/iam-authz-types.js'\nimport type { IamConfig } from '../iam-config.js'\nimport type { AuthResult, Session, SessionOperations } from '../session/iam-session-types.js'\nimport type { AgreementDisplay, User } from '../user/iam-user-types.js'\nimport type { ApiKeyOperations } from './apikey/iam-authn-apikey-types.js'\nimport type { ApiKeyCredentials, AuthnOperations, AuthStrategy, Credentials, LdapCredentials, OtpCredentials, PasswordCredentials } from './iam-authn-types.js'\nimport type { LdapClientFactory } from './ldap/iam-authn-ldap-strategy.js'\nimport type { OtpStrategyResult } from './otp/iam-authn-otp-strategy.js'\nimport type { PasswordStrategyResult } from './password/iam-authn-password-strategy.js'\n\nimport { core, err, ok } from '@h-ai/core'\n\nimport { AgreementConfigSchema, ApiKeyConfigSchema, LoginConfigSchema, OtpConfigSchema, SecurityConfigSchema } from '../iam-config.js'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { createDbUserRepository } from '../user/iam-user-repository-user.js'\nimport { createDbApiKeyRepository } from './apikey/iam-authn-apikey-repository.js'\nimport { createApiKeyStrategy } from './apikey/iam-authn-apikey-strategy.js'\nimport { createLdapStrategy } from './ldap/iam-authn-ldap-strategy.js'\nimport { createCacheOtpRepository } from './otp/iam-authn-otp-repository-otp.js'\nimport { createOtpStrategy } from './otp/iam-authn-otp-strategy.js'\nimport { createPasswordStrategy } from './password/iam-authn-password-strategy.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'authn' })\n\n// ─── 子功能依赖 ───\n\n/**\n * 认证子功能依赖\n */\nexport interface AuthnOperationsDeps {\n config: IamConfig\n sessionFunctions: SessionOperations\n authzFunctions: AuthzOperations\n ldapClientFactory?: LdapClientFactory\n ldapSyncUser?: boolean\n /** OTP 邮件发送回调(由业务层注入) */\n onOtpSendEmail?: (email: string, code: string) => Promise<void>\n /** OTP 短信发送回调(由业务层注入) */\n onOtpSendSms?: (phone: string, code: string) => Promise<void>\n}\n\n/**\n * 认证子功能工厂返回值\n *\n * 将公共 API 与内部依赖分离,避免将密码策略暴露在公共接口上。\n */\nexport interface AuthnOperationsResult {\n /** 对外暴露的认证操作(不含 registerAndLogin,由 iam-main 组合注入) */\n authn: Omit<AuthnOperations, 'registerAndLogin'>\n /** 密码策略结果(仅供内部 user 子功能复用,对外不可见) */\n passwordStrategyResult: PasswordStrategyResult\n /** API Key 管理操作(仅在启用 apikey 登录时可用) */\n apiKeyFunctions: ApiKeyOperations | null\n}\n\n/**\n * 创建认证子功能\n *\n * 内部创建密码/OTP/LDAP 策略,组装成统一的认证操作接口。\n */\nexport async function createAuthnOperations(deps: AuthnOperationsDeps): Promise<HaiResult<AuthnOperationsResult>> {\n try {\n const { config, sessionFunctions, authzFunctions, ldapClientFactory, ldapSyncUser, onOtpSendEmail, onOtpSendSms } = deps\n\n const userRepository = await createDbUserRepository()\n const securityConfig = SecurityConfigSchema.parse(config.security ?? {})\n const loginConfig = LoginConfigSchema.parse(config.login ?? {})\n\n /**\n * 用户自动注册后分配默认角色的回调\n *\n * 供 OTP/LDAP 策略在自动创建用户后调用。\n */\n async function onUserAutoRegistered(userId: string): Promise<void> {\n if (!config.rbac?.defaultRole)\n return\n const roleResult = await authzFunctions.getRoleByCode(config.rbac.defaultRole)\n if (roleResult.success && roleResult.data) {\n await authzFunctions.assignRole(userId, roleResult.data.id)\n }\n }\n\n // 密码策略\n const passwordResult = createPasswordStrategy({\n passwordConfig: config.password,\n userRepository,\n maxLoginAttempts: securityConfig.maxLoginAttempts,\n lockoutDuration: securityConfig.lockoutDuration,\n })\n\n // OTP 策略\n let otpResult: OtpStrategyResult | undefined\n const otpConfig = config.otp ? OtpConfigSchema.parse(config.otp) : undefined\n if (loginConfig.otp && otpConfig) {\n const otpRepository = createCacheOtpRepository()\n otpResult = createOtpStrategy({\n otpConfig,\n userRepository,\n otpRepository,\n autoRegister: true,\n registerConfig: config.register,\n maxLoginAttempts: securityConfig.maxLoginAttempts,\n lockoutDuration: securityConfig.lockoutDuration,\n onUserAutoRegistered,\n onOtpSendEmail,\n onOtpSendSms,\n })\n }\n\n // LDAP 策略\n let ldapStrategy: AuthStrategy | undefined\n if (loginConfig.ldap && config.ldap && ldapClientFactory) {\n ldapStrategy = createLdapStrategy({\n ldapConfig: config.ldap,\n userRepository,\n ldapClientFactory,\n syncUser: ldapSyncUser ?? true,\n maxLoginAttempts: securityConfig.maxLoginAttempts,\n lockoutDuration: securityConfig.lockoutDuration,\n onUserAutoRegistered,\n })\n }\n\n // API Key 策略\n let apiKeyStrategy: AuthStrategy | undefined\n let apiKeyFunctions: ApiKeyOperations | null = null\n if (loginConfig.apikey) {\n const apiKeyConfig = config.apikey ? ApiKeyConfigSchema.parse(config.apikey) : undefined\n const apiKeyRepository = await createDbApiKeyRepository()\n const apiKeyResult = createApiKeyStrategy({\n apikeyConfig: apiKeyConfig,\n userRepository,\n apiKeyRepository,\n })\n apiKeyStrategy = apiKeyResult.strategy\n apiKeyFunctions = apiKeyResult.apiKeyFunctions\n }\n\n // 组装认证操作\n const operations = buildAuthnOperations({\n passwordStrategy: passwordResult.strategy,\n otpStrategy: otpResult?.strategy,\n otpChallenge: otpResult?.challenge,\n ldapStrategy,\n apiKeyStrategy,\n sessionFunctions,\n authzFunctions,\n config,\n })\n\n logger.info('Authn sub-feature initialized')\n return ok({ authn: operations, passwordStrategyResult: passwordResult, apiKeyFunctions })\n }\n catch (error) {\n logger.error('Authn sub-feature initialization failed', { error })\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_initComponentFailed'),\n error,\n )\n }\n}\n\n// ─── 内部实现 ───\n\ninterface BuildAuthnDeps {\n passwordStrategy: AuthStrategy\n otpStrategy?: AuthStrategy\n otpChallenge?: (identifier: string) => Promise<HaiResult<{ expiresAt: Date }>>\n ldapStrategy?: AuthStrategy\n apiKeyStrategy?: AuthStrategy\n sessionFunctions: SessionOperations\n authzFunctions: AuthzOperations\n config: IamConfig\n}\n\n/**\n * 组装认证操作(纯同步,不涉及 I/O)\n *\n * 不含 registerAndLogin,该方法需要 userFunctions 依赖,由 iam-main 在初始化后组合注入。\n */\nfunction buildAuthnOperations(deps: BuildAuthnDeps): Omit<AuthnOperations, 'registerAndLogin'> {\n const {\n passwordStrategy,\n otpStrategy,\n otpChallenge,\n ldapStrategy,\n apiKeyStrategy,\n sessionFunctions,\n authzFunctions,\n config,\n } = deps\n\n const loginConfig = LoginConfigSchema.parse(config.login ?? {})\n const agreementConfig = AgreementConfigSchema.parse(config.agreements ?? {})\n\n /**\n * 构建协议展示信息\n *\n * 根据配置决定是否在登录时展示用户协议/隐私协议链接。\n *\n * @returns 协议展示信息,或 undefined(未启用时)\n */\n function buildAgreementDisplay(): AgreementDisplay | undefined {\n if (!agreementConfig.showOnLogin) {\n return undefined\n }\n if (!agreementConfig.userAgreementUrl && !agreementConfig.privacyPolicyUrl) {\n return undefined\n }\n return {\n userAgreementUrl: agreementConfig.userAgreementUrl,\n privacyPolicyUrl: agreementConfig.privacyPolicyUrl,\n showOnRegister: agreementConfig.showOnRegister,\n showOnLogin: agreementConfig.showOnLogin,\n }\n }\n\n /**\n * 检查指定登录方式是否被禁用\n *\n * @param type - 登录方式类型\n * @returns 禁用时返回错误 HaiResult,否则返回 null\n */\n function loginDisabled(type: 'password' | 'otp' | 'ldap' | 'apikey'): HaiResult<void> | null {\n if (!loginConfig[type]) {\n return err(\n HaiIamError.LOGIN_DISABLED,\n iamM('iam_loginDisabled', { params: { type } }),\n )\n }\n return null\n }\n\n /**\n * 查询用户角色 code 列表\n *\n * @param userId - 用户 ID\n * @returns 角色 code 数组\n */\n async function resolveUserRoleCodes(userId: string): Promise<HaiResult<string[]>> {\n const rolesResult = await authzFunctions.getUserRoles(userId)\n if (!rolesResult.success) {\n return rolesResult as HaiResult<string[]>\n }\n return ok(rolesResult.data.map(role => role.code))\n }\n\n /**\n * 查询用户权限 code 列表\n *\n * @param userId - 用户 ID\n * @returns 权限 code 数组\n */\n async function resolveUserPermissionCodes(userId: string): Promise<HaiResult<string[]>> {\n const permissionsResult = await authzFunctions.getUserPermissions(userId)\n if (!permissionsResult.success) {\n return permissionsResult as HaiResult<string[]>\n }\n return ok(permissionsResult.data.map(p => p.code))\n }\n\n /**\n * 解析认证策略实例\n *\n * 根据登录类型获取对应的策略实例,若策略未注册则返回错误。\n *\n * @param type - 登录方式类型\n * @param strategy - 已注册的策略实例(可选)\n * @returns 策略实例,或策略不支持错误\n */\n function resolveStrategy(type: 'password' | 'otp' | 'ldap' | 'apikey', strategy?: AuthStrategy): HaiResult<AuthStrategy> {\n if (strategy) {\n return ok(strategy)\n }\n\n if (type === 'otp') {\n return err(\n HaiIamError.STRATEGY_NOT_SUPPORTED,\n iamM('iam_otpStrategyRequired'),\n )\n }\n\n if (type === 'ldap') {\n return err(\n HaiIamError.STRATEGY_NOT_SUPPORTED,\n iamM('iam_ldapStrategyRequired'),\n )\n }\n\n return err(\n HaiIamError.STRATEGY_NOT_SUPPORTED,\n iamM('iam_featureNotImplemented'),\n )\n }\n\n /**\n * 构建认证结果\n *\n * 查询用户角色、创建会话、组装协议展示信息,返回完整的登录结果。\n *\n * @param user - 已认证的用户信息\n * @returns 包含用户信息、访问令牌、过期时间和协议展示的认证结果\n */\n async function buildAuthResult(user: User): Promise<HaiResult<AuthResult>> {\n // 并行获取角色和权限,登录时一次性查 DB,后续纯缓存\n const [roleCodesResult, permCodesResult] = await Promise.all([\n resolveUserRoleCodes(user.id),\n resolveUserPermissionCodes(user.id),\n ])\n if (!roleCodesResult.success) {\n return roleCodesResult as HaiResult<AuthResult>\n }\n if (!permCodesResult.success) {\n return permCodesResult as HaiResult<AuthResult>\n }\n\n const sessionResult = await sessionFunctions.create({\n userId: user.id,\n username: user.username,\n displayName: user.displayName,\n avatarUrl: user.avatarUrl,\n roles: roleCodesResult.data,\n permissions: permCodesResult.data,\n })\n\n if (!sessionResult.success) {\n return sessionResult as HaiResult<AuthResult>\n }\n\n const session = sessionResult.data\n\n // 从 session.data._tokenPair 提取 TokenPair(由 session.create 写入)\n const tokenPair = session.data?._tokenPair\n if (!tokenPair) {\n return err(HaiIamError.SESSION_CREATE_FAILED, iamM('iam_createSessionFailed'))\n }\n\n return ok({\n user,\n tokens: tokenPair,\n roles: roleCodesResult.data,\n permissions: permCodesResult.data,\n agreements: buildAgreementDisplay(),\n })\n }\n\n /**\n * 通用策略登录流程\n *\n * 检查登录方式是否启用→解析策略→执行认证→构建结果。\n *\n * @param type - 登录方式\n * @param credentials - 用户凭证\n * @param strategy - 认证策略实例(可选)\n * @returns 认证结果(包含用户、令牌、协议)\n */\n async function loginWithStrategy(\n type: 'password' | 'otp' | 'ldap' | 'apikey',\n credentials: PasswordCredentials | OtpCredentials | LdapCredentials | ApiKeyCredentials,\n strategy?: AuthStrategy,\n ): Promise<HaiResult<AuthResult>> {\n const disabled = loginDisabled(type)\n if (disabled)\n return disabled as HaiResult<AuthResult>\n\n const strategyResult = resolveStrategy(type, strategy)\n if (!strategyResult.success)\n return strategyResult as HaiResult<AuthResult>\n\n const authResult = await strategyResult.data.authenticate({\n type,\n ...credentials,\n } as Credentials)\n\n if (!authResult.success) {\n logger.warn('Login failed', { type, reason: authResult.error.code })\n return authResult as HaiResult<AuthResult>\n }\n\n const result = await buildAuthResult(authResult.data)\n if (result.success) {\n logger.info('Login succeeded', { type, userId: authResult.data.id })\n }\n return result\n }\n\n return {\n async login(credentials: PasswordCredentials): Promise<HaiResult<AuthResult>> {\n return loginWithStrategy('password', credentials, passwordStrategy)\n },\n\n async loginWithOtp(credentials: OtpCredentials): Promise<HaiResult<AuthResult>> {\n return loginWithStrategy('otp', credentials, otpStrategy)\n },\n\n async loginWithLdap(credentials: LdapCredentials): Promise<HaiResult<AuthResult>> {\n return loginWithStrategy('ldap', credentials, ldapStrategy)\n },\n\n async loginWithApiKey(credentials: ApiKeyCredentials): Promise<HaiResult<AuthResult>> {\n return loginWithStrategy('apikey', credentials, apiKeyStrategy)\n },\n\n async logout(accessToken: string): Promise<HaiResult<void>> {\n const sessionResult = await sessionFunctions.get(accessToken)\n if (sessionResult.success && sessionResult.data) {\n // 吊销 refreshToken,防止登出后被重用\n const tokenPair = sessionResult.data.data?._tokenPair\n if (tokenPair?.refreshToken) {\n await sessionFunctions.revokeRefresh(tokenPair.refreshToken)\n }\n await sessionFunctions.delete(sessionResult.data.accessToken)\n logger.info('User logged out', { userId: sessionResult.data.userId })\n }\n\n return ok(undefined)\n },\n\n async verifyToken(accessToken: string): Promise<HaiResult<Session>> {\n return sessionFunctions.verifyToken(accessToken)\n },\n\n async sendOtp(identifier: string): Promise<HaiResult<{ expiresAt: Date }>> {\n const disabled = loginDisabled('otp')\n if (disabled) {\n return disabled as HaiResult<{ expiresAt: Date }>\n }\n\n if (!otpChallenge) {\n return err(\n HaiIamError.STRATEGY_NOT_SUPPORTED,\n iamM('iam_otpStrategyRequiredForSend'),\n )\n }\n\n return otpChallenge(identifier)\n },\n }\n}\n","/**\n * @h-ai/iam — 权限存储实现\n *\n * 基于 @h-ai/reldb 的权限存储实现。\n * @module iam-authz-repository-permission\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations, ReldbCrudFieldDefinition, ReldbCrudRepository } from '@h-ai/reldb'\nimport type { Permission } from './iam-authz-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { BaseReldbCrudRepository, reldb } from '@h-ai/reldb'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n// ─── 权限存储接口 ───\n\n/**\n * 权限存储接口\n */\nexport interface PermissionRepository extends ReldbCrudRepository<Permission> {\n /**\n * 根据代码获取权限\n */\n findByCode: (code: string, tx?: DmlWithTxOperations) => Promise<HaiResult<Permission | null>>\n}\n\n// ─── 权限存储实现 ───\n\n/**\n * 权限表名\n */\nconst TABLE_NAME = 'hai_iam_permissions'\n\nconst PERMISSION_FIELDS: ReldbCrudFieldDefinition[] = [\n {\n fieldName: 'id',\n columnName: 'id',\n def: { type: 'TEXT' as const, primaryKey: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'code',\n columnName: 'code',\n def: { type: 'TEXT' as const, notNull: true, unique: true },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'name',\n columnName: 'name',\n def: { type: 'TEXT' as const, notNull: true },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'description',\n columnName: 'description',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'resource',\n columnName: 'resource',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'action',\n columnName: 'action',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'type',\n columnName: 'type',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'createdAt',\n columnName: 'created_at',\n def: { type: 'TIMESTAMP' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'updatedAt',\n columnName: 'updated_at',\n def: { type: 'TIMESTAMP' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n]\n\n/** 权限存储单例缓存(通过 reldb.config 引用比较检测 db 重新初始化) */\nlet permRepoInstance: PermissionRepository | null = null\nlet permRepoDbConfig: unknown = null\n\n/**\n * 重置权限存储单例\n *\n * 在 iam.close() 时调用,释放对旧 db 实例的引用。\n */\nexport function resetPermissionRepoSingleton(): void {\n permRepoInstance = null\n permRepoDbConfig = null\n}\n\n/**\n * 创建基于数据库的权限存储实例\n *\n * 单例模式:同一 db 生命周期内重复调用返回缓存实例,\n * db 重新初始化后自动创建新实例。\n *\n * @returns 权限存储接口实现\n */\nexport async function createDbPermissionRepository(): Promise<PermissionRepository> {\n if (permRepoInstance && permRepoDbConfig === reldb.config)\n return permRepoInstance\n\n const repo = new DbPermissionRepository()\n await repo.count()\n permRepoInstance = repo\n permRepoDbConfig = reldb.config\n return repo\n}\n\n/**\n * 基于数据库的权限存储实现\n *\n * 继承 BaseReldbCrudRepository,提供按 code 查找权限的能力。\n */\nclass DbPermissionRepository extends BaseReldbCrudRepository<Permission> implements PermissionRepository {\n constructor() {\n super(reldb, {\n table: TABLE_NAME,\n fields: PERMISSION_FIELDS,\n })\n }\n\n /** 根据权限代码查找权限 */\n async findByCode(code: string, tx?: DmlWithTxOperations): Promise<HaiResult<Permission | null>> {\n return this.findOneBy('code = ?', [code], tx)\n }\n\n private buildQueryError(error: { message: string }, cause: unknown): HaiResult<never> {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryPermissionFailed', { params: { message: error.message } }),\n cause,\n )\n }\n\n private async findOneBy(where: string, params: unknown[], tx?: DmlWithTxOperations): Promise<HaiResult<Permission | null>> {\n const result = await this.findAll({ where, params, limit: 1 }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error, result.error)\n }\n return ok(result.data[0] ?? null)\n }\n}\n","/**\n * @h-ai/iam — 关联关系存储实现\n *\n * 包含角色-权限、用户-角色关联存储。\n * @module iam-authz-repository-relation\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations } from '@h-ai/reldb'\nimport type { RoleRepository } from './iam-authz-repository-role.js'\nimport type { Permission, Role } from './iam-authz-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { reldb } from '@h-ai/reldb'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n// ─── 角色-权限关联存储接口 ───\n\n/**\n * 角色-权限关联存储接口\n */\nexport interface RolePermissionRepository {\n /**\n * 分配权限给角色\n */\n assign: (roleId: string, permissionId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n\n /**\n * 移除角色权限\n */\n remove: (roleId: string, permissionId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n\n /**\n * 获取角色的所有权限\n */\n getPermissions: (roleId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<Permission[]>>\n\n /**\n * 批量获取多个角色的权限代码(去重)\n *\n * 单次 JOIN 查询替代 N 次逐角色查询。\n *\n * @param roleIds - 角色 ID 列表\n * @returns 去重后的权限代码数组\n */\n getPermissionCodesForRoles: (roleIds: string[]) => Promise<HaiResult<string[]>>\n\n /**\n * 删除角色的所有权限关联\n */\n removeByRoleId: (roleId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n\n /**\n * 删除权限的所有角色关联\n */\n removeByPermissionId: (permissionId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n\n /**\n * 查询拥有指定权限的所有角色 ID\n *\n * @param permissionId - 权限 ID\n * @returns 角色 ID 数组\n */\n getRoleIdsByPermissionId: (permissionId: string) => Promise<HaiResult<string[]>>\n\n /**\n * 批量获取多个角色的权限列表\n *\n * 单次查询替代 N 次 getPermissions 调用,避免 N+1 问题。\n * 返回 Map:key 为 roleId,value 为该角色的权限列表;无权限的角色返回空数组。\n *\n * @param roleIds - 角色 ID 列表\n * @returns Map<roleId, Permission[]>\n */\n getPermissionsForRoles: (roleIds: string[]) => Promise<HaiResult<Map<string, Permission[]>>>\n}\n\n// ─── 用户-角色关联存储接口 ───\n\n/**\n * 用户-角色关联存储接口\n */\nexport interface UserRoleRepository {\n /**\n * 分配角色给用户\n */\n assign: (userId: string, roleId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n\n /**\n * 移除用户角色\n */\n remove: (userId: string, roleId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<void>>\n\n /**\n * 获取用户的所有角色 ID\n */\n getRoleIds: (userId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<string[]>>\n\n /**\n * 获取用户的所有角色\n */\n getRoles: (userId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<Role[]>>\n\n /**\n * 删除角色的所有用户关联(仅 DB 操作)\n *\n * 返回受影响的用户 ID 列表。\n * 不同步会话;调用方应在事务提交后通过 SessionOperations 同步。\n */\n removeByRoleId: (roleId: string, tx?: DmlWithTxOperations) => Promise<HaiResult<string[]>>\n\n /**\n * 查询拥有指定角色的所有用户 ID\n *\n * @param roleId - 角色 ID\n * @returns 用户 ID 数组\n */\n getUserIdsByRoleId: (roleId: string) => Promise<HaiResult<string[]>>\n\n /**\n * 批量获取多个用户的角色列表\n *\n * 单次查询替代 N 次 getRoles 调用,避免 N+1 问题。\n * 返回 Map:key 为 userId,value 为该用户的角色列表;无角色的用户返回空数组。\n *\n * @param userIds - 用户 ID 列表\n * @returns Map<userId, Role[]>\n */\n getRolesForUsers: (userIds: string[]) => Promise<HaiResult<Map<string, Role[]>>>\n}\n\n// ─── 角色-权限关联存储实现 ───\n\nconst ROLE_PERMISSION_TABLE = 'hai_iam_role_permissions'\nconst PERMISSION_TABLE = 'hai_iam_permissions'\nconst ROLE_PERMISSION_SCHEMA = {\n role_id: { type: 'TEXT' as const, notNull: true },\n permission_id: { type: 'TEXT' as const, notNull: true },\n}\n\n/**\n * 创建基于数据库的角色-权限关联存储\n *\n * 自动创建关联表和索引,提供分配/移除/查询权限能力。\n *\n * @returns 角色-权限关联存储接口实现(失败返回 IamError)\n */\nexport async function createDbRolePermissionRepository(): Promise<HaiResult<RolePermissionRepository>> {\n // 确保表存在\n async function ensureTable(): Promise<HaiResult<void>> {\n const result = await reldb.ddl.createTable(ROLE_PERMISSION_TABLE, ROLE_PERMISSION_SCHEMA, true)\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createRolePermissionTableFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n const indexResults = await Promise.all([\n reldb.ddl.createIndex(ROLE_PERMISSION_TABLE, 'idx_role_perm_role_perm', { columns: ['role_id', 'permission_id'], unique: true }),\n reldb.ddl.createIndex(ROLE_PERMISSION_TABLE, 'idx_role_perm_role', { columns: ['role_id'] }),\n ])\n for (const indexResult of indexResults) {\n if (!indexResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createRolePermissionIndexFailed', { params: { message: indexResult.error.message } }),\n indexResult.error,\n )\n }\n }\n\n return ok(undefined)\n }\n\n const initResult = await ensureTable()\n if (!initResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n initResult.error.message,\n initResult.error,\n )\n }\n\n /**\n * 查询角色的所有权限 ID\n *\n * @param roleId - 角色 ID\n * @param tx - 可选事务句柄\n * @returns 权限 ID 数组\n */\n async function getPermissionIdsInternal(roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<string[]>> {\n const runner = tx ?? reldb.sql\n const result = await runner.query<{ permission_id: string }>(\n `SELECT permission_id FROM ${ROLE_PERMISSION_TABLE} WHERE role_id = ?`,\n [roleId],\n )\n\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryPermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(result.data.map(r => r.permission_id))\n }\n\n return ok({\n async assign(roleId: string, permissionId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const runner = tx ?? reldb.sql\n const result = await runner.execute(\n `INSERT INTO ${ROLE_PERMISSION_TABLE} (role_id, permission_id) VALUES (?, ?) ON CONFLICT DO NOTHING`,\n [roleId, permissionId],\n )\n\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_assignPermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(undefined)\n },\n\n async remove(roleId: string, permissionId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const runner = tx ?? reldb.sql\n const result = await runner.execute(\n `DELETE FROM ${ROLE_PERMISSION_TABLE} WHERE role_id = ? AND permission_id = ?`,\n [roleId, permissionId],\n )\n\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_removePermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(undefined)\n },\n\n async getPermissions(roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<Permission[]>> {\n const idsResult = await getPermissionIdsInternal(roleId, tx)\n if (!idsResult.success)\n return idsResult\n\n if (idsResult.data.length === 0) {\n return ok([])\n }\n\n const placeholders = idsResult.data.map(() => '?').join(', ')\n const result = await reldb.sql.query<Record<string, unknown>>(\n `SELECT * FROM ${PERMISSION_TABLE} WHERE id IN (${placeholders})`,\n idsResult.data,\n )\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryPermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(result.data as unknown as Permission[])\n },\n\n async getPermissionCodesForRoles(roleIds: string[]): Promise<HaiResult<string[]>> {\n if (roleIds.length === 0) {\n return ok([])\n }\n\n const placeholders = roleIds.map(() => '?').join(', ')\n const result = await reldb.sql.query<{ code: string }>(\n `SELECT DISTINCT p.code FROM ${ROLE_PERMISSION_TABLE} rp JOIN ${PERMISSION_TABLE} p ON rp.permission_id = p.id WHERE rp.role_id IN (${placeholders})`,\n roleIds,\n )\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryPermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(result.data.map(r => r.code))\n },\n\n async removeByRoleId(roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const runner = tx ?? reldb.sql\n const result = await runner.execute(\n `DELETE FROM ${ROLE_PERMISSION_TABLE} WHERE role_id = ?`,\n [roleId],\n )\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_removePermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n },\n\n async removeByPermissionId(permissionId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const runner = tx ?? reldb.sql\n const result = await runner.execute(\n `DELETE FROM ${ROLE_PERMISSION_TABLE} WHERE permission_id = ?`,\n [permissionId],\n )\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_removePermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n },\n\n async getRoleIdsByPermissionId(permissionId: string): Promise<HaiResult<string[]>> {\n const result = await reldb.sql.query<{ role_id: string }>(\n `SELECT role_id FROM ${ROLE_PERMISSION_TABLE} WHERE permission_id = ?`,\n [permissionId],\n )\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryPermissionFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(result.data.map(r => r.role_id))\n },\n\n async getPermissionsForRoles(roleIds: string[]): Promise<HaiResult<Map<string, Permission[]>>> {\n const result = new Map<string, Permission[]>()\n if (roleIds.length === 0) {\n return ok(result)\n }\n\n const placeholders = roleIds.map(() => '?').join(', ')\n const relationsResult = await reldb.sql.query<{ role_id: string, permission_id: string }>(\n `SELECT role_id, permission_id FROM ${ROLE_PERMISSION_TABLE} WHERE role_id IN (${placeholders})`,\n roleIds,\n )\n if (!relationsResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryPermissionFailed', { params: { message: relationsResult.error.message } }),\n relationsResult.error,\n )\n }\n\n for (const rid of roleIds) {\n result.set(rid, [])\n }\n\n if (relationsResult.data.length === 0) {\n return ok(result)\n }\n\n const uniquePermIds = [...new Set(relationsResult.data.map(r => r.permission_id))]\n const permPlaceholders = uniquePermIds.map(() => '?').join(', ')\n const permsResult = await reldb.sql.query<Record<string, unknown>>(\n `SELECT * FROM ${PERMISSION_TABLE} WHERE id IN (${permPlaceholders})`,\n uniquePermIds,\n )\n if (!permsResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryPermissionFailed', { params: { message: permsResult.error.message } }),\n permsResult.error,\n )\n }\n\n const permMap = new Map<string, Permission>()\n for (const perm of permsResult.data as unknown as Permission[]) {\n permMap.set(perm.id, perm)\n }\n\n for (const rel of relationsResult.data) {\n const perm = permMap.get(rel.permission_id)\n if (perm) {\n result.get(rel.role_id)!.push(perm)\n }\n }\n\n return ok(result)\n },\n })\n}\n\n// ─── 用户-角色关联存储实现 ───\n\nconst USER_ROLE_TABLE = 'hai_iam_user_roles'\nconst USER_ROLE_SCHEMA = {\n user_id: { type: 'TEXT' as const, notNull: true },\n role_id: { type: 'TEXT' as const, notNull: true },\n}\n\n/**\n * 创建基于数据库的用户-角色关联存储\n *\n * 自动创建关联表和索引,提供分配/移除/查询角色能力。\n * 会话同步由上层(authz functions)通过 SessionOperations 完成。\n *\n * @param roleRepository - 角色存储(用于查询角色详情)\n * @returns 用户-角色关联存储接口实现(失败返回 IamError)\n */\nexport async function createDbUserRoleRepository(\n roleRepository: RoleRepository,\n): Promise<HaiResult<UserRoleRepository>> {\n /**\n * 确保关联表和索引已创建\n *\n * 创建 `hai_iam_user_roles` 表及唯一约束索引。\n */\n async function ensureTable(): Promise<HaiResult<void>> {\n const result = await reldb.ddl.createTable(USER_ROLE_TABLE, USER_ROLE_SCHEMA, true)\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createUserRoleTableFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n const indexResults = await Promise.all([\n reldb.ddl.createIndex(USER_ROLE_TABLE, 'idx_user_role_user_role', { columns: ['user_id', 'role_id'], unique: true }),\n reldb.ddl.createIndex(USER_ROLE_TABLE, 'idx_user_role_user', { columns: ['user_id'] }),\n ])\n for (const indexResult of indexResults) {\n if (!indexResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createUserRoleIndexFailed', { params: { message: indexResult.error.message } }),\n indexResult.error,\n )\n }\n }\n\n return ok(undefined)\n }\n\n const initResult = await ensureTable()\n if (!initResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n initResult.error.message,\n initResult.error,\n )\n }\n\n /**\n * 查询用户的所有角色 ID\n *\n * @param userId - 用户 ID\n * @param tx - 可选事务句柄\n * @returns 角色 ID 数组\n */\n async function getRoleIdsInternal(userId: string, tx?: DmlWithTxOperations): Promise<HaiResult<string[]>> {\n const runner = tx ?? reldb.sql\n const result = await runner.query<{ role_id: string }>(\n `SELECT role_id FROM ${USER_ROLE_TABLE} WHERE user_id = ?`,\n [userId],\n )\n\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryRoleFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(result.data.map(r => r.role_id))\n }\n\n return ok({\n async assign(userId: string, roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const runner = tx ?? reldb.sql\n const result = await runner.execute(\n `INSERT INTO ${USER_ROLE_TABLE} (user_id, role_id) VALUES (?, ?) ON CONFLICT DO NOTHING`,\n [userId, roleId],\n )\n\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_assignRoleFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(undefined)\n },\n\n async remove(userId: string, roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const runner = tx ?? reldb.sql\n const result = await runner.execute(\n `DELETE FROM ${USER_ROLE_TABLE} WHERE user_id = ? AND role_id = ?`,\n [userId, roleId],\n )\n\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_removeRoleFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n\n return ok(undefined)\n },\n\n async getRoleIds(userId: string, tx?: DmlWithTxOperations): Promise<HaiResult<string[]>> {\n return getRoleIdsInternal(userId, tx)\n },\n\n async getRoles(userId: string, tx?: DmlWithTxOperations): Promise<HaiResult<Role[]>> {\n const idsResult = await getRoleIdsInternal(userId, tx)\n if (!idsResult.success)\n return idsResult\n\n if (idsResult.data.length === 0) {\n return ok([])\n }\n const placeholders = idsResult.data.map(() => '?').join(', ')\n const roleResult = await roleRepository.findAll({\n where: `id IN (${placeholders})`,\n params: idsResult.data,\n }, tx)\n if (!roleResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryRoleFailed', { params: { message: roleResult.error.message } }),\n roleResult.error,\n )\n }\n\n return ok(roleResult.data)\n },\n\n async removeByRoleId(roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<string[]>> {\n const runner = tx ?? reldb.sql\n\n // 查出受影响的用户 ID\n const usersResult = await runner.query<{ user_id: string }>(\n `SELECT user_id FROM ${USER_ROLE_TABLE} WHERE role_id = ?`,\n [roleId],\n )\n if (!usersResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryRoleFailed', { params: { message: usersResult.error.message } }),\n usersResult.error,\n )\n }\n\n // 删除关联行\n const deleteResult = await runner.execute(\n `DELETE FROM ${USER_ROLE_TABLE} WHERE role_id = ?`,\n [roleId],\n )\n if (!deleteResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_removeRoleFailed', { params: { message: deleteResult.error.message } }),\n deleteResult.error,\n )\n }\n\n return ok(usersResult.data.map(r => r.user_id))\n },\n\n async getUserIdsByRoleId(roleId: string): Promise<HaiResult<string[]>> {\n const result = await reldb.sql.query<{ user_id: string }>(\n `SELECT user_id FROM ${USER_ROLE_TABLE} WHERE role_id = ?`,\n [roleId],\n )\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryRoleFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(result.data.map(r => r.user_id))\n },\n\n async getRolesForUsers(userIds: string[]): Promise<HaiResult<Map<string, Role[]>>> {\n const result = new Map<string, Role[]>()\n // 空列表直接返回空 Map\n if (userIds.length === 0) {\n return ok(result)\n }\n\n // 批量查询所有用户的角色关联\n const placeholders = userIds.map(() => '?').join(', ')\n const relationsResult = await reldb.sql.query<{ user_id: string, role_id: string }>(\n `SELECT user_id, role_id FROM ${USER_ROLE_TABLE} WHERE user_id IN (${placeholders})`,\n userIds,\n )\n if (!relationsResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryRoleFailed', { params: { message: relationsResult.error.message } }),\n relationsResult.error,\n )\n }\n\n // 初始化所有 userId → 空数组\n for (const uid of userIds) {\n result.set(uid, [])\n }\n\n if (relationsResult.data.length === 0) {\n return ok(result)\n }\n\n // 收集去重的 roleId,批量查询角色详情\n const uniqueRoleIds = [...new Set(relationsResult.data.map(r => r.role_id))]\n const rolePlaceholders = uniqueRoleIds.map(() => '?').join(', ')\n const rolesResult = await roleRepository.findAll({\n where: `id IN (${rolePlaceholders})`,\n params: uniqueRoleIds,\n })\n if (!rolesResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryRoleFailed', { params: { message: rolesResult.error.message } }),\n rolesResult.error,\n )\n }\n\n // roleId → Role 索引\n const roleMap = new Map<string, Role>()\n for (const role of rolesResult.data) {\n roleMap.set(role.id, role)\n }\n\n // 按 userId 分组填充\n for (const rel of relationsResult.data) {\n const role = roleMap.get(rel.role_id)\n if (role) {\n result.get(rel.user_id)!.push(role)\n }\n }\n\n return ok(result)\n },\n })\n}\n","/**\n * @h-ai/iam — 角色存储实现\n *\n * 基于 @h-ai/reldb 的角色存储实现。\n * @module iam-authz-repository-role\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations, ReldbCrudFieldDefinition, ReldbCrudRepository } from '@h-ai/reldb'\nimport type { Role } from './iam-authz-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { BaseReldbCrudRepository, reldb } from '@h-ai/reldb'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n// ─── 角色存储接口 ───\n\n/**\n * 角色存储接口\n */\nexport interface RoleRepository extends ReldbCrudRepository<Role> {\n /**\n * 根据代码获取角色\n */\n findByCode: (code: string, tx?: DmlWithTxOperations) => Promise<HaiResult<Role | null>>\n}\n\n// ─── 角色存储实现 ───\n\n/**\n * 角色表名\n */\nconst TABLE_NAME = 'hai_iam_roles'\n\nconst ROLE_FIELDS: ReldbCrudFieldDefinition[] = [\n {\n fieldName: 'id',\n columnName: 'id',\n def: { type: 'TEXT' as const, primaryKey: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'code',\n columnName: 'code',\n def: { type: 'TEXT' as const, notNull: true, unique: true },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'name',\n columnName: 'name',\n def: { type: 'TEXT' as const, notNull: true },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'description',\n columnName: 'description',\n def: { type: 'TEXT' as const },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'isSystem',\n columnName: 'is_system',\n def: { type: 'BOOLEAN' as const, defaultValue: 0 },\n select: true,\n create: true,\n update: true,\n },\n {\n fieldName: 'createdAt',\n columnName: 'created_at',\n def: { type: 'TIMESTAMP' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n {\n fieldName: 'updatedAt',\n columnName: 'updated_at',\n def: { type: 'TIMESTAMP' as const, notNull: true },\n select: true,\n create: true,\n update: false,\n },\n]\n\n/** 角色存储单例缓存(通过 reldb.config 引用比较检测 db 重新初始化) */\nlet roleRepoInstance: RoleRepository | null = null\nlet roleRepoDbConfig: unknown = null\n\n/**\n * 重置角色存储单例\n *\n * 在 iam.close() 时调用,释放对旧 db 实例的引用。\n */\nexport function resetRoleRepoSingleton(): void {\n roleRepoInstance = null\n roleRepoDbConfig = null\n}\n\n/**\n * 创建基于数据库的角色存储实例\n *\n * 单例模式:同一 db 生命周期内重复调用返回缓存实例,\n * db 重新初始化后自动创建新实例。\n *\n * @returns 角色存储接口实现\n */\nexport async function createDbRoleRepository(): Promise<RoleRepository> {\n if (roleRepoInstance && roleRepoDbConfig === reldb.config)\n return roleRepoInstance\n\n const repo = new DbRoleRepository()\n await repo.count()\n roleRepoInstance = repo\n roleRepoDbConfig = reldb.config\n return repo\n}\n\n/**\n * 基于数据库的角色存储实现\n *\n * 继承 BaseReldbCrudRepository,提供按 code 查找角色的能力。\n */\nclass DbRoleRepository extends BaseReldbCrudRepository<Role> implements RoleRepository {\n constructor() {\n super(reldb, {\n table: TABLE_NAME,\n fields: ROLE_FIELDS,\n })\n }\n\n /** 根据角色代码查找角色 */\n async findByCode(code: string, tx?: DmlWithTxOperations): Promise<HaiResult<Role | null>> {\n return this.findOneBy('code = ?', [code], tx)\n }\n\n private buildQueryError(error: { message: string }, cause: unknown): HaiResult<never> {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryRoleFailed', { params: { message: error.message } }),\n cause,\n )\n }\n\n private async findOneBy(where: string, params: unknown[], tx?: DmlWithTxOperations): Promise<HaiResult<Role | null>> {\n const result = await this.findAll({ where, params, limit: 1 }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error, result.error)\n }\n return ok(result.data[0] ?? null)\n }\n}\n","/**\n * @h-ai/iam — 授权子功能工厂(RBAC)\n *\n * 提供角色/权限的 CRUD、用户角色分配、权限检查等能力。\n * @module iam-authz-functions\n */\n\nimport type { HaiResult, PaginatedResult, PaginationOptionsInput } from '@h-ai/core'\nimport type { DmlWithTxOperations } from '@h-ai/reldb'\n\nimport type { IamConfig, RbacConfig } from '../iam-config.js'\nimport type { SessionFieldUpdates, SessionOperations } from '../session/iam-session-types.js'\nimport type { PermissionRepository } from './iam-authz-repository-permission.js'\nimport type { RolePermissionRepository, UserRoleRepository } from './iam-authz-repository-relation.js'\nimport type { RoleRepository } from './iam-authz-repository-role.js'\nimport type {\n AuthzOperations,\n Permission,\n PermissionQueryOptions,\n Role,\n} from './iam-authz-types.js'\n\nimport { audit } from '@h-ai/audit'\nimport { core, err, ok } from '@h-ai/core'\nimport { reldb } from '@h-ai/reldb'\n\nimport { RbacConfigSchema } from '../iam-config.js'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { createDbPermissionRepository } from './iam-authz-repository-permission.js'\nimport { createDbRolePermissionRepository, createDbUserRoleRepository } from './iam-authz-repository-relation.js'\nimport { createDbRoleRepository } from './iam-authz-repository-role.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'authz' })\n\n// ─── 子功能依赖 ───\n\n/**\n * 授权子功能依赖\n */\nexport interface AuthzOperationsDeps {\n config: IamConfig\n session: SessionOperations\n}\n\n/**\n * 创建授权子功能\n *\n * 内部创建 RBAC 所需的存储层,返回授权管理接口。\n */\nexport async function createAuthzOperations(deps: AuthzOperationsDeps): Promise<HaiResult<AuthzOperations>> {\n try {\n const { config, session } = deps\n\n const roleRepository = await createDbRoleRepository()\n const permissionRepository = await createDbPermissionRepository()\n\n const rolePermResult = await createDbRolePermissionRepository()\n if (!rolePermResult.success) {\n return rolePermResult\n }\n\n const userRoleResult = await createDbUserRoleRepository(roleRepository)\n if (!userRoleResult.success) {\n return userRoleResult\n }\n\n const manager = createRbacManager({\n rbacConfig: config.rbac,\n roleRepository,\n permissionRepository,\n rolePermissionRepository: rolePermResult.data,\n userRoleRepository: userRoleResult.data,\n session,\n })\n\n logger.info('Authz sub-feature initialized')\n return ok(manager)\n }\n catch (error) {\n logger.error('Authz sub-feature initialization failed', { error })\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_initComponentFailed'),\n error,\n )\n }\n}\n\n// ─── 内部实现 ───\n\n/**\n * RBAC 管理器内部配置\n */\ninterface RbacManagerConfig {\n rbacConfig?: RbacConfig\n roleRepository: RoleRepository\n permissionRepository: PermissionRepository\n rolePermissionRepository: RolePermissionRepository\n userRoleRepository: UserRoleRepository\n session: SessionOperations\n}\n\n/**\n * 创建 RBAC 授权管理器\n *\n * 提供角色/权限的 CRUD、用户角色分配、权限检查等能力。\n * 内置超级管理员角色识别:超管角色自动拥有所有权限。\n *\n * @param config - RBAC 配置和存储层依赖\n * @returns 授权管理器接口实现\n */\nfunction createRbacManager(config: RbacManagerConfig): AuthzOperations {\n const rbacConfig = config.rbacConfig\n ? RbacConfigSchema.parse(config.rbacConfig)\n : RbacConfigSchema.parse({})\n\n const {\n roleRepository,\n permissionRepository,\n rolePermissionRepository,\n userRoleRepository,\n session,\n } = config\n\n let superAdminRoleId: string | null | undefined\n\n /**\n * 解析超级管理员角色 ID\n *\n * 首次调用时从数据库查询,之后缓存结果。\n *\n * @returns 超管角色 ID,或 null(未配置时)\n */\n async function resolveSuperAdminRoleId(): Promise<HaiResult<string | null>> {\n if (superAdminRoleId !== undefined) {\n return ok(superAdminRoleId)\n }\n\n const roleResult = await roleRepository.findByCode(rbacConfig.superAdminRole)\n if (!roleResult.success) {\n return mapRepositoryError('iam_queryRoleFailed', roleResult.error.message) as HaiResult<string | null>\n }\n\n superAdminRoleId = roleResult.data?.id ?? null\n return ok(superAdminRoleId)\n }\n\n /**\n * 构建存储层错误响应\n *\n * @param messageKey - i18n 消息键\n * @param message - 原始错误消息\n */\n function mapRepositoryError(messageKey: Parameters<typeof iamM>[0], message: string) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM(messageKey, { params: { message } }),\n )\n }\n\n /**\n * 判断权限代码是否匹配指定权限\n *\n * 支持通配符 `*`,如 `user:*` 匹配 `user:read`、`user:write`。\n *\n * @param permission - 要检查的权限\n * @param code - 角色拥有的权限代码\n * @returns 匹配返回 true\n */\n function matchesPermission(permission: string, code: string): boolean {\n if (code === permission) {\n return true\n }\n\n if (code.endsWith(':*')) {\n const prefix = code.slice(0, -1)\n return permission.startsWith(prefix)\n }\n\n return false\n }\n\n /**\n * 批量查询多个角色的权限代码,并判断是否匹配指定权限\n */\n async function hasPermissionInRoles(roleIds: string[], permission: string): Promise<HaiResult<boolean>> {\n const codesResult = await rolePermissionRepository.getPermissionCodesForRoles(roleIds)\n if (!codesResult.success)\n return codesResult as HaiResult<boolean>\n\n for (const code of codesResult.data) {\n if (matchesPermission(permission, code))\n return ok(true)\n }\n\n return ok(false)\n }\n\n /**\n * 获取用户所有权限(通过角色聚合,批量 JOIN 查询避免 N+1)\n */\n async function getUserPermissionsInternal(userId: string): Promise<HaiResult<Permission[]>> {\n const roleIdsResult = await userRoleRepository.getRoleIds(userId)\n if (!roleIdsResult.success)\n return roleIdsResult as HaiResult<Permission[]>\n if (roleIdsResult.data.length === 0)\n return ok([])\n\n const permMapResult = await rolePermissionRepository.getPermissionsForRoles(roleIdsResult.data)\n if (!permMapResult.success)\n return permMapResult as HaiResult<Permission[]>\n\n const permissions: Permission[] = []\n const seen = new Set<string>()\n for (const perms of permMapResult.data.values()) {\n for (const perm of perms) {\n if (!seen.has(perm.id)) {\n permissions.push(perm)\n seen.add(perm.id)\n }\n }\n }\n\n return ok(permissions)\n }\n\n /**\n * 解析用户所有权限 code(通过角色聚合)\n *\n * 用于会话权限同步:查用户角色 → 单次 JOIN 查询权限 code → 去重。\n */\n async function resolveUserPermissionCodes(userId: string): Promise<HaiResult<string[]>> {\n const roleIdsResult = await userRoleRepository.getRoleIds(userId)\n if (!roleIdsResult.success) {\n return roleIdsResult as HaiResult<string[]>\n }\n if (roleIdsResult.data.length === 0) {\n return ok([])\n }\n\n return rolePermissionRepository.getPermissionCodesForRoles(roleIdsResult.data)\n }\n\n /**\n * 解析用户所有角色 code\n *\n * 用于会话角色同步:查用户角色 → 提取 code。\n */\n async function resolveUserRoleCodes(userId: string): Promise<HaiResult<string[]>> {\n const rolesResult = await userRoleRepository.getRoles(userId)\n if (!rolesResult.success) {\n return rolesResult as HaiResult<string[]>\n }\n return ok(rolesResult.data.map(r => r.code))\n }\n\n /**\n * 角色权限变更后,同步所有持有该角色用户的 session permissions\n *\n * 最大努力:单用户同步失败仅记录日志,不阻塞其他用户。\n *\n * @param roleId - 发生权限变更的角色 ID\n */\n async function syncSessionPermissionsForRole(roleId: string): Promise<void> {\n const userIdsResult = await userRoleRepository.getUserIdsByRoleId(roleId)\n if (!userIdsResult.success) {\n logger.error('Failed to query users for permission sync', { roleId, error: userIdsResult.error.message })\n return\n }\n\n // 并行同步所有受影响用户的会话权限,避免 await-in-loop\n await Promise.allSettled(\n userIdsResult.data.map(async (userId) => {\n const permResult = await resolveUserPermissionCodes(userId)\n if (!permResult.success) {\n logger.error('Failed to resolve permissions for session sync', { userId, roleId, error: permResult.error.message })\n return\n }\n\n const syncResult = await session.patchUserSessions(userId, { permissions: permResult.data })\n if (!syncResult.success) {\n logger.error('Failed to sync session permissions', { userId, roleId, error: syncResult.error.message })\n }\n }),\n )\n }\n\n /**\n * 用户角色变更后,统一同步会话中的角色和权限\n *\n * 并行解析角色/权限 code,一次调用 patchUserSessions 写入。\n * 最大努力:解析或写入失败仅记录日志。\n *\n * @param userId - 受影响的用户 ID\n */\n async function syncUserSessionAfterRoleChange(userId: string): Promise<void> {\n const [roleCodesResult, permCodesResult] = await Promise.all([\n resolveUserRoleCodes(userId),\n resolveUserPermissionCodes(userId),\n ])\n\n const updates: SessionFieldUpdates = {}\n if (roleCodesResult.success) {\n updates.roles = roleCodesResult.data\n }\n else {\n logger.error('Failed to resolve roles for session sync', { userId, error: roleCodesResult.error.message })\n }\n if (permCodesResult.success) {\n updates.permissions = permCodesResult.data\n }\n else {\n logger.error('Failed to resolve permissions for session sync', { userId, error: permCodesResult.error.message })\n }\n\n if (updates.roles !== undefined || updates.permissions !== undefined) {\n const syncResult = await session.patchUserSessions(userId, updates)\n if (!syncResult.success) {\n logger.error('Failed to patch user sessions', { userId, error: syncResult.error.message })\n }\n }\n }\n\n return {\n async checkPermission(userId: string, permission: string): Promise<HaiResult<boolean>> {\n // RBAC 未启用时,所有权限检查直接放行\n if (!rbacConfig.enabled) {\n return ok(true)\n }\n const roleIdsResult = await userRoleRepository.getRoleIds(userId)\n if (!roleIdsResult.success)\n return roleIdsResult as HaiResult<boolean>\n\n const roleIds = roleIdsResult.data\n\n // 无角色用户直接返回 false,跳过超管解析和权限查询\n if (roleIds.length === 0) {\n return ok(false)\n }\n\n const superAdminResult = await resolveSuperAdminRoleId()\n if (!superAdminResult.success)\n return superAdminResult as HaiResult<boolean>\n\n // 超级管理员拥有所有权限\n if (superAdminResult.data && roleIds.includes(superAdminResult.data)) {\n return ok(true)\n }\n\n // 查询所有角色的权限并匹配\n return hasPermissionInRoles(roleIds, permission)\n },\n\n async getUserPermissions(userId: string): Promise<HaiResult<Permission[]>> {\n return getUserPermissionsInternal(userId)\n },\n\n async getUserRoles(userId: string): Promise<HaiResult<Role[]>> {\n return userRoleRepository.getRoles(userId)\n },\n\n async assignRole(userId: string, roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const roleExistsResult = await roleRepository.existsById(roleId, tx)\n if (!roleExistsResult.success) {\n return mapRepositoryError('iam_queryRoleFailed', roleExistsResult.error.message) as HaiResult<void>\n }\n if (!roleExistsResult.data) {\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n\n const result = await userRoleRepository.assign(userId, roleId, tx)\n if (result.success) {\n logger.info('Role assigned to user', { userId, roleId })\n void audit.log({ action: 'role.assign', resource: 'iam_user_role', resourceId: userId, details: { roleId } })\n // 仅在非外部事务时同步会话(外部事务由调用方在 commit 后同步)\n if (!tx) {\n await syncUserSessionAfterRoleChange(userId)\n }\n }\n return result\n },\n\n async removeRole(userId: string, roleId: string, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const result = await userRoleRepository.remove(userId, roleId, tx)\n if (result.success) {\n logger.info('Role removed from user', { userId, roleId })\n void audit.log({ action: 'role.remove', resource: 'iam_user_role', resourceId: userId, details: { roleId } })\n // 仅在非外部事务时同步会话(外部事务由调用方在 commit 后同步)\n if (!tx) {\n await syncUserSessionAfterRoleChange(userId)\n }\n }\n return result\n },\n\n async syncRoles(userId: string, roleIds: string[], tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const currentResult = await userRoleRepository.getRoles(userId, tx)\n if (!currentResult.success) {\n return currentResult as HaiResult<void>\n }\n\n const currentIds = new Set(currentResult.data.map(r => r.id))\n const targetIds = new Set(roleIds)\n\n const toRemove = [...currentIds].filter(id => !targetIds.has(id))\n const toAdd = [...targetIds].filter(id => !currentIds.has(id))\n\n // 无变化时直接返回\n if (toRemove.length === 0 && toAdd.length === 0) {\n return ok(undefined)\n }\n\n // 验证新增角色存在性\n for (const roleId of toAdd) {\n const existsResult = await roleRepository.existsById(roleId, tx)\n if (!existsResult.success) {\n return mapRepositoryError('iam_queryRoleFailed', existsResult.error.message) as HaiResult<void>\n }\n if (!existsResult.data) {\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n }\n\n // 使用调用方事务或创建新事务,保证批量操作原子性\n const ownTx = !tx\n if (!tx) {\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_syncRolesFailed', txResult.error.message) as HaiResult<void>\n }\n tx = txResult.data\n }\n\n try {\n // 批量移除\n for (const roleId of toRemove) {\n const result = await userRoleRepository.remove(userId, roleId, tx)\n if (!result.success) {\n if (ownTx)\n await tx.rollback()\n return result\n }\n }\n\n // 批量添加\n for (const roleId of toAdd) {\n const result = await userRoleRepository.assign(userId, roleId, tx)\n if (!result.success) {\n if (ownTx)\n await tx.rollback()\n return result\n }\n }\n\n if (ownTx) {\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_syncRolesFailed', commitResult.error.message) as HaiResult<void>\n }\n }\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_syncRolesFailed', { params: { message: String(error) } }),\n error,\n )\n }\n\n logger.info('Roles synced for user', { userId, added: toAdd.length, removed: toRemove.length })\n void audit.log({ action: 'roles.sync', resource: 'iam_user_role', resourceId: userId, details: { added: toAdd, removed: toRemove } })\n\n // 事务提交后统一同步会话角色和权限\n if (ownTx) {\n await syncUserSessionAfterRoleChange(userId)\n }\n\n return ok(undefined)\n },\n\n // ─── 角色管理 ───\n\n async createRole(role, tx?: DmlWithTxOperations): Promise<HaiResult<Role>> {\n // 使用调用方事务或创建新事务,保证 create+findByCode 原子性\n const ownTx = !tx\n if (!tx) {\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_createRoleFailed', txResult.error.message) as HaiResult<Role>\n }\n tx = txResult.data\n }\n\n try {\n const createResult = await roleRepository.create(role, tx)\n if (!createResult.success) {\n if (ownTx)\n await tx.rollback()\n const msg = createResult.error.message.toLowerCase()\n if (msg.includes('unique') || msg.includes('duplicate')) {\n return err(HaiIamError.ROLE_ALREADY_EXISTS, iamM('iam_roleAlreadyExist'))\n }\n return mapRepositoryError('iam_createRoleFailed', createResult.error.message) as HaiResult<Role>\n }\n\n const createdResult = await roleRepository.findByCode(role.code, tx)\n if (!createdResult.success) {\n if (ownTx)\n await tx.rollback()\n return mapRepositoryError('iam_queryRoleFailed', createdResult.error.message) as HaiResult<Role>\n }\n if (!createdResult.data) {\n if (ownTx)\n await tx.rollback()\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n\n if (ownTx) {\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_createRoleFailed', commitResult.error.message) as HaiResult<Role>\n }\n }\n\n logger.info('Role created', { roleId: createdResult.data.id, code: role.code })\n void audit.helper.crud({ action: 'create', resource: 'iam_role', resourceId: createdResult.data.id, details: { code: role.code } })\n\n // 创建的角色可能是超管角色,强制下次 checkPermission 重新解析\n if (role.code === rbacConfig.superAdminRole) {\n superAdminRoleId = undefined\n }\n\n return ok(createdResult.data)\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\n const msg = String(error).toLowerCase()\n if (msg.includes('unique') || msg.includes('duplicate')) {\n return err(HaiIamError.ROLE_ALREADY_EXISTS, iamM('iam_roleAlreadyExist'))\n }\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createRoleFailed', { params: { message: String(error) } }),\n error,\n )\n }\n },\n\n async getRole(roleId): Promise<HaiResult<Role | null>> {\n const result = await roleRepository.findById(roleId)\n if (!result.success) {\n return mapRepositoryError('iam_queryRoleFailed', result.error.message) as HaiResult<Role | null>\n }\n return ok(result.data)\n },\n\n async getRoleByCode(code): Promise<HaiResult<Role | null>> {\n const result = await roleRepository.findByCode(code)\n if (!result.success) {\n return mapRepositoryError('iam_queryRoleFailed', result.error.message) as HaiResult<Role | null>\n }\n return ok(result.data)\n },\n\n async getAllRoles(options?: PaginationOptionsInput): Promise<HaiResult<PaginatedResult<Role>>> {\n const result = await roleRepository.findPage({\n orderBy: 'created_at DESC',\n pagination: options,\n })\n if (!result.success) {\n return mapRepositoryError('iam_queryRoleListFailed', result.error.message) as HaiResult<PaginatedResult<Role>>\n }\n return ok(result.data)\n },\n\n async updateRole(roleId, data, tx?: DmlWithTxOperations): Promise<HaiResult<Role>> {\n // 使用调用方事务或创建新事务,保证 update+findById 原子性\n const ownTx = !tx\n if (!tx) {\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_updateRoleFailed', txResult.error.message) as HaiResult<Role>\n }\n tx = txResult.data\n }\n\n try {\n const updateResult = await roleRepository.updateById(roleId, data, tx)\n if (!updateResult.success) {\n if (ownTx)\n await tx.rollback()\n return mapRepositoryError('iam_updateRoleFailed', updateResult.error.message) as HaiResult<Role>\n }\n if (updateResult.data.changes === 0) {\n if (ownTx)\n await tx.rollback()\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n\n const updatedResult = await roleRepository.findById(roleId, tx)\n if (!updatedResult.success) {\n if (ownTx)\n await tx.rollback()\n return mapRepositoryError('iam_queryRoleFailed', updatedResult.error.message) as HaiResult<Role>\n }\n if (!updatedResult.data) {\n if (ownTx)\n await tx.rollback()\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n\n if (ownTx) {\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_updateRoleFailed', commitResult.error.message) as HaiResult<Role>\n }\n }\n\n // 角色代码可能变更,强制下次 checkPermission 重新解析超管角色\n superAdminRoleId = undefined\n\n // 角色代码变更后同步受影响用户的会话(仅在自管事务时,外部事务由调用方在 commit 后同步)\n if (ownTx) {\n const affectedUsersResult = await userRoleRepository.getUserIdsByRoleId(roleId)\n if (affectedUsersResult.success) {\n for (const userId of affectedUsersResult.data) {\n await syncUserSessionAfterRoleChange(userId)\n }\n }\n else {\n logger.error('Failed to query affected users after updateRole', { roleId, error: affectedUsersResult.error.message })\n }\n }\n\n void audit.helper.crud({ action: 'update', resource: 'iam_role', resourceId: roleId, details: data as Record<string, unknown> })\n\n return ok(updatedResult.data)\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_updateRoleFailed', { params: { message: String(error) } }),\n error,\n )\n }\n },\n\n async deleteRole(roleId, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n // 校验角色存在且非系统角色\n const roleResult = await roleRepository.findById(roleId, tx)\n if (!roleResult.success) {\n return mapRepositoryError('iam_queryRoleFailed', roleResult.error.message) as HaiResult<void>\n }\n if (!roleResult.data) {\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n if (roleResult.data.isSystem) {\n return err(HaiIamError.PERMISSION_DENIED, iamM('iam_cannotDeleteSystemRole'))\n }\n\n // 使用调用方事务或创建新事务,保证级联删除原子执行\n const ownTx = !tx\n if (!tx) {\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_deleteRoleFailed', txResult.error.message) as HaiResult<void>\n }\n tx = txResult.data\n }\n\n let affectedUserIds: string[] = []\n try {\n // 级联删除:用户-角色关联\n const userIdsResult = await userRoleRepository.removeByRoleId(roleId, tx)\n if (!userIdsResult.success) {\n if (ownTx)\n await tx.rollback()\n return userIdsResult as HaiResult<void>\n }\n affectedUserIds = userIdsResult.data\n\n // 级联删除:角色-权限关联\n const rpResult = await rolePermissionRepository.removeByRoleId(roleId, tx)\n if (!rpResult.success) {\n if (ownTx)\n await tx.rollback()\n return rpResult\n }\n\n // 删除角色本身\n const delResult = await roleRepository.deleteById(roleId, tx)\n if (!delResult.success) {\n if (ownTx)\n await tx.rollback()\n return mapRepositoryError('iam_deleteRoleFailed', delResult.error.message) as HaiResult<void>\n }\n\n if (ownTx) {\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_deleteRoleFailed', commitResult.error.message) as HaiResult<void>\n }\n }\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_deleteRoleFailed', { params: { message: String(error) } }),\n error,\n )\n }\n\n // 事务提交后:会话同步(仅在自管事务时,外部事务由调用方在 commit 后同步)\n if (ownTx) {\n for (const userId of affectedUserIds) {\n await syncUserSessionAfterRoleChange(userId)\n }\n }\n\n // 强制下次 checkPermission 重新解析超管角色\n superAdminRoleId = undefined\n\n logger.info('Role deleted', { roleId })\n void audit.helper.crud({ action: 'delete', resource: 'iam_role', resourceId: roleId })\n return ok(undefined)\n },\n\n // ─── 权限管理 ───\n\n async createPermission(permission, tx?: DmlWithTxOperations): Promise<HaiResult<Permission>> {\n // 使用调用方事务或创建新事务,保证 create+findByCode 原子性\n const ownTx = !tx\n if (!tx) {\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_createPermissionFailed', txResult.error.message) as HaiResult<Permission>\n }\n tx = txResult.data\n }\n\n try {\n const createResult = await permissionRepository.create(permission, tx)\n if (!createResult.success) {\n if (ownTx)\n await tx.rollback()\n const msg = createResult.error.message.toLowerCase()\n if (msg.includes('unique') || msg.includes('duplicate')) {\n return err(HaiIamError.PERMISSION_ALREADY_EXISTS, iamM('iam_permissionAlreadyExist'))\n }\n return mapRepositoryError('iam_createPermissionFailed', createResult.error.message) as HaiResult<Permission>\n }\n\n const createdResult = await permissionRepository.findByCode(permission.code, tx)\n if (!createdResult.success) {\n if (ownTx)\n await tx.rollback()\n return mapRepositoryError('iam_queryPermissionFailed', createdResult.error.message) as HaiResult<Permission>\n }\n if (!createdResult.data) {\n if (ownTx)\n await tx.rollback()\n return err(HaiIamError.PERMISSION_NOT_FOUND, iamM('iam_permissionNotExist'))\n }\n\n if (ownTx) {\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_createPermissionFailed', commitResult.error.message) as HaiResult<Permission>\n }\n }\n\n logger.info('Permission created', { permissionId: createdResult.data.id, code: permission.code })\n void audit.helper.crud({ action: 'create', resource: 'iam_permission', resourceId: createdResult.data.id, details: { code: permission.code } })\n return ok(createdResult.data)\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\n const msg = String(error).toLowerCase()\n if (msg.includes('unique') || msg.includes('duplicate')) {\n return err(HaiIamError.PERMISSION_ALREADY_EXISTS, iamM('iam_permissionAlreadyExist'))\n }\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_createPermissionFailed', { params: { message: String(error) } }),\n error,\n )\n }\n },\n\n async getPermission(permissionId): Promise<HaiResult<Permission | null>> {\n const result = await permissionRepository.findById(permissionId)\n if (!result.success) {\n return mapRepositoryError('iam_queryPermissionFailed', result.error.message) as HaiResult<Permission | null>\n }\n return ok(result.data)\n },\n\n async getPermissionByCode(code): Promise<HaiResult<Permission | null>> {\n const result = await permissionRepository.findByCode(code)\n if (!result.success) {\n return mapRepositoryError('iam_queryPermissionFailed', result.error.message) as HaiResult<Permission | null>\n }\n return ok(result.data)\n },\n\n async getAllPermissions(options?: PermissionQueryOptions): Promise<HaiResult<PaginatedResult<Permission>>> {\n const whereClauses: string[] = []\n const whereParams: unknown[] = []\n\n if (options?.type) {\n whereClauses.push('type = ?')\n whereParams.push(options.type)\n }\n\n if (options?.search) {\n whereClauses.push('(code LIKE ? OR name LIKE ?)')\n const escaped = options.search.replace(/[%_\\\\]/g, '\\\\$&')\n const pattern = `%${escaped}%`\n whereParams.push(pattern, pattern)\n }\n\n const result = await permissionRepository.findPage({\n where: whereClauses.length > 0 ? whereClauses.join(' AND ') : undefined,\n params: whereParams.length > 0 ? whereParams : undefined,\n orderBy: 'created_at DESC',\n pagination: options,\n })\n if (!result.success) {\n return mapRepositoryError('iam_queryPermissionListFailed', result.error.message) as HaiResult<PaginatedResult<Permission>>\n }\n return ok(result.data)\n },\n\n async deletePermission(permissionId, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n const permissionResult = await permissionRepository.findById(permissionId, tx)\n if (!permissionResult.success) {\n return mapRepositoryError('iam_queryPermissionFailed', permissionResult.error.message) as HaiResult<void>\n }\n if (!permissionResult.data) {\n return err(\n HaiIamError.PERMISSION_NOT_FOUND,\n iamM('iam_permissionNotExist'),\n )\n }\n\n // 事务前:从 DB 查询哪些角色关联此权限(事务中会删除关联行)\n const affectedRoleIdsResult = await rolePermissionRepository.getRoleIdsByPermissionId(permissionId)\n const affectedRoleIds = affectedRoleIdsResult.success ? affectedRoleIdsResult.data : []\n\n // 使用调用方事务或创建新事务,保证级联删除原子执行\n const ownTx = !tx\n if (!tx) {\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_deletePermissionFailed', txResult.error.message) as HaiResult<void>\n }\n tx = txResult.data\n }\n\n try {\n // 级联删除:角色-权限关联\n const cascadeResult = await rolePermissionRepository.removeByPermissionId(permissionId, tx)\n if (!cascadeResult.success) {\n if (ownTx)\n await tx.rollback()\n return cascadeResult\n }\n\n // 删除权限本身\n const delResult = await permissionRepository.deleteById(permissionId, tx)\n if (!delResult.success) {\n if (ownTx)\n await tx.rollback()\n return mapRepositoryError('iam_deletePermissionFailed', delResult.error.message) as HaiResult<void>\n }\n\n if (ownTx) {\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_deletePermissionFailed', commitResult.error.message) as HaiResult<void>\n }\n }\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_deletePermissionFailed', { params: { message: String(error) } }),\n error,\n )\n }\n\n // 事务提交后:会话同步(仅在自管事务时,外部事务由调用方在 commit 后同步)\n if (ownTx) {\n for (const roleId of affectedRoleIds) {\n await syncSessionPermissionsForRole(roleId)\n }\n }\n\n logger.info('Permission deleted', { permissionId })\n void audit.helper.crud({ action: 'delete', resource: 'iam_permission', resourceId: permissionId })\n return ok(undefined)\n },\n\n async assignPermissionToRole(roleId, permissionId, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n // 检查角色和权限是否存在\n const [roleResult, permResult] = await Promise.all([\n roleRepository.existsById(roleId, tx),\n permissionRepository.findById(permissionId, tx),\n ])\n\n if (!roleResult.success) {\n return mapRepositoryError('iam_queryRoleFailed', roleResult.error.message) as HaiResult<void>\n }\n if (!roleResult.data) {\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n\n if (!permResult.success) {\n return mapRepositoryError('iam_queryPermissionFailed', permResult.error.message) as HaiResult<void>\n }\n if (!permResult.data) {\n return err(HaiIamError.PERMISSION_NOT_FOUND, iamM('iam_permissionNotExist'))\n }\n\n const assignResult = await rolePermissionRepository.assign(roleId, permissionId, tx)\n if (assignResult.success) {\n logger.info('Permission assigned to role', { roleId, permissionId })\n void audit.log({ action: 'permission.assign', resource: 'iam_role_permission', resourceId: roleId, details: { permissionId } })\n // 仅在非外部事务时同步会话(外部事务由调用方在 commit 后同步)\n if (!tx) {\n await syncSessionPermissionsForRole(roleId)\n }\n }\n return assignResult\n },\n\n async removePermissionFromRole(roleId, permissionId, tx?: DmlWithTxOperations): Promise<HaiResult<void>> {\n // 检查角色和权限是否存在\n const [roleResult, permResult] = await Promise.all([\n roleRepository.existsById(roleId, tx),\n permissionRepository.findById(permissionId, tx),\n ])\n\n if (!roleResult.success) {\n return mapRepositoryError('iam_queryRoleFailed', roleResult.error.message) as HaiResult<void>\n }\n if (!roleResult.data) {\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n }\n\n if (!permResult.success) {\n return mapRepositoryError('iam_queryPermissionFailed', permResult.error.message) as HaiResult<void>\n }\n if (!permResult.data) {\n return err(\n HaiIamError.PERMISSION_NOT_FOUND,\n iamM('iam_permissionNotExist'),\n )\n }\n\n const removeResult = await rolePermissionRepository.remove(roleId, permissionId, tx)\n if (removeResult.success) {\n logger.info('Permission removed from role', { roleId, permissionId })\n void audit.log({ action: 'permission.remove', resource: 'iam_role_permission', resourceId: roleId, details: { permissionId } })\n // 仅在非外部事务时同步会话(外部事务由调用方在 commit 后同步)\n if (!tx) {\n await syncSessionPermissionsForRole(roleId)\n }\n }\n return removeResult\n },\n\n async getRolePermissions(roleId): Promise<HaiResult<Permission[]>> {\n return rolePermissionRepository.getPermissions(roleId)\n },\n\n async getUserRolesForMany(userIds): Promise<HaiResult<Map<string, Role[]>>> {\n return userRoleRepository.getRolesForUsers(userIds)\n },\n\n async getRolePermissionsForMany(roleIds): Promise<HaiResult<Map<string, Permission[]>>> {\n return rolePermissionRepository.getPermissionsForRoles(roleIds)\n },\n }\n}\n","/**\n * @h-ai/iam — 种子数据初始化\n *\n * 通过 authz 子功能 API 初始化默认角色、权限和角色-权限关联。\n * 重复执行时跳过已存在的数据,确保幂等性。\n * @module iam-seed\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type { PermissionType } from './authz/iam-authz-types.js'\n\nimport type { AuthzOperations } from './iam-types.js'\n\nimport { core, err, ok } from '@h-ai/core'\n\nimport { iamM } from './iam-i18n.js'\nimport { HaiIamError } from './iam-types.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'seed' })\n\n// ─── 默认角色定义 ───\n\n/** 默认角色(名称通过 i18n 获取) */\nconst DEFAULT_ROLES = [\n { code: 'admin', name: () => iamM('iam_seedRoleAdminName'), description: () => iamM('iam_seedRoleAdminDesc'), isSystem: true },\n { code: 'user', name: () => iamM('iam_seedRoleUserName'), description: () => iamM('iam_seedRoleUserDesc'), isSystem: true },\n { code: 'guest', name: () => iamM('iam_seedRoleGuestName'), description: () => iamM('iam_seedRoleGuestDesc'), isSystem: true },\n]\n\n/** 默认权限(名称通过 i18n 获取),按类型分组 */\nconst DEFAULT_PERMISSIONS: Array<{\n code: string\n name: () => string\n type: PermissionType\n resource: string\n action: string\n}> = [\n // ─── 菜单权限 ───\n { code: 'dashboard:view', name: () => iamM('iam_seedPermDashboardView'), type: 'menu', resource: 'dashboard', action: 'view' },\n { code: 'user:read', name: () => iamM('iam_seedPermUserRead'), type: 'menu', resource: 'user', action: 'read' },\n { code: 'role:read', name: () => iamM('iam_seedPermRoleRead'), type: 'menu', resource: 'role', action: 'read' },\n { code: 'permission:read', name: () => iamM('iam_seedPermPermRead'), type: 'menu', resource: 'permission', action: 'read' },\n { code: 'system:logs', name: () => iamM('iam_seedPermSystemLogs'), type: 'menu', resource: 'system', action: 'logs' },\n { code: 'system:settings', name: () => iamM('iam_seedPermSystemSettings'), type: 'menu', resource: 'system', action: 'settings' },\n { code: 'system:modules', name: () => iamM('iam_seedPermSystemModules'), type: 'menu', resource: 'system', action: 'modules' },\n { code: 'profile:read', name: () => iamM('iam_seedPermProfileRead'), type: 'menu', resource: 'profile', action: 'read' },\n\n // ─── API 权限 ───\n { code: 'user:list', name: () => iamM('iam_seedPermUserList'), type: 'api', resource: 'user', action: 'list' },\n { code: 'user:api:create', name: () => iamM('iam_seedPermUserApiCreate'), type: 'api', resource: 'user', action: 'api:create' },\n { code: 'user:api:update', name: () => iamM('iam_seedPermUserApiUpdate'), type: 'api', resource: 'user', action: 'api:update' },\n { code: 'user:api:delete', name: () => iamM('iam_seedPermUserApiDelete'), type: 'api', resource: 'user', action: 'api:delete' },\n { code: 'role:list', name: () => iamM('iam_seedPermRoleList'), type: 'api', resource: 'role', action: 'list' },\n { code: 'role:api:create', name: () => iamM('iam_seedPermRoleApiCreate'), type: 'api', resource: 'role', action: 'api:create' },\n { code: 'role:api:update', name: () => iamM('iam_seedPermRoleApiUpdate'), type: 'api', resource: 'role', action: 'api:update' },\n { code: 'role:api:delete', name: () => iamM('iam_seedPermRoleApiDelete'), type: 'api', resource: 'role', action: 'api:delete' },\n { code: 'permission:list', name: () => iamM('iam_seedPermPermList'), type: 'api', resource: 'permission', action: 'list' },\n { code: 'permission:manage', name: () => iamM('iam_seedPermPermManage'), type: 'api', resource: 'permission', action: 'manage' },\n { code: 'permission:api:create', name: () => iamM('iam_seedPermPermApiCreate'), type: 'api', resource: 'permission', action: 'api:create' },\n { code: 'permission:api:delete', name: () => iamM('iam_seedPermPermApiDelete'), type: 'api', resource: 'permission', action: 'api:delete' },\n { code: 'audit:read', name: () => iamM('iam_seedPermAuditRead'), type: 'api', resource: 'audit', action: 'read' },\n\n // ─── 按钮权限 ───\n { code: 'user:create', name: () => iamM('iam_seedPermUserCreate'), type: 'button', resource: 'user', action: 'create' },\n { code: 'user:update', name: () => iamM('iam_seedPermUserUpdate'), type: 'button', resource: 'user', action: 'update' },\n { code: 'user:delete', name: () => iamM('iam_seedPermUserDelete'), type: 'button', resource: 'user', action: 'delete' },\n { code: 'role:create', name: () => iamM('iam_seedPermRoleCreate'), type: 'button', resource: 'role', action: 'create' },\n { code: 'role:update', name: () => iamM('iam_seedPermRoleUpdate'), type: 'button', resource: 'role', action: 'update' },\n { code: 'role:delete', name: () => iamM('iam_seedPermRoleDelete'), type: 'button', resource: 'role', action: 'delete' },\n { code: 'permission:create', name: () => iamM('iam_seedPermPermCreate'), type: 'button', resource: 'permission', action: 'create' },\n { code: 'permission:delete', name: () => iamM('iam_seedPermPermDelete'), type: 'button', resource: 'permission', action: 'delete' },\n]\n\n/** 普通用户(user)角色默认权限代码列表 */\nconst USER_ROLE_PERMISSIONS = ['dashboard:view', 'profile:read']\n\n// ─── 种子函数 ───\n\n/**\n * 执行种子数据初始化(幂等)\n *\n * 通过 authz 子功能 API 初始化默认角色、权限和角色-权限关联。\n * 重复执行时跳过已存在的数据,确保幂等性。\n *\n * @param authz - 已初始化的授权子功能实例\n * @returns 成功返回 ok(undefined);失败返回 REPOSITORY_ERROR\n */\nexport async function seedIamData(\n authz: AuthzOperations,\n): Promise<HaiResult<void>> {\n try {\n // 查询现有角色,避免重复创建\n const existingRoles = await authz.getAllRoles({ page: 1, pageSize: 1000 })\n const existingRoleMap = new Map<string, string>()\n if (existingRoles.success) {\n for (const role of existingRoles.data.items) {\n existingRoleMap.set(role.code, role.id)\n }\n }\n\n const roleMap = new Map<string, string>()\n for (const role of DEFAULT_ROLES) {\n const existingId = existingRoleMap.get(role.code)\n if (existingId) {\n roleMap.set(role.code, existingId)\n continue\n }\n const result = await authz.createRole({ code: role.code, name: role.name(), description: role.description(), isSystem: role.isSystem })\n if (result.success) {\n roleMap.set(role.code, result.data.id)\n }\n else {\n return result as HaiResult<void>\n }\n }\n\n // 查询现有权限,避免重复创建\n const existingPerms = await authz.getAllPermissions({ page: 1, pageSize: 1000 })\n const existingPermMap = new Map<string, string>()\n if (existingPerms.success) {\n for (const perm of existingPerms.data.items) {\n existingPermMap.set(perm.code, perm.id)\n }\n }\n\n const permMap = new Map<string, string>()\n for (const perm of DEFAULT_PERMISSIONS) {\n const existingId = existingPermMap.get(perm.code)\n if (existingId) {\n permMap.set(perm.code, existingId)\n continue\n }\n const result = await authz.createPermission({ code: perm.code, name: perm.name(), type: perm.type, resource: perm.resource, action: perm.action })\n if (result.success) {\n permMap.set(perm.code, result.data.id)\n }\n else {\n return result as HaiResult<void>\n }\n }\n\n // 管理员分配所有权限\n const adminRoleId = roleMap.get('admin')\n if (adminRoleId) {\n for (const [, permId] of permMap) {\n await authz.assignPermissionToRole(adminRoleId, permId)\n }\n }\n\n // 普通用户(user)分配基础权限(仪表盘 + 个人中心)\n const userRoleId = roleMap.get('user')\n if (userRoleId) {\n for (const permCode of USER_ROLE_PERMISSIONS) {\n const permId = permMap.get(permCode)\n if (permId) {\n await authz.assignPermissionToRole(userRoleId, permId)\n }\n }\n }\n\n // 访客(guest)不分配任何权限\n\n logger.info('IAM seed data initialized')\n return ok(undefined)\n }\n catch (error) {\n logger.error('Failed to seed IAM data', { error })\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_initSeedDataFailed'),\n error,\n )\n }\n}\n","/**\n * @h-ai/iam — 会话工具函数\n * @module iam-session-utils\n */\n\nimport type { CreateSessionOptions, Session } from './iam-session-types.js'\n\n/**\n * 生成访问令牌\n *\n * 使用 256 位(32 字节)加密安全随机数,编码为 base64url 格式。\n * 相比 UUID v4(122 位),提供更高的熵值和抗碰撞能力。\n *\n * @returns base64url 编码的 256 位随机令牌\n */\nexport function generateToken(): string {\n const bytes = new Uint8Array(32)\n crypto.getRandomValues(bytes)\n // base64url 编码(RFC 4648 §5)\n const base64 = btoa(String.fromCharCode(...bytes))\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n/**\n * 构建会话数据\n *\n * @param options - 创建会话选项(用户 ID、角色等)\n * @param now - 当前时间\n * @param sessionTtl - 会话有效期(秒)\n * @param accessToken - 访问令牌\n * @returns 完整的 Session 对象\n */\nexport function buildSession(options: CreateSessionOptions, now: Date, sessionTtl: number, accessToken: string): Session {\n return {\n userId: options.userId,\n username: options.username,\n displayName: options.displayName,\n avatarUrl: options.avatarUrl,\n roles: options.roles ?? [],\n permissions: options.permissions ?? [],\n source: options.source,\n accessToken,\n createdAt: now,\n lastActiveAt: now,\n expiresAt: new Date(now.getTime() + sessionTtl * 1000),\n data: options.data,\n }\n}\n\n/**\n * 计算会话剩余 TTL\n *\n * @param session - 会话对象\n * @param now - 当前时间戳(毫秒,默认 Date.now())\n * @returns 剩余秒数,最小为 0\n */\nexport function getSessionTtl(session: Session, now = Date.now()): number {\n return Math.max(0, Math.floor((session.expiresAt.getTime() - now) / 1000))\n}\n\n/**\n * 应用会话更新\n *\n * 将 patch 中的字段合并到现有会话,同时更新 lastActiveAt。\n * data 字段采用浅合并策略。\n *\n * @param session - 原始会话\n * @param patch - 要更新的字段\n * @returns 更新后的新会话对象(不修改原对象)\n */\nexport function applySessionPatch(session: Session, patch: Partial<Session>): Session {\n const nextSession = { ...session }\n if (patch.data !== undefined) {\n nextSession.data = { ...nextSession.data, ...patch.data }\n }\n if (patch.roles !== undefined) {\n nextSession.roles = patch.roles\n }\n if (patch.permissions !== undefined) {\n nextSession.permissions = patch.permissions\n }\n if (patch.username !== undefined) {\n nextSession.username = patch.username\n }\n if (patch.displayName !== undefined) {\n nextSession.displayName = patch.displayName\n }\n if (patch.avatarUrl !== undefined) {\n nextSession.avatarUrl = patch.avatarUrl\n }\n if (patch.source !== undefined) {\n nextSession.source = patch.source\n }\n nextSession.lastActiveAt = new Date()\n return nextSession\n}\n","/**\n * @h-ai/iam — 会话缓存存储实现\n *\n * 基于 @h-ai/cache 的会话存储,统一管理三组缓存键:\n * - `hai:iam:token:{accessToken}` → Session(含 _tokenPair)\n * - `hai:iam:user:{userId}:tokens` → Set\\<accessToken\\>\n * - `hai:iam:refresh:{refreshToken}` → { userId, accessToken }\n *\n * @module iam-session-repository-cache\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { Session, TokenPair } from './iam-session-types.js'\nimport { cache } from '@h-ai/cache'\nimport { err, ok } from '@h-ai/core'\n\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { applySessionPatch, getSessionTtl } from './iam-session-utils.js'\n\n// ─── 缓存键前缀 ───\n\nconst TOKEN_KEY_PREFIX = 'hai:iam:token:'\nconst USER_TOKENS_KEY_PREFIX = 'hai:iam:user:'\nconst REFRESH_TOKEN_PREFIX = 'hai:iam:refresh:'\n\n/**\n * 构建令牌对应的缓存 key\n *\n * @param token - 访问令牌\n * @returns 格式:`hai:iam:token:{token}`\n */\nexport function buildTokenKey(token: string): string {\n return `${TOKEN_KEY_PREFIX}${token}`\n}\n\n/**\n * 构建用户令牌集合的缓存 key\n *\n * @param userId - 用户 ID\n * @returns 格式:`hai:iam:user:{userId}:tokens`\n */\nexport function buildUserTokensKey(userId: string): string {\n return `${USER_TOKENS_KEY_PREFIX}${userId}:tokens`\n}\n\nfunction buildRefreshKey(refreshToken: string): string {\n return `${REFRESH_TOKEN_PREFIX}${refreshToken}`\n}\n\n/**\n * 修复从缓存反序列化后的日期字段\n */\nfunction restoreSessionDates(session: Session): Session {\n return {\n ...session,\n createdAt: session.createdAt instanceof Date ? session.createdAt : new Date(session.createdAt),\n lastActiveAt: session.lastActiveAt instanceof Date ? session.lastActiveAt : new Date(session.lastActiveAt),\n expiresAt: session.expiresAt instanceof Date ? session.expiresAt : new Date(session.expiresAt),\n }\n}\n\n// ─── 会话存储接口 ───\n\n/**\n * 会话存储接口\n *\n * 统一管理 accessToken、userTokens、refreshToken 三组缓存键,\n * 对上层提供面向会话的操作语义。\n */\nexport interface SessionRepository {\n /**\n * 保存会话\n *\n * 同时创建三个缓存条目:\n * - accessToken → session(含 _tokenPair)\n * - userId → Set\\<accessToken\\>\n * - refreshToken → { userId, accessToken }\n *\n * @param session - 会话数据(data 中应已包含 _tokenPair)\n * @param tokenPair - 令牌对(用于存储 refreshToken 映射)\n */\n save: (session: Session, tokenPair: TokenPair) => Promise<HaiResult<void>>\n\n /**\n * 根据 accessToken 获取会话\n */\n getByAccessToken: (accessToken: string) => Promise<HaiResult<Session | null>>\n\n /**\n * 根据 accessToken 更新会话\n *\n * 合并 patch 到现有会话后写回缓存,同时保留剩余 TTL。\n *\n * @param accessToken - 访问令牌\n * @param data - 要更新的字段\n */\n updateByAccessToken: (accessToken: string, data: Partial<Session>) => Promise<HaiResult<void>>\n\n /**\n * 根据 accessToken 删除会话\n *\n * 同时清理三个缓存条目(accessToken 映射、用户令牌集合成员、refreshToken 映射)。\n */\n removeByAccessToken: (accessToken: string) => Promise<HaiResult<void>>\n\n /**\n * 删除用户的所有会话\n *\n * 遍历用户令牌集合,逐一删除关联的三个缓存条目,最后删除集合本身。\n */\n removeByUserId: (userId: string) => Promise<HaiResult<void>>\n\n /**\n * 根据 refreshToken 获取关联的会话\n *\n * 先查 refreshToken 映射获取 accessToken,再查 accessToken 获取会话。\n * 若 refreshToken 有效但 session 已过期(TTL 到期),返回 null。\n */\n getByRefreshToken: (refreshToken: string) => Promise<HaiResult<Session | null>>\n\n /**\n * 仅删除 refreshToken 映射(不影响 accessToken 会话)\n */\n removeRefreshToken: (refreshToken: string) => Promise<HaiResult<void>>\n\n /**\n * 批量更新用户所有活跃会话的指定字段\n *\n * 遍历用户令牌集合,合并 updates 到每个会话后写回缓存,\n * 同时清理已失效的令牌。\n *\n * @param userId - 用户 ID\n * @param updates - 要合并到会话的字段(如 { roles, permissions })\n */\n patchUserSessions: (userId: string, updates: Record<string, unknown>) => Promise<HaiResult<void>>\n}\n\n/**\n * 创建基于缓存的会话存储\n *\n * @param sessionMaxAge - 会话最大有效期(秒),用于设置用户令牌集合的 TTL\n * @param refreshTokenMaxAge - refreshToken 最大有效期(秒)\n * @returns 会话存储接口实现\n */\nexport function createCacheSessionRepository(\n sessionMaxAge: number,\n refreshTokenMaxAge: number,\n): SessionRepository {\n const repo: SessionRepository = {\n async save(session, tokenPair): Promise<HaiResult<void>> {\n const accessToken = session.accessToken\n const userId = session.userId\n const ttl = getSessionTtl(session)\n\n // 1. accessToken → session(带 TTL)\n const setResult = await cache.kv.set(buildTokenKey(accessToken), session, { ex: ttl })\n if (!setResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveSessionMappingCacheFailed', { params: { message: setResult.error.message } }),\n setResult.error,\n )\n }\n\n // 2. userId → Set<accessToken>\n const saddResult = await cache.set_.sadd(buildUserTokensKey(userId), accessToken)\n if (!saddResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveUserSessionCacheFailed', { params: { message: saddResult.error.message } }),\n saddResult.error,\n )\n }\n // 刷新集合 TTL(2 倍会话最大有效期,防止僵尸键)\n await cache.kv.expire(buildUserTokensKey(userId), sessionMaxAge * 2)\n\n // 3. refreshToken → { userId, accessToken }\n const refreshResult = await cache.kv.set(\n buildRefreshKey(tokenPair.refreshToken),\n { userId, accessToken },\n { ex: refreshTokenMaxAge },\n )\n if (!refreshResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveSessionMappingCacheFailed', { params: { message: refreshResult.error.message } }),\n refreshResult.error,\n )\n }\n\n return ok(undefined)\n },\n\n async getByAccessToken(accessToken): Promise<HaiResult<Session | null>> {\n const result = await cache.kv.get<Session>(buildTokenKey(accessToken))\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_querySessionMappingCacheFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n if (!result.data) {\n return ok(null)\n }\n return ok(restoreSessionDates(result.data))\n },\n\n async updateByAccessToken(accessToken, data): Promise<HaiResult<void>> {\n const sessionResult = await repo.getByAccessToken(accessToken)\n if (!sessionResult.success) {\n return sessionResult as HaiResult<void>\n }\n if (!sessionResult.data) {\n return err(\n HaiIamError.SESSION_NOT_FOUND,\n iamM('iam_sessionNotExist'),\n )\n }\n\n const nextSession = applySessionPatch(sessionResult.data, data)\n const ttl = getSessionTtl(nextSession)\n\n const setResult = await cache.kv.set(buildTokenKey(accessToken), nextSession, { ex: ttl })\n if (!setResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveSessionMappingCacheFailed', { params: { message: setResult.error.message } }),\n setResult.error,\n )\n }\n return ok(undefined)\n },\n\n async removeByAccessToken(accessToken): Promise<HaiResult<void>> {\n // 读取 session 以获取 userId 和 _tokenPair.refreshToken\n const sessionResult = await cache.kv.get<Session>(buildTokenKey(accessToken))\n if (sessionResult.success && sessionResult.data) {\n const session = sessionResult.data as Session & { data?: { _tokenPair?: TokenPair } }\n\n // 从用户令牌集合中移除\n await cache.set_.srem(buildUserTokensKey(session.userId), accessToken)\n\n // 删除 refreshToken 映射\n const tokenPair = session.data?._tokenPair\n if (tokenPair?.refreshToken) {\n await cache.kv.del(buildRefreshKey(tokenPair.refreshToken))\n }\n }\n\n // 删除 session 本身\n await cache.kv.del(buildTokenKey(accessToken))\n return ok(undefined)\n },\n\n async removeByUserId(userId): Promise<HaiResult<void>> {\n const tokensResult = await cache.set_.smembers<string>(buildUserTokensKey(userId))\n if (tokensResult.success) {\n for (const token of tokensResult.data) {\n await repo.removeByAccessToken(token)\n }\n }\n // 清理用户令牌集合本身\n await cache.kv.del(buildUserTokensKey(userId))\n return ok(undefined)\n },\n\n async getByRefreshToken(refreshToken): Promise<HaiResult<Session | null>> {\n const mappingResult = await cache.kv.get<{ userId: string, accessToken: string }>(buildRefreshKey(refreshToken))\n if (!mappingResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_querySessionMappingCacheFailed', { params: { message: mappingResult.error.message } }),\n mappingResult.error,\n )\n }\n if (!mappingResult.data) {\n return ok(null)\n }\n\n return repo.getByAccessToken(mappingResult.data.accessToken)\n },\n\n async removeRefreshToken(refreshToken): Promise<HaiResult<void>> {\n const result = await cache.kv.del(buildRefreshKey(refreshToken))\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_deleteSessionMappingCacheFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(undefined)\n },\n\n async patchUserSessions(userId, updates): Promise<HaiResult<void>> {\n const tokensResult = await cache.set_.smembers<string>(buildUserTokensKey(userId))\n if (!tokensResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryUserSessionCacheFailed', { params: { message: tokensResult.error.message } }),\n tokensResult.error,\n )\n }\n\n const staleTokens: string[] = []\n\n for (const token of tokensResult.data) {\n const sessionKey = buildTokenKey(token)\n const sessionResult = await cache.kv.get<Record<string, unknown>>(sessionKey)\n if (!sessionResult.success || !sessionResult.data) {\n staleTokens.push(token)\n continue\n }\n\n const ttlResult = await cache.kv.ttl(sessionKey)\n if (!ttlResult.success || ttlResult.data <= 0) {\n staleTokens.push(token)\n continue\n }\n\n const updated = { ...sessionResult.data, ...updates }\n const setResult = await cache.kv.set(sessionKey, updated, { ex: ttlResult.data })\n if (!setResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveUserSessionCacheFailed', { params: { message: setResult.error.message } }),\n setResult.error,\n )\n }\n }\n\n // 清理已失效的令牌\n if (staleTokens.length > 0) {\n await cache.set_.srem(buildUserTokensKey(userId), ...staleTokens)\n }\n\n return ok(undefined)\n },\n }\n\n return repo\n}\n","/**\n * @h-ai/iam — 会话子功能工厂\n *\n * 基于缓存存储的会话实现:创建、查询、验证、更新、删除。\n * @module iam-session-functions\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { IamConfig } from '../iam-config.js'\nimport type { SessionRepository } from './iam-session-repository-cache.js'\nimport type { CreateSessionOptions, Session, SessionOperations, TokenPair } from './iam-session-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { SessionConfigSchema } from '../iam-config.js'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { createCacheSessionRepository } from './iam-session-repository-cache.js'\nimport { buildSession, generateToken } from './iam-session-utils.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'session' })\n\n// ─── 子功能依赖 ───\n\n/**\n * 会话子功能依赖\n */\nexport interface SessionOperationsDeps {\n config: IamConfig\n}\n\n/**\n * 创建会话子功能\n *\n * 内部创建缓存会话存储,返回会话管理接口。\n */\nexport async function createSessionOperations(deps: SessionOperationsDeps): Promise<HaiResult<SessionOperations>> {\n try {\n const { config } = deps\n const sessionConfig = SessionConfigSchema.parse(config.session ?? {})\n const sessionRepository = createCacheSessionRepository(\n sessionConfig.maxAge ?? 86400,\n sessionConfig.refreshTokenMaxAge ?? 604800,\n )\n\n const functions = buildSessionFunctions({\n maxAge: sessionConfig.maxAge,\n sliding: sessionConfig.sliding,\n singleDevice: sessionConfig.singleDevice,\n sessionRepository,\n })\n\n logger.info('Session sub-feature initialized')\n return ok(functions)\n }\n catch (error) {\n logger.error('Session sub-feature initialization failed', { error })\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_initComponentFailed'),\n error,\n )\n }\n}\n\n// ─── 内部实现 ───\n\n/**\n * 内部会话构建器配置\n */\ninterface SessionBuilderConfig {\n /** 会话最大有效期(秒,默认 86400 = 24小时) */\n maxAge?: number\n /** 是否滑动窗口 */\n sliding?: boolean\n /** 单设备登录(踢掉其他设备) */\n singleDevice?: boolean\n /** 会话存储 */\n sessionRepository: SessionRepository\n}\n\n/**\n * 组装会话操作\n */\nfunction buildSessionFunctions(config: SessionBuilderConfig): SessionOperations {\n const maxAge = config.maxAge ?? 86400\n const sliding = config.sliding ?? true\n const singleDevice = config.singleDevice ?? false\n const repo = config.sessionRepository\n\n return {\n async create(options: CreateSessionOptions): Promise<HaiResult<Session>> {\n try {\n if (singleDevice) {\n const clearResult = await repo.removeByUserId(options.userId)\n if (!clearResult.success) {\n return clearResult as HaiResult<Session>\n }\n }\n\n const accessToken = generateToken()\n const tokenPair: TokenPair = {\n accessToken,\n refreshToken: generateToken(),\n expiresIn: maxAge,\n tokenType: 'Bearer',\n }\n\n const now = new Date()\n const sessionTtl = options.maxAge ?? maxAge\n const session = buildSession(options, now, sessionTtl, accessToken)\n\n // 将 tokenPair 附加到 session 的 data 字段(持久化到缓存,logout 时可提取 refreshToken)\n session.data = { ...session.data, _tokenPair: tokenPair }\n\n const saveResult = await repo.save(session, tokenPair)\n if (!saveResult.success) {\n return saveResult as HaiResult<Session>\n }\n\n logger.debug('Session created', { userId: options.userId })\n return ok(session)\n }\n catch (error) {\n return err(\n HaiIamError.SESSION_CREATE_FAILED,\n iamM('iam_createSessionFailed'),\n error,\n )\n }\n },\n\n async get(accessToken: string): Promise<HaiResult<Session | null>> {\n const sessionResult = await repo.getByAccessToken(accessToken)\n if (!sessionResult.success) {\n return sessionResult\n }\n\n const session = sessionResult.data\n if (!session) {\n return ok(null)\n }\n\n if (new Date() > session.expiresAt) {\n await repo.removeByAccessToken(accessToken)\n return ok(null)\n }\n\n if (sliding) {\n const now = new Date()\n await repo.updateByAccessToken(accessToken, {\n lastActiveAt: now,\n expiresAt: new Date(now.getTime() + maxAge * 1000),\n })\n }\n\n return ok(session)\n },\n\n async verifyToken(accessToken: string): Promise<HaiResult<Session>> {\n const sessionResult = await this.get(accessToken)\n if (!sessionResult.success) {\n return sessionResult as HaiResult<Session>\n }\n\n if (!sessionResult.data) {\n return err(\n HaiIamError.SESSION_INVALID,\n iamM('iam_sessionExpired'),\n )\n }\n\n return ok(sessionResult.data)\n },\n\n async update(accessToken: string, data: Partial<Session>): Promise<HaiResult<void>> {\n return repo.updateByAccessToken(accessToken, data)\n },\n\n async delete(accessToken: string): Promise<HaiResult<void>> {\n logger.debug('Session deleted', { accessToken })\n return repo.removeByAccessToken(accessToken)\n },\n\n async deleteByUserId(userId: string): Promise<HaiResult<number>> {\n // removeByUserId 内部遍历删除,无法直接获取删除数量\n // 暂返回 0 表示成功;上层仅关注 success/failure\n const result = await repo.removeByUserId(userId)\n if (!result.success) {\n return result as HaiResult<number>\n }\n return ok(0)\n },\n\n async refresh(refreshToken: string): Promise<HaiResult<TokenPair>> {\n try {\n // 根据 refreshToken 获取旧会话\n const oldSessionResult = await repo.getByRefreshToken(refreshToken)\n if (!oldSessionResult.success) {\n return oldSessionResult as HaiResult<TokenPair>\n }\n\n const oldSession = oldSessionResult.data\n if (!oldSession) {\n return err(\n HaiIamError.TOKEN_EXPIRED,\n iamM('iam_refreshTokenExpired'),\n )\n }\n\n // Rotation 策略:删除旧会话(removeByAccessToken 内部同时清理 refreshToken 映射)\n await repo.removeByAccessToken(oldSession.accessToken)\n\n // 创建新会话(复用旧会话的用户数据)\n const newSessionResult = await this.create({\n userId: oldSession.userId,\n username: oldSession.username,\n displayName: oldSession.displayName,\n avatarUrl: oldSession.avatarUrl,\n roles: oldSession.roles,\n permissions: oldSession.permissions,\n source: oldSession.source,\n data: oldSession.data ? { ...oldSession.data, _tokenPair: undefined } : undefined,\n })\n\n if (!newSessionResult.success) {\n return newSessionResult as HaiResult<TokenPair>\n }\n\n // 从新会话中提取 tokenPair\n const tokenPair = newSessionResult.data.data?._tokenPair\n if (!tokenPair) {\n return err(\n HaiIamError.TOKEN_REFRESH_FAILED,\n iamM('iam_refreshTokenFailed'),\n )\n }\n\n logger.debug('Token refreshed', { userId: oldSession.userId })\n return ok(tokenPair)\n }\n catch (error) {\n return err(\n HaiIamError.TOKEN_REFRESH_FAILED,\n iamM('iam_refreshTokenFailed'),\n error,\n )\n }\n },\n\n async revokeRefresh(refreshToken: string): Promise<HaiResult<void>> {\n return repo.removeRefreshToken(refreshToken)\n },\n\n async patchUserSessions(userId, updates): Promise<HaiResult<void>> {\n return repo.patchUserSessions(userId, { ...updates })\n },\n }\n}\n","/**\n * @h-ai/iam — 密码重置令牌存储实现\n *\n * 基于 @h-ai/cache 的密码重置令牌存储,采用两个缓存键实现令牌验证与尝试次数限制:\n * - `hai:iam:reset:{hashedToken}` → userId(带 TTL 自动过期)\n * - `hai:iam:reset:attempts:{userId}` → 尝试次数(带 TTL 自动过期)\n *\n * @module iam-user-repository-reset-token\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport { cache } from '@h-ai/cache'\nimport { err, ok } from '@h-ai/core'\nimport { crypto as haiCrypto } from '@h-ai/crypto'\n\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n/**\n * 对令牌进行 SHA-256 哈希\n *\n * 缓存中只存储令牌的哈希值,不存储明文。\n * 查询时也先哈希再匹配。\n *\n * @param token - 明文令牌\n * @returns 十六进制 SHA-256 哈希值,失败时返回 IamError\n */\nexport function hashResetToken(token: string): HaiResult<string> {\n const result = haiCrypto.hash.hash(token)\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_hashResetTokenFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n return ok(result.data)\n}\n\n/**\n * 密码重置令牌存储接口\n */\nexport interface ResetTokenRepository {\n /**\n * 保存重置令牌\n *\n * 存储 hashedToken → userId 映射(带 TTL),并重置用户尝试次数。\n *\n * @param token - 明文令牌\n * @param userId - 用户 ID\n * @param expiresAt - 过期时间\n */\n saveToken: (token: string, userId: string, expiresAt: Date) => Promise<HaiResult<void>>\n\n /**\n * 根据令牌获取用户 ID,同时递增尝试次数\n *\n * 自动检查尝试次数是否超限。超限时删除令牌并返回 RESET_TOKEN_MAX_ATTEMPTS 错误。\n * 令牌不存在或已过期(TTL 到期自动清理)返回 RESET_TOKEN_INVALID 错误。\n *\n * @param token - 明文令牌\n * @param maxAttempts - 最大允许尝试次数\n * @returns 成功返回 userId\n */\n tryGetUserByToken: (token: string, maxAttempts: number) => Promise<HaiResult<string>>\n\n /**\n * 删除令牌及关联的尝试次数\n *\n * @param token - 明文令牌\n */\n removeToken: (token: string) => Promise<HaiResult<void>>\n}\n\n// ─── 缓存键构建 ───\n\n/** 令牌缓存键前缀:hashedToken → userId */\nconst RESET_TOKEN_KEY_PREFIX = 'hai:iam:reset:'\n\n/** 用户尝试次数键前缀:userId → attempts */\nconst RESET_ATTEMPTS_KEY_PREFIX = 'hai:iam:reset:attempts:'\n\nfunction buildResetTokenKey(hashedToken: string): string {\n return `${RESET_TOKEN_KEY_PREFIX}${hashedToken}`\n}\n\nfunction buildAttemptsKey(userId: string): string {\n return `${RESET_ATTEMPTS_KEY_PREFIX}${userId}`\n}\n\n// ─── 缓存实现 ───\n\n/** 令牌存储单例缓存 */\nlet resetTokenRepoInstance: ResetTokenRepository | null = null\n\n/**\n * 重置令牌存储单例\n *\n * 在 iam.close() 时调用,释放对旧 cache 实例的引用。\n */\nexport function resetResetTokenRepoSingleton(): void {\n resetTokenRepoInstance = null\n}\n\n/**\n * 创建基于缓存的密码重置令牌存储实例\n *\n * 单例模式:重复调用返回缓存实例。\n *\n * @returns 密码重置令牌存储接口实现\n */\nexport function createCacheResetTokenRepository(): ResetTokenRepository {\n if (resetTokenRepoInstance)\n return resetTokenRepoInstance\n\n const repo: ResetTokenRepository = {\n async saveToken(token, userId, expiresAt): Promise<HaiResult<void>> {\n const hashResult = hashResetToken(token)\n if (!hashResult.success) {\n return hashResult\n }\n const hashedToken = hashResult.data\n const ttlSeconds = Math.max(1, Math.ceil((expiresAt.getTime() - Date.now()) / 1000))\n\n // 存储 hashedToken → userId(带 TTL)\n const setResult = await cache.kv.set(buildResetTokenKey(hashedToken), userId, { ex: ttlSeconds })\n if (!setResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveResetTokenFailed', { params: { message: setResult.error.message } }),\n setResult.error,\n )\n }\n\n // 重置尝试次数(与令牌相同 TTL)\n const attemptsResult = await cache.kv.set(buildAttemptsKey(userId), 0, { ex: ttlSeconds })\n if (!attemptsResult.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveResetTokenFailed', { params: { message: attemptsResult.error.message } }),\n attemptsResult.error,\n )\n }\n\n return ok(undefined)\n },\n\n async tryGetUserByToken(token, maxAttempts): Promise<HaiResult<string>> {\n const hashResult = hashResetToken(token)\n if (!hashResult.success) {\n return hashResult\n }\n const hashedToken = hashResult.data\n const tokenKey = buildResetTokenKey(hashedToken)\n\n // 查找 userId\n const result = await cache.kv.get<string>(tokenKey)\n if (!result.success) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_queryResetTokenFailed', { params: { message: result.error.message } }),\n result.error,\n )\n }\n if (!result.data) {\n return err(\n HaiIamError.RESET_TOKEN_INVALID,\n iamM('iam_resetTokenInvalid'),\n )\n }\n\n const userId = result.data\n const attemptsKey = buildAttemptsKey(userId)\n\n // 原子递增尝试次数\n const incrResult = await cache.kv.incr(attemptsKey)\n const nextAttempts = incrResult.success ? incrResult.data : 1\n\n // 超限:删除令牌,返回错误\n if (nextAttempts > maxAttempts) {\n await cache.kv.del(tokenKey)\n await cache.kv.del(attemptsKey)\n return err(\n HaiIamError.RESET_TOKEN_MAX_ATTEMPTS,\n iamM('iam_resetTokenMaxAttempts'),\n )\n }\n\n return ok(userId)\n },\n\n async removeToken(token): Promise<HaiResult<void>> {\n const hashResult = hashResetToken(token)\n if (!hashResult.success) {\n return hashResult\n }\n const hashedToken = hashResult.data\n const tokenKey = buildResetTokenKey(hashedToken)\n\n // 先获取 userId 以便清理尝试次数\n const result = await cache.kv.get<string>(tokenKey)\n if (result.success && result.data) {\n await cache.kv.del(buildAttemptsKey(result.data))\n }\n\n await cache.kv.del(tokenKey)\n return ok(undefined)\n },\n }\n\n resetTokenRepoInstance = repo\n return repo\n}\n","/**\n * @h-ai/iam — 用户子功能工厂\n *\n * 提供用户管理相关操作:注册、查询、更新、密码管理等。\n * @module iam-user-functions\n */\n\nimport type { HaiResult, PaginatedResult } from '@h-ai/core'\nimport type { PasswordStrategyResult } from '../authn/password/iam-authn-password-strategy.js'\nimport type { AuthzOperations } from '../authz/iam-authz-types.js'\nimport type { IamConfig } from '../iam-config.js'\nimport type { SessionOperations } from '../session/iam-session-types.js'\nimport type { ResetTokenRepository } from './iam-user-repository-reset-token.js'\nimport type { UserRepository } from './iam-user-repository-user.js'\nimport type {\n AgreementDisplay,\n ListUsersOptions,\n RegisterOptions,\n RegisterResult,\n UpdateCurrentUserInput,\n User,\n UserOperations,\n} from './iam-user-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { crypto } from '@h-ai/crypto'\nimport { reldb } from '@h-ai/reldb'\n\nimport { AgreementConfigSchema, PasswordResetConfigSchema, RegisterConfigSchema } from '../iam-config.js'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { createCacheResetTokenRepository } from './iam-user-repository-reset-token.js'\nimport { createDbUserRepository } from './iam-user-repository-user.js'\nimport { toUser } from './iam-user-utils.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'user' })\n\n// ─── 子功能依赖 ───\n\n/**\n * 用户子功能依赖\n */\nexport interface UserOperationsDeps {\n config: IamConfig\n passwordStrategyResult: PasswordStrategyResult\n sessionFunctions: SessionOperations\n authzFunctions: AuthzOperations\n /** 密码重置令牌回调(由业务层注入) */\n onPasswordResetRequest?: (user: User, token: string, expiresAt: Date) => Promise<void>\n}\n\n/**\n * 创建用户子功能\n *\n * 内部创建用户存储,组装用户管理操作接口。\n */\nexport async function createUserOperations(deps: UserOperationsDeps): Promise<HaiResult<UserOperations>> {\n try {\n const { config, passwordStrategyResult, sessionFunctions, authzFunctions, onPasswordResetRequest } = deps\n\n const userRepository = await createDbUserRepository()\n const resetTokenRepository = createCacheResetTokenRepository()\n\n const functions = buildUserFunctions({\n userRepository,\n resetTokenRepository,\n passwordStrategyResult,\n sessionFunctions,\n authzFunctions,\n config,\n onPasswordResetRequest,\n })\n\n logger.info('User sub-feature initialized')\n return ok(functions)\n }\n catch (error) {\n logger.error('User sub-feature initialization failed', { error })\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_initComponentFailed'),\n error,\n )\n }\n}\n\n// ─── 纯工具函数 ───\n\n/**\n * 判断更新数据中是否包含有效字段\n *\n * @param data - 用户更新数据\n * @returns 包含至少一个非 undefined 字段返回 true\n */\nfunction hasUpdateFields(data: Partial<User>): boolean {\n return Object.values(data).some(value => value !== undefined)\n}\n\n/**\n * 构建存储层错误响应\n *\n * @param messageKey - i18n 消息键\n * @param message - 原始错误消息\n * @returns 包含 REPOSITORY_ERROR 码的错误 HaiResult\n */\nfunction mapRepositoryError(messageKey: Parameters<typeof iamM>[0], message: string) {\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM(messageKey, { params: { message } }),\n )\n}\n\n/**\n * 将底层更新错误转换为领域层 IAM 错误。\n *\n * @param message 底层错误消息\n * @returns 领域层错误结果\n */\nfunction mapUpdateErrorAsDomainError(message: string): HaiResult<never> {\n const loweredMessage = message.toLowerCase()\n if (loweredMessage.includes('unique') || loweredMessage.includes('duplicate')) {\n return err(\n HaiIamError.USER_ALREADY_EXISTS,\n iamM('iam_userAlreadyExist'),\n )\n }\n\n return mapRepositoryError('iam_updateUserFailed', message)\n}\n\n/**\n * 更新用户前校验用户名和邮箱唯一性。\n *\n * @param userRepository - 用户仓库\n * @param userId - 用户 ID\n * @param data - 待更新用户字段\n * @returns 唯一性校验结果\n */\nasync function validateUniqueFieldsForUpdate(\n userRepository: UserRepository,\n userId: string,\n data: Partial<User>,\n): Promise<HaiResult<void>> {\n const currentResult = await userRepository.findById(userId)\n if (!currentResult.success) {\n return mapRepositoryError('iam_queryUserFailed', currentResult.error.message) as HaiResult<void>\n }\n if (!currentResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n if (data.username && data.username !== currentResult.data.username) {\n const usernameExistsResult = await userRepository.existsByUsername(data.username)\n if (!usernameExistsResult.success) {\n return mapRepositoryError('iam_queryUserFailed', usernameExistsResult.error.message) as HaiResult<void>\n }\n if (usernameExistsResult.data) {\n return err(\n HaiIamError.USER_ALREADY_EXISTS,\n iamM('iam_usernameAlreadyExist'),\n )\n }\n }\n\n if (data.email && data.email !== currentResult.data.email) {\n const emailExistsResult = await userRepository.existsByEmail(data.email)\n if (!emailExistsResult.success) {\n return mapRepositoryError('iam_queryUserFailed', emailExistsResult.error.message) as HaiResult<void>\n }\n if (emailExistsResult.data) {\n return err(\n HaiIamError.USER_ALREADY_EXISTS,\n iamM('iam_emailAlreadyUsed'),\n )\n }\n }\n\n return ok(undefined)\n}\n\n// ─── 内部实现 ───\n\n/**\n * 子功能构建器共享上下文\n */\ninterface UserFnContext {\n userRepository: UserRepository\n resetTokenRepository: ResetTokenRepository\n validatePassword: (password: string) => HaiResult<void>\n hashPassword: (password: string) => HaiResult<string>\n sessionFunctions: SessionOperations\n authzFunctions: AuthzOperations\n config: IamConfig\n registerConfig: { enabled: boolean, defaultEnabled: boolean }\n agreementConfig: { showOnRegister: boolean, showOnLogin: boolean, userAgreementUrl?: string, privacyPolicyUrl?: string }\n onPasswordResetRequest?: (user: User, token: string, expiresAt: Date) => Promise<void>\n}\n\n// ─── 注册操作 ───\n\n/**\n * 构建用户注册相关操作\n */\nfunction buildRegistrationOps(ctx: UserFnContext): Pick<UserOperations, 'register' | 'validatePassword'> {\n const { userRepository, authzFunctions, config, registerConfig, agreementConfig } = ctx\n const { validatePassword, hashPassword } = ctx\n\n /**\n * 校验注册前置条件\n */\n async function validateRegisterPreconditions(options: RegisterOptions): Promise<HaiResult<void>> {\n if (!registerConfig.enabled) {\n return err(\n HaiIamError.REGISTER_DISABLED,\n iamM('iam_registerDisabled'),\n )\n }\n\n const validateResult = validatePassword(options.password)\n if (!validateResult.success)\n return validateResult\n\n const existsResult = await userRepository.existsByUsername(options.username)\n if (existsResult.success && existsResult.data) {\n return err(\n HaiIamError.USER_ALREADY_EXISTS,\n iamM('iam_usernameAlreadyExist'),\n )\n }\n\n if (options.email) {\n const emailExistsResult = await userRepository.existsByEmail(options.email)\n if (emailExistsResult.success && emailExistsResult.data) {\n return err(\n HaiIamError.USER_ALREADY_EXISTS,\n iamM('iam_emailAlreadyUsed'),\n )\n }\n }\n\n return ok(undefined)\n }\n\n /**\n * 构建注册页协议展示信息\n */\n function buildAgreementDisplay(): AgreementDisplay | undefined {\n if (!agreementConfig.showOnRegister)\n return undefined\n if (!agreementConfig.userAgreementUrl && !agreementConfig.privacyPolicyUrl)\n return undefined\n return {\n userAgreementUrl: agreementConfig.userAgreementUrl,\n privacyPolicyUrl: agreementConfig.privacyPolicyUrl,\n showOnRegister: agreementConfig.showOnRegister,\n showOnLogin: agreementConfig.showOnLogin,\n }\n }\n\n /**\n * 为新用户分配默认角色\n */\n async function assignDefaultRole(userId: string): Promise<void> {\n if (!config.rbac?.defaultRole)\n return\n const roleResult = await authzFunctions.getRoleByCode(config.rbac.defaultRole)\n if (roleResult.success && roleResult.data) {\n await authzFunctions.assignRole(userId, roleResult.data.id)\n }\n }\n\n return {\n async register(options: RegisterOptions): Promise<HaiResult<RegisterResult>> {\n // 校验前置条件\n const preResult = await validateRegisterPreconditions(options)\n if (!preResult.success)\n return preResult as HaiResult<RegisterResult>\n\n // 哈希密码\n const hashResult = hashPassword(options.password)\n if (!hashResult.success)\n return hashResult as HaiResult<RegisterResult>\n\n // 事务:创建用户\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_createUserFailed', txResult.error.message) as HaiResult<RegisterResult>\n }\n const tx = txResult.data\n\n const createResult = await userRepository.create({\n username: options.username,\n email: options.email,\n phone: options.phone,\n displayName: options.displayName,\n enabled: registerConfig.defaultEnabled,\n emailVerified: false,\n phoneVerified: false,\n passwordHash: hashResult.data,\n passwordUpdatedAt: new Date(),\n metadata: options.metadata,\n }, tx)\n\n if (!createResult.success) {\n await tx.rollback()\n return mapUpdateErrorAsDomainError(createResult.error.message) as HaiResult<RegisterResult>\n }\n\n const createdUserResult = await userRepository.findByUsername(options.username, tx)\n if (!createdUserResult.success || !createdUserResult.data) {\n await tx.rollback()\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_createUserFailed', commitResult.error.message) as HaiResult<RegisterResult>\n }\n\n const createdUser = createdUserResult.data\n\n // 分配默认角色(事务外,失败不影响注册结果)\n await assignDefaultRole(createdUser.id)\n\n logger.info('User registered', { userId: createdUser.id, username: options.username })\n return ok({\n user: toUser(createdUser),\n agreements: buildAgreementDisplay(),\n })\n },\n\n validatePassword(password: string): HaiResult<void> {\n return validatePassword(password)\n },\n }\n}\n\n// ─── 查询操作 ───\n\n/**\n * 构建用户查询操作\n */\nfunction buildUserQueryOps(ctx: UserFnContext): Pick<UserOperations, 'getCurrentUser' | 'getUser' | 'listUsers'> {\n const { userRepository, sessionFunctions, authzFunctions } = ctx\n\n return {\n async getCurrentUser(accessToken: string): Promise<HaiResult<User>> {\n const verifyResult = await sessionFunctions.verifyToken(accessToken)\n if (!verifyResult.success) {\n return verifyResult as HaiResult<User>\n }\n\n const userResult = await userRepository.findById(verifyResult.data.userId)\n if (!userResult.success) {\n return mapRepositoryError('iam_queryUserFailed', userResult.error.message) as HaiResult<User>\n }\n\n if (!userResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n return ok(toUser(userResult.data))\n },\n\n async getUser(userId: string, options?: { include?: ('roles')[] }): Promise<HaiResult<User | null>> {\n const userResult = await userRepository.findById(userId)\n if (!userResult.success) {\n return mapRepositoryError('iam_queryUserFailed', userResult.error.message) as HaiResult<User | null>\n }\n\n if (!userResult.data) {\n return ok(null)\n }\n\n const user = toUser(userResult.data)\n\n if (options?.include?.includes('roles')) {\n const rolesResult = await authzFunctions.getUserRoles(userId)\n if (rolesResult.success) {\n user.roles = rolesResult.data\n }\n }\n\n return ok(user)\n },\n\n async listUsers(options?: ListUsersOptions): Promise<HaiResult<PaginatedResult<User>>> {\n const conditions: string[] = []\n const params: unknown[] = []\n\n if (options?.search) {\n // 转义 LIKE 通配符,防止用户输入 % 或 _ 产生非预期匹配\n const escaped = options.search.replace(/[%_\\\\]/g, '\\\\$&')\n const keyword = `%${escaped}%`\n conditions.push('(username LIKE ? OR email LIKE ? OR phone LIKE ? OR display_name LIKE ?)')\n params.push(keyword, keyword, keyword, keyword)\n }\n\n if (options?.enabled !== undefined) {\n conditions.push('enabled = ?')\n params.push(options.enabled ? 1 : 0)\n }\n\n const where = conditions.length > 0 ? conditions.join(' AND ') : undefined\n\n const usersResult = await userRepository.findPage({\n where,\n params: params.length > 0 ? params : undefined,\n orderBy: 'created_at DESC',\n pagination: options ? { page: options.page, pageSize: options.pageSize } : undefined,\n })\n if (!usersResult.success) {\n return mapRepositoryError('iam_queryUserListFailed', usersResult.error.message) as HaiResult<PaginatedResult<User>>\n }\n\n const items = usersResult.data.items.map(toUser)\n\n if (options?.include?.includes('roles') && items.length > 0) {\n const userIds = items.map(u => u.id)\n const rolesMapResult = await authzFunctions.getUserRolesForMany(userIds)\n if (rolesMapResult.success) {\n for (const user of items) {\n user.roles = rolesMapResult.data.get(user.id) ?? []\n }\n }\n }\n\n return ok({\n items,\n total: usersResult.data.total,\n page: usersResult.data.page,\n pageSize: usersResult.data.pageSize,\n })\n },\n }\n}\n\n// ─── 变更操作 ───\n\n/**\n * 构建用户变更操作(更新、删除)\n */\nfunction buildUserMutationOps(ctx: UserFnContext): Pick<UserOperations, 'updateCurrentUser' | 'updateUser' | 'deleteUser'> {\n const { userRepository, sessionFunctions, authzFunctions } = ctx\n\n return {\n async updateCurrentUser(accessToken: string, data: UpdateCurrentUserInput): Promise<HaiResult<User>> {\n const verifyResult = await sessionFunctions.verifyToken(accessToken)\n if (!verifyResult.success) {\n return verifyResult as HaiResult<User>\n }\n\n const userId = verifyResult.data.userId\n\n // 提取白名单字段,防止修改安全字段\n const safeData: Partial<User> = {}\n if (data.username !== undefined)\n safeData.username = data.username\n if (data.email !== undefined)\n safeData.email = data.email\n if (data.displayName !== undefined)\n safeData.displayName = data.displayName\n if (data.avatarUrl !== undefined)\n safeData.avatarUrl = data.avatarUrl\n if (data.phone !== undefined)\n safeData.phone = data.phone\n if (data.metadata !== undefined)\n safeData.metadata = data.metadata\n\n if (!hasUpdateFields(safeData)) {\n const currentResult = await userRepository.findById(userId)\n if (!currentResult.success) {\n return mapRepositoryError('iam_queryUserFailed', currentResult.error.message) as HaiResult<User>\n }\n if (!currentResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n return ok(toUser(currentResult.data))\n }\n\n const uniqueResult = await validateUniqueFieldsForUpdate(userRepository, userId, safeData)\n if (!uniqueResult.success) {\n return uniqueResult as HaiResult<User>\n }\n\n const updateResult = await userRepository.updateById(userId, safeData)\n if (!updateResult.success) {\n return mapUpdateErrorAsDomainError(updateResult.error.message) as HaiResult<User>\n }\n\n if (updateResult.data.changes === 0) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n const updatedResult = await userRepository.findById(userId)\n if (!updatedResult.success) {\n return mapRepositoryError('iam_queryUserFailed', updatedResult.error.message) as HaiResult<User>\n }\n if (!updatedResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n return ok(toUser(updatedResult.data))\n },\n\n async updateUser(userId: string, data: Partial<User>): Promise<HaiResult<User>> {\n if (!hasUpdateFields(data)) {\n const currentResult = await userRepository.findById(userId)\n if (!currentResult.success) {\n return mapRepositoryError('iam_queryUserFailed', currentResult.error.message) as HaiResult<User>\n }\n if (!currentResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n return ok(toUser(currentResult.data))\n }\n\n const uniqueResult = await validateUniqueFieldsForUpdate(userRepository, userId, data)\n if (!uniqueResult.success) {\n return uniqueResult as HaiResult<User>\n }\n\n const updateResult = await userRepository.updateById(userId, data)\n if (!updateResult.success) {\n return mapUpdateErrorAsDomainError(updateResult.error.message) as HaiResult<User>\n }\n\n if (updateResult.data.changes === 0) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n // 禁用用户时注销所有活跃会话\n if (data.enabled === false) {\n await sessionFunctions.deleteByUserId(userId)\n }\n\n const updatedResult = await userRepository.findById(userId)\n if (!updatedResult.success) {\n return mapRepositoryError('iam_queryUserFailed', updatedResult.error.message) as HaiResult<User>\n }\n if (!updatedResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n return ok(toUser(updatedResult.data))\n },\n\n async deleteUser(userId: string): Promise<HaiResult<void>> {\n logger.debug('Deleting user', { userId })\n\n const userResult = await userRepository.findById(userId)\n if (!userResult.success) {\n return mapRepositoryError('iam_queryUserFailed', userResult.error.message) as HaiResult<void>\n }\n if (!userResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n const txResult = await reldb.tx.begin()\n if (!txResult.success) {\n return mapRepositoryError('iam_deleteUserFailed', txResult.error.message) as HaiResult<void>\n }\n const tx = txResult.data\n\n try {\n // 通过 authz 子模块清理用户角色关联\n const syncResult = await authzFunctions.syncRoles(userId, [], tx)\n if (!syncResult.success) {\n await tx.rollback()\n return mapRepositoryError('iam_deleteUserFailed', syncResult.error.message) as HaiResult<void>\n }\n\n // 删除用户记录\n const deleteResult = await userRepository.deleteById(userId, tx)\n if (!deleteResult.success) {\n await tx.rollback()\n return mapRepositoryError('iam_deleteUserFailed', deleteResult.error.message) as HaiResult<void>\n }\n\n const commitResult = await tx.commit()\n if (!commitResult.success) {\n return mapRepositoryError('iam_deleteUserFailed', commitResult.error.message) as HaiResult<void>\n }\n }\n catch (error) {\n await tx.rollback()\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_deleteUserFailed', { params: { message: String(error) } }),\n error,\n )\n }\n\n // 事务提交后:最佳努力清理会话\n await sessionFunctions.deleteByUserId(userId)\n\n logger.info('User deleted', { userId })\n return ok(undefined)\n },\n }\n}\n\n// ─── 密码变更操作 ───\n\n/**\n * 构建密码变更操作(管理员重置、用户改密)\n */\nfunction buildPasswordChangeOps(ctx: UserFnContext): Pick<UserOperations, 'adminResetPassword' | 'changePassword' | 'changeCurrentUserPassword'> {\n const { userRepository, sessionFunctions } = ctx\n const { validatePassword, hashPassword } = ctx\n\n return {\n async adminResetPassword(userId: string, newPassword: string): Promise<HaiResult<void>> {\n logger.debug('Admin resetting user password', { userId })\n\n const userResult = await userRepository.findById(userId)\n if (!userResult.success) {\n return mapRepositoryError('iam_queryUserFailed', userResult.error.message) as HaiResult<void>\n }\n if (!userResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n const validateResult = validatePassword(newPassword)\n if (!validateResult.success)\n return validateResult\n\n const hashResult = hashPassword(newPassword)\n if (!hashResult.success)\n return hashResult as HaiResult<void>\n\n const updateResult = await userRepository.updateById(userId, {\n passwordHash: hashResult.data,\n passwordUpdatedAt: new Date(),\n })\n if (!updateResult.success) {\n return mapRepositoryError('iam_updateUserFailed', updateResult.error.message)\n }\n\n // 密码重置后注销该用户所有活跃会话\n await sessionFunctions.deleteByUserId(userId)\n\n logger.info('Admin reset password', { userId })\n return ok(undefined)\n },\n\n async changePassword(userId: string, oldPassword: string, newPassword: string): Promise<HaiResult<void>> {\n // 获取用户\n const userResult = await userRepository.findById(userId)\n if (!userResult.success) {\n return mapRepositoryError('iam_queryUserFailed', userResult.error.message) as HaiResult<void>\n }\n if (!userResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n const user = userResult.data\n\n // 验证旧密码\n if (!user.passwordHash) {\n return err(\n HaiIamError.INVALID_CREDENTIALS,\n iamM('iam_accountNoPassword'),\n )\n }\n\n const verifyResult = crypto.password.verify(oldPassword, user.passwordHash)\n if (!verifyResult.success || !verifyResult.data) {\n return err(\n HaiIamError.INVALID_CREDENTIALS,\n iamM('iam_originalPasswordWrong'),\n )\n }\n\n // 验证新密码强度\n const validateResult = validatePassword(newPassword)\n if (!validateResult.success)\n return validateResult\n\n // 哈希新密码\n const hashResult = hashPassword(newPassword)\n if (!hashResult.success)\n return hashResult as HaiResult<void>\n\n // 更新密码\n const updateResult = await userRepository.updateById(userId, {\n passwordHash: hashResult.data,\n passwordUpdatedAt: new Date(),\n })\n if (!updateResult.success) {\n return mapRepositoryError('iam_updateUserFailed', updateResult.error.message)\n }\n\n // 密码修改后注销该用户所有活跃会话\n await sessionFunctions.deleteByUserId(userId)\n\n logger.info('Password changed', { userId })\n return ok(undefined)\n },\n\n /**\n * 通过访问令牌定位当前用户并执行改密。\n *\n * @param accessToken 访问令牌\n * @param oldPassword 原密码\n * @param newPassword 新密码\n * @returns 改密执行结果\n */\n async changeCurrentUserPassword(accessToken: string, oldPassword: string, newPassword: string): Promise<HaiResult<void>> {\n const verifyResult = await sessionFunctions.verifyToken(accessToken)\n if (!verifyResult.success) {\n return verifyResult as HaiResult<void>\n }\n\n return this.changePassword(verifyResult.data.userId, oldPassword, newPassword)\n },\n }\n}\n\n// ─── 密码重置操作 ───\n\n/**\n * 构建密码重置操作(请求重置、确认重置)\n */\nfunction buildPasswordResetOps(ctx: UserFnContext): Pick<UserOperations, 'requestPasswordReset' | 'confirmPasswordReset'> {\n const { userRepository, resetTokenRepository, sessionFunctions, config, onPasswordResetRequest } = ctx\n const { validatePassword, hashPassword } = ctx\n\n return {\n async requestPasswordReset(identifier: string): Promise<HaiResult<void>> {\n logger.debug('Password reset requested', { identifier })\n\n const resetConfig = PasswordResetConfigSchema.parse(config.passwordReset ?? {})\n\n // 根据标识符查找用户\n const userResult = await userRepository.findByIdentifier(identifier)\n if (!userResult.success) {\n // 防止用户枚举:无论是否查找失败都返回 ok\n logger.warn('Failed to look up user for password reset', { identifier })\n return ok(undefined)\n }\n if (!userResult.data) {\n // 防止用户枚举:用户不存在也返回 ok\n logger.debug('User not found for password reset, returning ok to prevent enumeration', { identifier })\n return ok(undefined)\n }\n\n const user = toUser(userResult.data)\n\n // 生成令牌\n const token = globalThis.crypto.randomUUID()\n const expiresAt = new Date(Date.now() + resetConfig.tokenExpiresIn * 1000)\n\n // 保存新令牌(saveToken 内部重置尝试次数)\n const saveResult = await resetTokenRepository.saveToken(token, user.id, expiresAt)\n if (!saveResult.success) {\n return saveResult\n }\n\n // 通过回调通知业务层(如发送邮件)\n if (onPasswordResetRequest) {\n try {\n await onPasswordResetRequest(user, token, expiresAt)\n }\n catch (callbackError) {\n logger.error('Password reset callback failed', { userId: user.id, error: callbackError })\n // 回调失败不影响令牌生成,仍返回成功\n }\n }\n else {\n logger.warn('No password reset callback configured, token will not be delivered to user', { userId: user.id })\n }\n\n logger.info('Password reset token generated', { userId: user.id })\n return ok(undefined)\n },\n\n async confirmPasswordReset(token: string, newPassword: string): Promise<HaiResult<void>> {\n logger.debug('Confirming password reset')\n\n const resetConfig = PasswordResetConfigSchema.parse(config.passwordReset ?? {})\n\n // 先验证新密码强度(不消耗尝试次数)\n const validateResult = validatePassword(newPassword)\n if (!validateResult.success)\n return validateResult\n\n // 验证令牌并获取 userId(自动递增尝试次数、超限自动删除令牌)\n const tokenResult = await resetTokenRepository.tryGetUserByToken(token, resetConfig.maxAttempts)\n if (!tokenResult.success) {\n return tokenResult as HaiResult<void>\n }\n\n const userId = tokenResult.data\n\n // 查找用户\n const userResult = await userRepository.findById(userId)\n if (!userResult.success) {\n return mapRepositoryError('iam_queryUserFailed', userResult.error.message) as HaiResult<void>\n }\n if (!userResult.data) {\n return err(\n HaiIamError.USER_NOT_FOUND,\n iamM('iam_userNotExist'),\n )\n }\n\n // 哈希新密码\n const hashResult = hashPassword(newPassword)\n if (!hashResult.success)\n return hashResult as HaiResult<void>\n\n // 更新密码\n const updateResult = await userRepository.updateById(userId, {\n passwordHash: hashResult.data,\n passwordUpdatedAt: new Date(),\n })\n if (!updateResult.success) {\n return mapRepositoryError('iam_updateUserFailed', updateResult.error.message)\n }\n\n // 删除已使用的令牌\n await resetTokenRepository.removeToken(token)\n\n // 注销该用户所有活跃会话\n await sessionFunctions.deleteByUserId(userId)\n\n logger.info('Password reset confirmed', { userId })\n return ok(undefined)\n },\n }\n}\n\n// ─── 组装 ───\n\n/**\n * 组装用户操作\n *\n * 将注册、查询、变更、密码管理四类子操作组合为统一的 UserOperations。\n */\nfunction buildUserFunctions(deps: UserBuilderDeps): UserOperations {\n const { validatePassword, hashPassword } = deps.passwordStrategyResult\n\n const ctx: UserFnContext = {\n ...deps,\n validatePassword,\n hashPassword,\n registerConfig: RegisterConfigSchema.parse(deps.config.register ?? {}),\n agreementConfig: AgreementConfigSchema.parse(deps.config.agreements ?? {}),\n }\n\n return {\n ...buildRegistrationOps(ctx),\n ...buildUserQueryOps(ctx),\n ...buildUserMutationOps(ctx),\n ...buildPasswordChangeOps(ctx),\n ...buildPasswordResetOps(ctx),\n }\n}\n\ninterface UserBuilderDeps {\n userRepository: UserRepository\n resetTokenRepository: ResetTokenRepository\n passwordStrategyResult: PasswordStrategyResult\n sessionFunctions: SessionOperations\n authzFunctions: AuthzOperations\n config: IamConfig\n onPasswordResetRequest?: (user: User, token: string, expiresAt: Date) => Promise<void>\n}\n","/**\n * @h-ai/iam — IAM 服务主入口\n *\n * 管理运行时状态、实现生命周期(init / close)、通过 get 访问器暴露子功能。\n * @module iam-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type { IamConfig } from './iam-config.js'\nimport type { ApiKeyOperations, AuthnOperations, AuthResult, AuthzOperations, IamConfigInput, IamFunctions, SessionOperations, UserOperations } from './iam-types.js'\n\nimport { cache } from '@h-ai/cache'\nimport { core, err, ok } from '@h-ai/core'\nimport { crypto } from '@h-ai/crypto'\nimport { reldb } from '@h-ai/reldb'\n\nimport { resetApiKeyRepoSingleton } from './authn/apikey/iam-authn-apikey-repository.js'\nimport { createAuthnOperations } from './authn/iam-authn-functions.js'\nimport { resetOtpRepoSingleton } from './authn/otp/iam-authn-otp-repository-otp.js'\nimport { createAuthzOperations } from './authz/iam-authz-functions.js'\nimport { resetPermissionRepoSingleton } from './authz/iam-authz-repository-permission.js'\nimport { resetRoleRepoSingleton } from './authz/iam-authz-repository-role.js'\nimport { IamConfigSchema } from './iam-config.js'\nimport { iamM } from './iam-i18n.js'\nimport { seedIamData } from './iam-seed.js'\nimport {\n\n HaiIamError,\n\n} from './iam-types.js'\nimport { createSessionOperations } from './session/iam-session-functions.js'\nimport { createUserOperations } from './user/iam-user-functions.js'\nimport { resetResetTokenRepoSingleton } from './user/iam-user-repository-reset-token.js'\nimport { resetUserRepoSingleton } from './user/iam-user-repository-user.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'main' })\n\n// ─── 内部状态 ───\n\n/** init() 是否正在执行(并发防护) */\nlet initInProgress = false\nlet currentConfig: IamConfig | null = null\nlet currentAuth: AuthnOperations | null = null\nlet currentUser: UserOperations | null = null\nlet currentAuthz: AuthzOperations | null = null\nlet currentSession: SessionOperations | null = null\nlet currentApiKey: ApiKeyOperations | null = null\n\n// ─── 未初始化占位 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiIamError.NOT_INITIALIZED,\n () => iamM('iam_notInitialized'),\n)\n\nconst notInitializedAuth = notInitialized.proxy<AuthnOperations>()\nconst notInitializedAuthz = notInitialized.proxy<AuthzOperations>()\nconst notInitializedSession = notInitialized.proxy<SessionOperations>()\nconst notInitializedApiKey = notInitialized.proxy<ApiKeyOperations>()\n\n/**\n * 用户子功能的未初始化代理\n *\n * 需要特殊处理 validatePassword:该方法是同步的,\n * 其余方法为异步,因此不能统一使用 proxy('async') 或 proxy('sync')。\n */\nconst syncUserProxy = notInitialized.proxy<UserOperations>('sync')\nconst asyncUserProxy = notInitialized.proxy<UserOperations>()\nconst notInitializedUser: UserOperations = new Proxy({} as UserOperations, {\n get(_, prop, receiver) {\n return prop === 'validatePassword'\n ? Reflect.get(syncUserProxy as object, prop, receiver)\n : Reflect.get(asyncUserProxy as object, prop, receiver)\n },\n})\n\n// ─── 服务对象 ───\n\nexport const iam: IamFunctions = {\n async init(config: IamConfigInput): Promise<HaiResult<void>> {\n // 并发防护:防止多次同时调用导致子功能/连接泄漏\n if (initInProgress) {\n logger.warn('IAM init already in progress, skipping concurrent call')\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_initInProgress'),\n )\n }\n initInProgress = true\n\n try {\n if (currentConfig !== null) {\n logger.warn('IAM module is already initialized, reinitializing')\n await iam.close()\n }\n const { ldapClientFactory, ldapSyncUser, onPasswordResetRequest, onOtpSendEmail, onOtpSendSms, ...settingsInput } = config\n\n logger.info('Initializing IAM module')\n\n // 前置依赖检查:reldb 和 cache 必须已初始化\n if (!reldb.isInitialized) {\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_depsNotInitialized', { params: { dep: 'reldb' } }),\n )\n }\n if (!cache.isInitialized) {\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_depsNotInitialized', { params: { dep: 'cache' } }),\n )\n }\n\n // 确保 crypto 已初始化(密码哈希依赖)\n if (!crypto.isInitialized) {\n const cryptoResult = await crypto.init()\n if (!cryptoResult.success) {\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_initFailed'),\n cryptoResult.error,\n )\n }\n }\n\n const parseResult = IamConfigSchema.safeParse(settingsInput)\n if (!parseResult.success) {\n logger.error('IAM config validation failed', { error: parseResult.error.message })\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_configError', { params: { error: parseResult.error.message } }),\n parseResult.error,\n )\n }\n const parsed = parseResult.data\n\n // 创建子功能(按依赖顺序),使用局部变量暂存,全部成功后再原子性赋值\n const sessionResult = await createSessionOperations({ config: parsed })\n if (!sessionResult.success) {\n return sessionResult\n }\n\n const authzResult = await createAuthzOperations({ config: parsed, session: sessionResult.data })\n if (!authzResult.success) {\n return authzResult\n }\n\n const authnResult = await createAuthnOperations({\n config: parsed,\n sessionFunctions: sessionResult.data,\n authzFunctions: authzResult.data,\n ldapClientFactory,\n ldapSyncUser,\n onOtpSendEmail,\n onOtpSendSms,\n })\n if (!authnResult.success) {\n return authnResult\n }\n\n const userResult = await createUserOperations({\n config: parsed,\n passwordStrategyResult: authnResult.data.passwordStrategyResult,\n sessionFunctions: sessionResult.data,\n authzFunctions: authzResult.data,\n onPasswordResetRequest,\n })\n if (!userResult.success) {\n return userResult\n }\n\n // 种子数据\n if (parsed.seedDefaultData) {\n const seedResult = await seedIamData(authzResult.data)\n if (!seedResult.success) {\n return seedResult\n }\n }\n\n // 所有子功能创建成功,原子性赋值到模块状态\n currentSession = sessionResult.data\n currentAuthz = authzResult.data\n currentUser = userResult.data\n currentConfig = parsed\n currentApiKey = authnResult.data.apiKeyFunctions\n\n // 组合 auth:注入 registerAndLogin(依赖 user + auth 两个子功能)\n const authn = authnResult.data.authn\n currentAuth = {\n ...authn,\n async registerAndLogin(options) {\n const regResult = await currentUser!.register(options)\n if (!regResult.success) {\n return regResult as HaiResult<AuthResult>\n }\n return authn.login({ identifier: options.username, password: options.password })\n },\n }\n logger.info('IAM module initialized')\n return ok(undefined)\n }\n catch (error) {\n logger.error('IAM module initialization failed', { error })\n return err(\n HaiIamError.CONFIG_ERROR,\n iamM('iam_initFailed'),\n error,\n )\n }\n finally {\n initInProgress = false\n }\n },\n\n get auth(): AuthnOperations { return currentAuth ?? notInitializedAuth },\n get user(): UserOperations { return currentUser ?? notInitializedUser },\n get authz(): AuthzOperations { return currentAuthz ?? notInitializedAuthz },\n get session(): SessionOperations { return currentSession ?? notInitializedSession },\n get apiKey(): ApiKeyOperations { return currentApiKey ?? notInitializedApiKey },\n get config() { return currentConfig },\n get isInitialized() { return currentConfig !== null },\n get isRegisterEnabled() { return currentConfig?.register?.enabled !== false },\n\n async close() {\n if (currentConfig === null && currentAuth === null && currentUser === null && currentAuthz === null && currentSession === null) {\n logger.info('IAM module already closed, skipping')\n return\n }\n\n logger.info('Closing IAM module')\n\n currentAuth = null\n currentUser = null\n currentAuthz = null\n currentSession = null\n currentApiKey = null\n currentConfig = null\n\n // 重置所有仓库单例,释放对旧 db 实例的引用\n resetApiKeyRepoSingleton()\n resetOtpRepoSingleton()\n resetUserRepoSingleton()\n resetResetTokenRepoSingleton()\n resetRoleRepoSingleton()\n resetPermissionRepoSingleton()\n\n logger.info('IAM module closed')\n },\n}\n"]}