@h-ai/iam 0.1.0-alpha9 → 1.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +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 NOT_INITIALIZED: '010:500',\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 OTP_EXPIRED: '022:400',\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 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 // BaseReldbCrudRepository.create 接受 Record<string, unknown>,StoredApiKey 兼容但需强转\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 // BaseReldbCrudRepository.updateById 接受 Record<string, unknown>,Partial<StoredApiKey> 兼容但需强转\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 // reldb.sql.query 返回 Record<string, unknown>[],此处强转为领域类型(字段映射由 SQL 保证)\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 // reldb.sql.query 返回 Record<string, unknown>[],此处强转为领域类型(字段映射由 SQL 保证)\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 await Promise.allSettled(\n affectedUsersResult.data.map(userId => 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 await Promise.allSettled(\n affectedUserIds.map(userId => 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 const escaped = options.search.replace(/[%_\\\\]/g, '\\\\$&')\n const pattern = `%${escaped}%`\n whereClauses.push('(code LIKE ? ESCAPE \\'\\\\\\' OR name LIKE ? ESCAPE \\'\\\\\\')')\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 await Promise.allSettled(\n affectedRoleIds.map(roleId => 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 // 并行读取所有 session 及其 TTL,避免逐个串行 cache 调用\n const tokens = tokensResult.data\n const readResults = await Promise.allSettled(\n tokens.map(async (token) => {\n const sessionKey = buildTokenKey(token)\n const [sessionResult, ttlResult] = await Promise.all([\n cache.kv.get<Record<string, unknown>>(sessionKey),\n cache.kv.ttl(sessionKey),\n ])\n return { token, sessionKey, sessionResult, ttlResult }\n }),\n )\n\n const staleTokens: string[] = []\n const writeOps: Array<Promise<HaiResult<void>>> = []\n\n for (const entry of readResults) {\n if (entry.status === 'rejected')\n continue\n const { token, sessionKey, sessionResult, ttlResult } = entry.value\n\n if (!sessionResult.success || !sessionResult.data || !ttlResult.success || ttlResult.data <= 0) {\n staleTokens.push(token)\n continue\n }\n\n const updated = { ...sessionResult.data, ...updates }\n writeOps.push(cache.kv.set(sessionKey, updated, { ex: ttlResult.data }))\n }\n\n // 并行写入所有更新\n const writeResults = await Promise.allSettled(writeOps)\n const failedWrite = writeResults.find(r => r.status === 'fulfilled' && !r.value.success) as\n PromiseFulfilledResult<HaiResult<void>> | undefined\n if (failedWrite) {\n const failedResult = failedWrite.value as { success: false, error: { message: string } }\n return err(\n HaiIamError.REPOSITORY_ERROR,\n iamM('iam_saveUserSessionCacheFailed', { params: { message: failedResult.error.message } }),\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 { generateToken } from '../session/iam-session-utils.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 ? ESCAPE \\'\\\\\\' OR email LIKE ? ESCAPE \\'\\\\\\' OR phone LIKE ? ESCAPE \\'\\\\\\' OR display_name LIKE ? ESCAPE \\'\\\\\\')')\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 // 生成 256-bit 加密安全令牌(与 session token 强度一致)\n const token = generateToken()\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"]}
1
+ {"version":3,"sources":["../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/iam-i18n.ts","../src/iam-cache.ts","../src/authn/apikey/iam-authn-apikey-repository.ts","../src/iam-agreement.ts","../src/session/iam-session-utils.ts","../src/ticket/iam-ticket-functions.ts","../src/user/iam-user-utils.ts","../src/user/iam-user-repository-user.ts","../src/authn/apikey/iam-authn-apikey-scope.ts","../src/authn/iam-authn-utils.ts","../src/authn/apikey/iam-authn-apikey-strategy.ts","../src/authn/iam-authn-access.ts","../src/authn/iam-authn-captcha.ts","../src/authn/ldap/iam-authn-ldap-client.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-audit.ts","../src/iam-migration.ts","../src/iam-notifications.ts","../src/iam-public-config.ts","../src/iam-security-cache.ts","../src/iam-seed.ts","../src/session/iam-session-repository-cache.ts","../src/session/iam-session-functions.ts","../src/user/iam-user-functions.ts","../src/iam-main.ts"],"names":["core","after","err","ok","prefix","logger","cache","TABLE_NAME","reldb","BaseReldbCrudRepository","crypto","haiCrypto","createHash","randomBytes","failure","mapRepositoryError","HaiReldbError"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"iam_invitationDisabled\": \"Invitations are disabled or a required delivery channel is unavailable.\",\n \"iam_invitationDeliveryUnknown\": \"Account created; invitation delivery is unconfirmed. Check delivery before requesting a new reset notification.\",\n \"iam_reauthenticationRequired\": \"Verify your password again to continue this operation.\",\n \"iam_loginAccessDenied\": \"Sign-in is not allowed from this address or at this time.\",\n \"iam_batchUserIdsInvalid\": \"Provide at most 1000 non-empty user IDs\",\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"iam_securityStateFailed\": \"Unable to update authentication security state. Please try again later.\",\n \"iam_securityBusy\": \"Too many authentication requests. Please try again later.\",\n \"iam_passwordResetDisabled\": \"Password reset is disabled or delivery is not configured.\",\n \"iam_passwordResetDeliveryFailed\": \"Unable to deliver the reset notification. Please try again later.\",\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_accountUnavailable\": \"This account is currently unavailable. Contact an administrator to check its status or expiration.\",\n \"iam_accountLocked\": \"Account is locked, please try again later\",\n \"iam_accountNoPassword\": \"Username or password is incorrect.\",\n \"iam_passwordWrong\": \"Username or password is incorrect.\",\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_ticketInvalid\": \"Invalid, already used, or unknown ticket\",\n \"iam_ticketExpired\": \"Ticket has expired\",\n \"iam_ticketIssueFailed\": \"Failed to issue or read ticket\",\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\": \"Username or 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 verification code. Please try again later.\",\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 \"iam_sessionStateFailed\": \"Shared session state operation failed\",\n \"iam_sessionStateConflict\": \"Session state changed; retry the operation\",\n \"iam_sessionMaxAgeInvalid\": \"Invalid session lifetime or timestamp\",\n \"iam_sessionLimitExceeded\": \"The active session limit has been reached. Sign out another session first.\",\n \"iam_accountPolicyInvalid\": \"Invalid account type, status, or expiry.\",\n \"iam_accountUpdateFailed\": \"Account update failed. Please try again later.\",\n \"iam_passwordChangeRequired\": \"Change your initial password before signing in.\",\n \"iam_passwordMustDiffer\": \"The new password must differ from the current password.\",\n \"iam_passwordCharacterClasses\": \"Use at least {count} character classes in the password.\",\n \"iam_notificationDeliveryUnknown\": \"Notification delivery is unknown and may have succeeded; do not resend automatically.\",\n \"iam_captchaRequired\": \"Complete the security check first\",\n \"iam_captchaInvalid\": \"Security check is invalid or expired; try again\",\n \"iam_captchaDisabled\": \"Security challenges are disabled\",\n \"iam_captchaUnavailable\": \"Security check is temporarily unavailable\",\n \"iam_sensitiveOperationsInvalid\": \"Invalid sensitive operation IDs: use at most 1000 entries of 1–128 characters each.\",\n \"iam_terminalTypeInvalid\": \"Invalid terminal type: use web, app, desktop or api.\"\n}\n","{\n \"iam_invitationDisabled\": \"招待機能が無効、または必要な通知経路が利用できません。\",\n \"iam_invitationDeliveryUnknown\": \"アカウントは作成済みですが招待の配送は未確認です。配送状況を確認してから再設定通知を要求してください。\",\n \"iam_reauthenticationRequired\": \"この操作を続けるにはパスワードを再確認してください。\",\n \"iam_loginAccessDenied\": \"このアドレスまたは時間帯からのログインは許可されていません。\",\n \"iam_batchUserIdsInvalid\": \"空でないユーザーIDを1000件以内で指定してください\",\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"iam_securityStateFailed\": \"認証セキュリティ状態を更新できません。しばらくしてから再試行してください。\",\n \"iam_securityBusy\": \"認証リクエストが多すぎます。しばらくしてから再試行してください。\",\n \"iam_passwordResetDisabled\": \"パスワードのリセットが無効か、配信が設定されていません。\",\n \"iam_passwordResetDeliveryFailed\": \"リセット通知を配信できません。しばらくしてから再試行してください。\",\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_accountUnavailable\": \"現在このアカウントは利用できません。状態または有効期限を管理者に確認してください。\",\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_ticketInvalid\": \"チケットが無効、使用済み、または不明です\",\n \"iam_ticketExpired\": \"チケットの有効期限が切れています\",\n \"iam_ticketIssueFailed\": \"チケットの発行または読み取りに失敗しました\",\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\": \"認証コードの送信に失敗しました。しばらくしてから再試行してください。\",\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キーが無効です\",\n \"iam_apikeyExpired\": \"APIキーの有効期限が切れています\",\n \"iam_apikeyDisabled\": \"APIキーが無効化されています\",\n \"iam_apikeyMaxKeysReached\": \"APIキーの上限({max}件)に達しました\",\n \"iam_apikeyCreateFailed\": \"APIキーの作成に失敗しました: {message}\",\n \"iam_apikeyUpdateFailed\": \"APIキーの更新に失敗しました: {message}\",\n \"iam_apikeyDeleteFailed\": \"APIキーの削除に失敗しました: {message}\",\n \"iam_apikeyQueryFailed\": \"APIキーの取得に失敗しました: {message}\",\n \"iam_apikeyStrategyRequired\": \"APIキー認証にはAPIキー戦略の設定が必要です\",\n \"iam_sessionStateFailed\": \"共有セッション状態の操作に失敗しました\",\n \"iam_sessionStateConflict\": \"セッション状態が変更されました。操作を再試行してください\",\n \"iam_sessionMaxAgeInvalid\": \"セッションの有効期間またはタイムスタンプが無効です\",\n \"iam_sessionLimitExceeded\": \"有効なセッション数が上限に達しました。他のセッションからログアウトしてください。\",\n \"iam_accountPolicyInvalid\": \"アカウント種別、状態、または有効期限が無効です。\",\n \"iam_accountUpdateFailed\": \"アカウントの更新に失敗しました。後で再試行してください。\",\n \"iam_passwordChangeRequired\": \"最初のパスワードを変更してからログインしてください。\",\n \"iam_passwordMustDiffer\": \"新しいパスワードは現在のパスワードと異なる必要があります。\",\n \"iam_passwordCharacterClasses\": \"パスワードには少なくとも{count}種類の文字を含めてください。\",\n \"iam_notificationDeliveryUnknown\": \"通知の配信結果は不明で、成功した可能性があります。自動で再送しないでください。\",\n \"iam_captchaRequired\": \"先にセキュリティ確認を完了してください\",\n \"iam_captchaInvalid\": \"セキュリティ確認が無効または期限切れです。再試行してください\",\n \"iam_captchaDisabled\": \"セキュリティ確認は無効です\",\n \"iam_captchaUnavailable\": \"セキュリティ確認を一時的に利用できません\",\n \"iam_sensitiveOperationsInvalid\": \"重要操作 ID は最大1000件、各1~128文字で指定してください。\",\n \"iam_terminalTypeInvalid\": \"端末種別は web、app、desktop、api のいずれかを指定してください。\"\n}\n","{\n \"iam_invitationDisabled\": \"邀请功能未启用,或所需通知通道未就绪。\",\n \"iam_invitationDeliveryUnknown\": \"账号已创建,邀请投递尚未确认。请核对投递后再请求新的重置通知。\",\n \"iam_reauthenticationRequired\": \"请重新验证密码后继续此操作。\",\n \"iam_loginAccessDenied\": \"当前地址或时段不允许登录。\",\n \"iam_batchUserIdsInvalid\": \"请提供最多 1000 个非空用户 ID\",\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"iam_securityStateFailed\": \"无法更新认证安全状态,请稍后重试\",\n \"iam_securityBusy\": \"认证请求过于频繁,请稍后重试\",\n \"iam_passwordResetDisabled\": \"密码重置未启用或通知渠道未配置\",\n \"iam_passwordResetDeliveryFailed\": \"重置通知发送失败,请稍后重试\",\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_accountUnavailable\": \"账号当前不可用,请联系管理员确认账号状态或有效期。\",\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_ticketInvalid\": \"票据无效、已使用或不存在\",\n \"iam_ticketExpired\": \"票据已过期\",\n \"iam_ticketIssueFailed\": \"票据签发或读取失败\",\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\": \"验证码发送失败,请稍后重试\",\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 \"iam_sessionStateFailed\": \"会话共享状态操作失败\",\n \"iam_sessionStateConflict\": \"会话状态已变化,请重试\",\n \"iam_sessionMaxAgeInvalid\": \"会话有效期或时间字段无效\",\n \"iam_sessionLimitExceeded\": \"有效会话数量已达上限,请先退出其他会话\",\n \"iam_accountPolicyInvalid\": \"账号类型、状态或到期时间无效\",\n \"iam_accountUpdateFailed\": \"账号更新失败,请稍后重试\",\n \"iam_passwordChangeRequired\": \"请先更换初始密码后登录\",\n \"iam_passwordMustDiffer\": \"新密码不能与当前密码相同\",\n \"iam_passwordCharacterClasses\": \"密码至少应包含 {count} 类字符\",\n \"iam_notificationDeliveryUnknown\": \"通知可能已送达,结果未知;请勿自动重发。\",\n \"iam_captchaRequired\": \"请先完成安全验证\",\n \"iam_captchaInvalid\": \"安全验证无效或已过期,请重试\",\n \"iam_captchaDisabled\": \"安全验证未启用\",\n \"iam_captchaUnavailable\": \"安全验证暂不可用,请稍后重试\",\n \"iam_sensitiveOperationsInvalid\": \"敏感操作 ID 列表无效:最多 1000 项,每项为 1–128 字符。\",\n \"iam_terminalTypeInvalid\": \"终端类型无效,请使用 web、app、desktop 或 api。\"\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 messagesJaJP from '../messages/ja-JP.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n// ─── i18n ───\n\n/**\n * IAM 模块文案 Key 类型\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const key: IamMessageKey = 'iam_notInitialized'\n * const message = iamM(key)\n * ```\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 * @example 模块内部上下文\n * ```ts\n * const message = iamM('iam_notInitialized')\n * ```\n */\nexport const iamM = core.i18n.createMessageGetter<IamMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n 'ja-JP': messagesJaJP,\n})\n","/** IAM 热路径共享缓存;写入栅栏覆盖数据库提交和外部事务完成。 */\nimport type { HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations } from '@h-ai/reldb'\nimport { randomUUID } from 'node:crypto'\nimport { cache } from '@h-ai/cache'\nimport { core, err, ok } from '@h-ai/core'\nimport { iamM } from './iam-i18n.js'\nimport { HaiIamError } from './iam-types.js'\n\n/**\n * 缓存读取代际与尚未确认完成的写入数。\n * @example 模块内部上下文\n * ```ts\n * const state: Revision = { epoch: 'example', writers: 0 }\n * void state\n * ```\n */\ninterface Revision { epoch: string, writers: number }\nconst revisionKey = 'hai:iam:read_cache:revision'\nconst transactions = new WeakMap<DmlWithTxOperations, Promise<HaiResult<void>>>()\nconst logger = core.logger.child({ module: 'iam', scope: 'read-cache' })\nlet degraded = false\nfunction failure() {\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_sessionExpired'))\n}\n\nasync function revision(): Promise<HaiResult<Revision>> {\n const current = await cache.kv.get<Revision>(revisionKey)\n if (!current.success)\n return current\n if (current.data)\n return ok(current.data)\n const created = await cache.kv.set(revisionKey, { epoch: randomUUID(), writers: 0 }, { nx: true })\n if (!created.success)\n return created\n const loaded = await cache.kv.get<Revision>(revisionKey)\n return loaded.success && loaded.data ? ok(loaded.data) : failure()\n}\n\nasync function change(delta: number): Promise<HaiResult<void>> {\n for (let attempt = 0; attempt < 32; attempt++) {\n const current = await revision()\n if (!current.success)\n return current\n const written = await cache.kv.compareAndSwap(revisionKey, current.data, { epoch: randomUUID(), writers: Math.max(0, current.data.writers + delta) })\n if (!written.success)\n return written\n if (written.data)\n return ok(undefined)\n }\n return failure()\n}\n\n/**\n * 只缓存成功的有限寿命 DTO;写入中或 Redis 不可用时回源,绝不复用旧授权。\n * @example 模块内部上下文\n * ```ts\n * async function readExample() {\n * const result = await readIamCache('example', async () => ok({ enabled: true }))\n * if (!result.success) return result\n * return result.data.enabled\n * }\n * ```\n */\nexport async function readIamCache<T>(key: string, load: () => Promise<HaiResult<T>>): Promise<HaiResult<T>> {\n const before = await revision()\n if (!before.success || before.data.writers)\n return load()\n const address = `hai:iam:read_cache:${before.data.epoch}:${key}`\n const cached = await cache.kv.get<{ value: T }>(address)\n if (cached.success && cached.data) {\n const after = await revision()\n if (after.success && !after.data.writers && after.data.epoch === before.data.epoch)\n return ok(cached.data.value)\n return load()\n }\n const result = await load()\n if (!result.success)\n return result\n const after = await revision()\n if (after.success && !after.data.writers && after.data.epoch === before.data.epoch)\n await cache.kv.set(address, { value: result.data }, { ex: 60 })\n return result\n}\n\nasync function finish() {\n const completed = await change(-1)\n if (!completed.success && !degraded) {\n degraded = true\n // 写入已提交时不能伪装成失败;持久脏标记保留,后续鉴权安全回源。\n logger.warn('IAM cache invalidation incomplete; authorization reads use database', { code: completed.error.code })\n }\n if (completed.success)\n degraded = false\n}\n\nasync function enroll(tx: DmlWithTxOperations): Promise<HaiResult<void>> {\n const existing = transactions.get(tx)\n if (existing)\n return existing\n const pending = (async () => {\n const started = await change(1)\n if (!started.success)\n return started\n const commit = tx.commit.bind(tx)\n const rollback = tx.rollback.bind(tx)\n // DmlWithTxOperations 的完成方法可写;原方法仍恰好调用一次。\n // 未知提交结果或进程崩溃保留脏标记,不依赖 TTL 恢复可能过时的授权。\n tx.commit = async () => {\n const result = await commit()\n if (result.success)\n await finish()\n return result\n }\n tx.rollback = async () => {\n const result = await rollback()\n if (result.success)\n await finish()\n return result\n }\n return ok(undefined)\n })()\n transactions.set(tx, pending)\n return pending\n}\n\n/**\n * 给真实写入口增加共享失效;txIndex 为已有事务参数的位置。\n * @example 模块内部上下文\n * ```ts\n * async function writeExample() {\n * const operation = guardIamMutation(async () => ok(undefined))\n * const result = await operation()\n * if (!result.success) return result\n * return result.data\n * }\n * ```\n */\nexport function guardIamMutation<A extends unknown[], T>(operation: (...args: A) => Promise<HaiResult<T>>, txIndex?: number): (...args: A) => Promise<HaiResult<T>> {\n return async (...args) => {\n const candidate = txIndex === undefined ? undefined : args[txIndex]\n // 事务参数来自已声明的 IAM 方法签名;此处只收窄公共事务句柄。\n const tx = candidate as DmlWithTxOperations | undefined\n let started: HaiResult<void>\n try {\n started = tx ? await enroll(tx) : await change(1)\n }\n catch { return failure() }\n if (!started.success)\n return started\n try {\n return await operation(...args)\n }\n catch { return failure() }\n finally {\n if (!tx)\n await finish()\n }\n }\n}\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, PaginatedResult } from '@h-ai/core'\nimport type { DmlWithTxOperations, ReldbCrudFieldDefinition } from '@h-ai/reldb'\nimport type { ApiKeySortField, ListApiKeysOptions, StoredApiKey } from './iam-authn-apikey-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { BaseReldbCrudRepository, reldb } from '@h-ai/reldb'\nimport { guardIamMutation } from '../../iam-cache.js'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\n\n// ─── API Key 存储接口 ───\n\n/**\n * API Key 存储接口\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // RelDB 已初始化;后续仓储读取仍可能失败,必须检查 HaiResult。\n * const repository = await createDbApiKeyRepository()\n * const found = await repository.findOneById('key-1')\n * if (!found.success)\n * return found\n * return found.data?.keyPrefix ?? null\n * ```\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 findPageByUserId: (userId: string, options: ListApiKeysOptions, tx?: DmlWithTxOperations) => Promise<HaiResult<PaginatedResult<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\n/** API Key 排序字段到数据库列名的映射。 */\nconst API_KEY_SORT_COLUMNS: Record<ApiKeySortField, string> = {\n name: 'name',\n createdAt: 'created_at',\n lastUsedAt: 'last_used_at',\n expiresAt: 'expires_at',\n}\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 apiKeyRepoSqlOps: unknown = null\n\n/**\n * 重置 API Key 存储单例\n * 仅重置本地引用,不删除共享存储数据。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 所有使用该仓储的 IAM 子功能均已关闭后,才清理工厂缓存。\n * resetApiKeyRepoSingleton()\n * ```\n */\nexport function resetApiKeyRepoSingleton(): void {\n apiKeyRepoInstance = null\n apiKeyRepoSqlOps = null\n}\n\n/**\n * 创建基于数据库的 API Key 存储实例\n *\n * @returns API Key 存储接口实现\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // RelDB 已初始化;后续仓储读取仍可能失败,必须检查 HaiResult。\n * const repository = await createDbApiKeyRepository()\n * const found = await repository.findOneById('key-1')\n * if (!found.success)\n * return found\n * return found.data?.keyPrefix ?? null\n * ```\n */\nexport async function createDbApiKeyRepository(): Promise<ApiKeyRepository> {\n if (apiKeyRepoInstance && apiKeyRepoSqlOps === reldb.sql)\n return apiKeyRepoInstance\n\n const repo = new DbApiKeyRepository()\n await repo.count()\n repo.removeById = guardIamMutation(repo.removeById.bind(repo), 1)\n const update = repo.updateFields.bind(repo)\n const protectedUpdate = guardIamMutation(update, 2)\n repo.updateFields = (id, data, tx) => Object.keys(data).every(key => key === 'lastUsedAt') ? update(id, data, tx) : protectedUpdate(id, data, tx)\n apiKeyRepoInstance = repo\n apiKeyRepoSqlOps = reldb.sql\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 }, 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 findPageByUserId(userId: string, options: ListApiKeysOptions, tx?: DmlWithTxOperations): Promise<HaiResult<PaginatedResult<StoredApiKey>>> {\n const conditions: string[] = ['user_id = ?']\n const params: unknown[] = [userId]\n\n if (options.search) {\n // 转义 LIKE 通配符,防止用户输入 % 或 _ 产生非预期匹配。\n const escaped = options.search.replace(/[%_\\\\]/g, '\\\\$&')\n const keyword = `%${escaped}%`\n conditions.push('(name LIKE ? ESCAPE \\'\\\\\\' OR key_prefix LIKE ? ESCAPE \\'\\\\\\')')\n params.push(keyword, keyword)\n }\n\n if (options.enabled !== undefined) {\n conditions.push('enabled = ?')\n params.push(options.enabled ? 1 : 0)\n }\n\n const sortColumn = options.sortBy ? API_KEY_SORT_COLUMNS[options.sortBy] : API_KEY_SORT_COLUMNS.createdAt\n const sortDirection = options.sortBy && options.sortDirection === 'asc' ? 'ASC' : 'DESC'\n\n const result = await this.findPage({\n where: conditions.join(' AND '),\n params,\n orderBy: `${sortColumn} ${sortDirection}`,\n pagination: { page: options.page, pageSize: options.pageSize },\n }, tx)\n if (!result.success) {\n return this.buildQueryError(result.error)\n }\n return result\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 }, 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 * 登录页与注册页共用的用户协议/隐私协议展示信息构建逻辑。\n * @module iam-agreement\n */\n\nimport type { AgreementConfig } from './iam-config.js'\nimport type { AgreementDisplay } from './user/iam-user-types.js'\n\n/**\n * 根据展示开关构建协议展示信息;未启用或未配置正文/链接时返回 undefined。\n *\n * @param config - 协议配置\n * @param enabled - 当前场景(登录/注册)是否展示协议\n * @returns 当前场景启用且配置了协议正文或 URL 时返回展示配置,否则返回 undefined。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const display = buildAgreementDisplay({ userAgreementUrl: 'https://app.example.com/terms', showOnRegister: true, showOnLogin: false }, true)\n * const agreementUrl = display?.userAgreementUrl\n * ```\n */\nexport function buildAgreementDisplay(\n config: AgreementConfig,\n enabled: boolean,\n): AgreementDisplay | undefined {\n if (!enabled)\n return undefined\n if (!config.userAgreementMarkdown && !config.privacyPolicyMarkdown && !config.userAgreementUrl && !config.privacyPolicyUrl)\n return undefined\n return {\n userAgreementMarkdown: config.userAgreementMarkdown,\n privacyPolicyMarkdown: config.privacyPolicyMarkdown,\n userAgreementUrl: config.userAgreementUrl,\n privacyPolicyUrl: config.privacyPolicyUrl,\n showOnRegister: config.showOnRegister,\n showOnLogin: config.showOnLogin,\n }\n}\n","/**\n * @h-ai/iam — 会话工具函数\n * @module iam-session-utils\n */\n\nimport type { CreateSessionOptions, Session } from './iam-session-types.js'\nimport { createHash } from 'node:crypto'\n\nconst BASE64_PLUS_REGEX = /\\+/g\nconst BASE64_SLASH_REGEX = /\\//g\nconst BASE64_TRAILING_PADDING_REGEX = /=+$/\n\n/**\n * 生成访问令牌\n *\n * 使用 256 位(32 字节)加密安全随机数,编码为 base64url 格式。\n * 相比 UUID v4(122 位),提供更高的熵值和抗碰撞能力。\n *\n * @returns base64url 编码的 256 位随机令牌\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const token = generateToken()\n * const isBase64Url = /^[\\w-]{43}$/.test(token)\n * ```\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(BASE64_PLUS_REGEX, '-').replace(BASE64_SLASH_REGEX, '_').replace(BASE64_TRAILING_PADDING_REGEX, '')\n}\n\n/**\n * 获取用户会话分区;SHA-256 路由提示不包含原始用户 ID,也不充当认证凭据。\n * @param userId - 可信用户 ID;不能用路由提示替代完整令牌认证。\n * @returns 用户 ID 的 SHA-256 十六进制分区提示,同一用户在所有节点得到相同值。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const scope = getUserSessionScope('user-1')\n * const samePartition = scope === getUserSessionScope('user-1')\n * ```\n */\nexport function getUserSessionScope(userId: string): string {\n return createHash('sha256').update(userId).digest('hex')\n}\n\n/**\n * 生成携带分区提示的随机会话令牌;认证仍须匹配共享状态中的完整 256 位随机值。\n * @param userId - 已核验用户 ID,作为共享会话的分区路由来源。\n * @returns s1 前缀、用户分区提示与 256 位安全随机值组成的不透明令牌。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const token = generateSessionToken('user-1')\n * const partition = getTokenSessionScope(token)\n * ```\n */\nexport function generateSessionToken(userId: string): string {\n return `s1.${getUserSessionScope(userId)}.${generateToken()}`\n}\n\n/**\n * 解析经过格式约束的路由提示;非法 token 不访问共享存储。\n * @param token - 请求携带的完整访问或刷新令牌。\n * @returns 格式有效时返回分区提示;非法格式返回 undefined,不授予身份权限。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const token = generateSessionToken('user-1')\n * const samePartition = getTokenSessionScope(token) === getUserSessionScope('user-1')\n * const invalid = getTokenSessionScope('malformed-token') // undefined,不访问共享缓存。\n * ```\n */\nexport function getTokenSessionScope(token: string): string | undefined {\n return /^s1\\.([a-f0-9]{64})\\.[\\w-]{43}$/.exec(token)?.[1]\n}\n\n/**\n * 构建会话数据\n *\n * @param options - 创建会话选项(用户 ID、角色等)\n * @param now - 当前时间\n * @param sessionTtl - 会话有效期(秒)\n * @param accessToken - 访问令牌\n * @param credentialVersion - 已核对当前数据库的可信凭据代\n * @returns 完整的 Session 对象\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const session = buildSession({ userId: 'user-1', source: 'server' }, new Date(), 3600, generateSessionToken('user-1'), 'verified-credential-version')\n * const expiresInSeconds = getSessionTtl(session)\n * ```\n */\nexport function buildSession(options: CreateSessionOptions, now: Date, sessionTtl: number, accessToken: string, credentialVersion: string): Session {\n return {\n version: crypto.randomUUID(),\n credentialVersion,\n apiKeyId: options.apiKeyId,\n apiKeyScopes: options.apiKeyScopes,\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 terminalType: options.terminalType ?? 'web',\n accessToken,\n createdAt: now,\n startedAt: now,\n lastActiveAt: now,\n expiresAt: new Date(now.getTime() + sessionTtl * 1000),\n maxAge: sessionTtl,\n data: options.data,\n }\n}\n\n/**\n * 计算会话剩余 TTL\n *\n * @param session - 会话对象\n * @param now - 当前时间戳(毫秒,默认 Date.now())\n * @returns 剩余秒数,最小为 0\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const session = buildSession({ userId: 'user-1', source: 'server' }, new Date(), 3600, generateSessionToken('user-1'), 'verified-credential-version')\n * const remaining = getSessionTtl(session, session.createdAt.getTime() + 1000) // 3599\n * ```\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * const session = buildSession({ userId: 'user-1', source: 'server' }, new Date(), 3600, generateSessionToken('user-1'), 'verified-credential-version')\n * const updated = applySessionPatch(session, { data: { theme: 'dark' } })\n * const originalUnchanged = session.data === undefined\n * ```\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 if (patch.expiresAt !== undefined)\n nextSession.expiresAt = new Date(patch.expiresAt)\n nextSession.lastActiveAt = patch.lastActiveAt !== undefined ? new Date(patch.lastActiveAt) : new Date()\n return nextSession\n}\n","/**\n * @h-ai/iam — 一次性票据实现\n *\n * 基于 @h-ai/cache 实现短期、一次性能力票据:签发写入带 TTL 的 cache 键,\n * 消费通过「读取 + 原子删除」保证单次有效(并发消费仅一个成功)。\n * @module ticket/iam-ticket-functions\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type {\n ConsumedTicket,\n ConsumeTicketOptions,\n IssuedTicket,\n IssueTicketOptions,\n TicketGrant,\n TicketOperations,\n} from './iam-ticket-types.js'\n\nimport { cache } from '@h-ai/cache'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { generateToken } from '../session/iam-session-utils.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'ticket' })\n\n/** 票据缓存键前缀 */\nconst TICKET_KEY_PREFIX = 'hai:iam:ticket:'\n/** 默认有效期(毫秒) */\nconst DEFAULT_TICKET_TTL_MS = 30_000\n\n/**\n * 缓存中存储的票据记录\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const record: StoredTicket = { subjectId: 'user-1', purpose: 'ai-audio', grant: { operation: 'transcribe' }, expiresAt: Date.now() + 30000 }\n * const expired = record.expiresAt <= Date.now()\n * ```\n */\ninterface StoredTicket {\n /** 签发时已核验的主体,消费时不根据客户端 userId 替换。 */\n subjectId: string\n /** 单一用途绑定,消费前必须与请求用途核对。 */\n purpose: string\n /** 签发时授权的操作、模型、会话等参数快照。 */\n grant: TicketGrant\n /** Unix 毫秒截止时间;共享缓存原子消费仍独立核验有效期。 */\n expiresAt: number\n}\n\n/** 构建票据缓存键 */\nfunction buildTicketKey(ticket: string): string {\n return `${TICKET_KEY_PREFIX}${ticket}`\n}\n\n/**\n * 创建一次性票据操作接口\n * @returns 无本地票据真值的操作接口;issue/consume 使用已初始化的共享 Cache 并返回 HaiResult。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const tickets = createTicketOperations()\n * const issued = await tickets.issue({ subjectId: 'user-1', purpose: 'ai-audio' })\n * if (!issued.success)\n * return issued\n * return tickets.consume(issued.data.ticket, { purpose: 'ai-audio' })\n * ```\n */\nexport function createTicketOperations(): TicketOperations {\n return {\n async issue(options: IssueTicketOptions): Promise<HaiResult<IssuedTicket>> {\n const ttlMs = options.ttlMs !== undefined && options.ttlMs > 0 ? options.ttlMs : DEFAULT_TICKET_TTL_MS\n const ticket = generateToken()\n const expiresAt = Date.now() + ttlMs\n const record: StoredTicket = {\n subjectId: options.subjectId,\n purpose: options.purpose,\n grant: options.grant ?? {},\n expiresAt,\n }\n\n // NX 保证键唯一(随机值几乎不会碰撞,nx 兜底防止极端重复覆盖已有票据)\n const saved = await cache.kv.set(buildTicketKey(ticket), record, { px: ttlMs, nx: true })\n if (!saved.success || !saved.data) {\n logger.warn('Failed to issue ticket', { purpose: options.purpose })\n return err(HaiIamError.TICKET_ISSUE_FAILED, iamM('iam_ticketIssueFailed'))\n }\n\n return ok({ ticket, expiresAt })\n },\n\n async consume(ticket: string, options?: ConsumeTicketOptions): Promise<HaiResult<ConsumedTicket>> {\n if (!ticket) {\n return err(HaiIamError.TICKET_INVALID, iamM('iam_ticketInvalid'))\n }\n const key = buildTicketKey(ticket)\n\n const found = await cache.kv.get<StoredTicket>(key)\n if (!found.success) {\n return err(HaiIamError.TICKET_ISSUE_FAILED, iamM('iam_ticketIssueFailed'))\n }\n const record = found.data\n if (!record) {\n return err(HaiIamError.TICKET_INVALID, iamM('iam_ticketInvalid'))\n }\n\n // 原子单次消费:删除计数为 1 的调用方胜出;并发消费的其余调用方得到 0 → 视为已消费\n const removed = await cache.kv.del(key)\n if (!removed.success || removed.data !== 1) {\n return err(HaiIamError.TICKET_INVALID, iamM('iam_ticketInvalid'))\n }\n\n // TTL 到期兜底(cache 已按 TTL 过期,此处防御时钟/后端差异)\n if (record.expiresAt <= Date.now()) {\n return err(HaiIamError.TICKET_EXPIRED, iamM('iam_ticketExpired'))\n }\n\n // 用途校验:防止跨用途重放\n if (options?.purpose !== undefined && options.purpose !== record.purpose) {\n return err(HaiIamError.TICKET_INVALID, iamM('iam_ticketInvalid'))\n }\n\n return ok({\n subjectId: record.subjectId,\n purpose: record.purpose,\n grant: record.grant,\n })\n },\n }\n}\n","/**\n * @h-ai/iam — 用户工具函数\n *\n * 提供用户实体的转换与去敏处理能力。\n * @module iam-user-utils\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { PasswordConfig } from '../iam-config.js'\nimport type { StoredUser, User } from './iam-user-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n/**\n * 首次/过期口令不能授权普通业务;验证旧密码后的 renewPassword 不使用此门禁。\n * @example 模块内部上下文\n * ```ts\n * function check(user: StoredUser, policy: PasswordConfig) { return checkPasswordState(user, policy) }\n * ```\n */\nexport function checkPasswordState(user: Pick<StoredUser, 'mustChangePassword' | 'passwordHash' | 'passwordUpdatedAt'>, policy?: PasswordConfig): HaiResult<void> {\n if (policy?.requireInitialChange && user.mustChangePassword)\n return err(HaiIamError.PASSWORD_CHANGE_REQUIRED, iamM('iam_passwordChangeRequired'))\n const days = policy?.expirationDays ?? 0\n if (days > 0 && user.passwordHash && (!user.passwordUpdatedAt || user.passwordUpdatedAt.getTime() + days * 86400_000 <= Date.now()))\n return err(HaiIamError.PASSWORD_EXPIRED, iamM('iam_passwordExpired'))\n return ok(undefined)\n}\n\n/**\n * 账号状态与到期时间在所有鉴别方式和持久凭据读取中共用。\n * @example 模块内部上下文\n * ```ts\n * function allowed(user: User) { return isUserActive(user) }\n * ```\n */\nexport function isUserActive(user: Pick<User, 'accountType' | 'accountStatus' | 'accountExpiresAt'>): boolean {\n return user.accountStatus === 'active'\n && (user.accountType !== 'temporary' || !!user.accountExpiresAt)\n && (!user.accountExpiresAt || new Date(user.accountExpiresAt).getTime() > Date.now())\n}\n\n/**\n * 仅接受公开账号枚举与合法日期,不把无期限的临时账号保存为可登录账号。\n * @example 模块内部上下文\n * ```ts\n * const result = validateAccountPolicy({ accountType: 'temporary', accountExpiresAt: new Date(Date.now() + 3600000) }); if (!result.success) result.error.code\n * ```\n */\nexport function validateAccountPolicy(user: Partial<Pick<User, 'accountType' | 'accountStatus' | 'accountExpiresAt'>>): HaiResult<void> {\n if ((user.accountType !== undefined && !['permanent', 'temporary'].includes(user.accountType))\n || (user.accountStatus !== undefined && !['active', 'dormant', 'closed'].includes(user.accountStatus))\n || (user.accountExpiresAt != null && (!(user.accountExpiresAt instanceof Date) || !Number.isFinite(user.accountExpiresAt.getTime())))\n || (user.accountType === 'temporary' && !user.accountExpiresAt)) {\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_accountPolicyInvalid'))\n }\n return ok(undefined)\n}\n\n/**\n * 将 StoredUser 转换为 User(移除敏感信息)\n *\n * 去除密码哈希、登录失败计数、锁定时间等内部字段,\n * 仅保留前端安全的用户信息。\n *\n * @param storedUser - 包含敏感信息的内部用户数据\n * @returns 去敏后的用户信息\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function response(stored: StoredUser): User {\n * return toUser(stored) // 投影白名单,不将密码哈希与凭据代际返回给调用端。\n * }\n * ```\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 accountType: storedUser.accountType ?? 'permanent',\n accountStatus: storedUser.accountStatus ?? 'active',\n accountExpiresAt: storedUser.accountExpiresAt ?? null,\n lastLoginAt: storedUser.lastLoginAt ?? null,\n mustChangePassword: storedUser.mustChangePassword ?? false,\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 * 基于 @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 { LoginFailurePolicy } from '../authn/iam-authn-utils.js'\nimport type { StoredUser } from './iam-user-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { BaseReldbCrudRepository, reldb } from '@h-ai/reldb'\nimport { guardIamMutation } from '../iam-cache.js'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { isUserActive } from './iam-user-utils.js'\n\n// ─── 用户存储接口 ───\n\n/**\n * 用户存储接口\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function commitPassword(repository: UserRepository, current: StoredUser, passwordHash: string) {\n * const written = await repository.setPassword({ userId: current.id, expectedVersion: current.credentialVersion ?? '', passwordHash })\n * if (!written.success)\n * return written\n * if (!written.data)\n * return { applied: false } // 凭据代际已变化;不能继续签发本次认证的会话。\n * return { applied: true }\n * }\n * ```\n */\nexport interface UserRepository extends ReldbCrudRepository<StoredUser> {\n /** 成功鉴别后记录登录时间;不修改角色或其他用户资料。 */\n recordSuccessfulLogin: (userId: string) => Promise<HaiResult<void>>\n /** 按最后成功登录/创建时间原子休眠并推进凭据代际。 */\n suspendInactive: (cutoff: Date) => Promise<HaiResult<number>>\n /** 按读取到的凭据代际改密并撤销重置令牌;旧版本不能覆盖较新密码。 */\n setPassword: (input: { userId: string, expectedVersion: string, passwordHash: string, mustChangePassword?: boolean }) => Promise<HaiResult<boolean>>\n /** 按用户快照发布新重置令牌;不使用 Redis/数据库之间的伪事务。 */\n publishPasswordReset: (input: { user: StoredUser, tokenHash: string, expiresAt: Date }) => Promise<HaiResult<boolean>>\n /** 按当前重置代际计次并颁发提交快照;新发布/尝试使旧快照失效。 */\n claimPasswordReset: (tokenHash: string, maxAttempts: number) => Promise<HaiResult<StoredUser>>\n /** 最终一条 SQL 同时验证授权代际、有效期、启用状态、消费令牌并改密。 */\n commitPasswordReset: (input: { user: StoredUser, tokenHash: string, passwordHash: string }) => Promise<HaiResult<boolean>>\n /** 在数据库中原子累加失败次数并执行锁定策略。 */\n recordLoginFailure: (userId: string, policy: LoginFailurePolicy) => Promise<HaiResult<void>>\n /** 仅未锁定且启用的账户可以清除失败计数。 */\n resetLoginFailures: (userId: string, expectedCredentialVersion: string, lockoutEnabled?: boolean) => Promise<HaiResult<void>>\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 { fieldName: 'mustChangePassword', columnName: 'must_change_password', def: { type: 'BOOLEAN', notNull: true, defaultValue: false }, select: true, create: true, update: false },\n { fieldName: 'accountType', columnName: 'account_type', def: { type: 'TEXT', notNull: true, defaultValue: 'permanent' }, select: true, create: true, update: true },\n { fieldName: 'accountStatus', columnName: 'account_status', def: { type: 'TEXT', notNull: true, defaultValue: 'active' }, select: true, create: true, update: true },\n { fieldName: 'accountExpiresAt', columnName: 'account_expires_at', def: { type: 'TIMESTAMP' }, select: true, create: true, update: true },\n { fieldName: 'lastLoginAt', columnName: 'last_login_at', def: { type: 'TIMESTAMP' }, select: true, create: false, update: false },\n { fieldName: 'credentialVersion', columnName: 'credential_version', def: { type: 'TEXT', notNull: true, defaultValue: '' }, select: true, create: false, update: false },\n { fieldName: 'resetVersion', columnName: 'reset_version', def: { type: 'TEXT', notNull: true, defaultValue: '' }, select: true, create: false, update: false },\n { fieldName: 'resetHash', columnName: 'reset_hash', def: { type: 'TEXT' }, select: true, create: false, update: false },\n { fieldName: 'resetExpiresAt', columnName: 'reset_expires_at', def: { type: 'BIGINT' }, select: true, create: false, update: false },\n { fieldName: 'resetAttempts', columnName: 'reset_attempts', def: { type: 'INTEGER', notNull: true, defaultValue: 0 }, select: true, create: false, update: false },\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: '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: 'firstLoginFailedAt',\n columnName: 'first_login_failed_at',\n def: { type: 'TIMESTAMP' as const },\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.sql 引用比较检测 db 生命周期切换) */\nlet userRepoInstance: UserRepository | null = null\nlet userRepoSqlOps: unknown = null\n\n/**\n * 重置用户存储单例\n *\n * 在 iam.close() 时调用,释放对旧 db 实例的引用。\n * 仅重置本地引用,不删除共享存储数据。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 所有使用该仓储的 IAM 子功能均已关闭后,才清理工厂缓存。\n * resetUserRepoSingleton()\n * ```\n */\nexport function resetUserRepoSingleton(): void {\n userRepoInstance = null\n userRepoSqlOps = null\n}\n\n/**\n * 创建基于数据库的用户存储实例\n *\n * 单例模式:同一 db 生命周期内重复调用返回缓存实例,\n * db 重新初始化后自动创建新实例。\n *\n * @returns 用户存储接口实现\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // RelDB 已初始化;后续仓储读取仍可能失败,必须检查 HaiResult。\n * const repository = await createDbUserRepository()\n * const found = await repository.findByUsername('alice')\n * if (!found.success)\n * return found\n * return found.data?.credentialVersion ?? null\n * ```\n */\nexport async function createDbUserRepository(): Promise<UserRepository> {\n if (userRepoInstance && userRepoSqlOps === reldb.sql)\n return userRepoInstance\n\n const repo = new DbUserRepository()\n // 确保底层表创建完成(BaseReldbCrudRepository 的表创建是异步的)\n await repo.count()\n repo.create = guardIamMutation(repo.create.bind(repo), 1)\n repo.updateById = guardIamMutation(repo.updateById.bind(repo), 2)\n repo.deleteById = guardIamMutation(repo.deleteById.bind(repo), 1)\n repo.suspendInactive = guardIamMutation(repo.suspendInactive.bind(repo))\n repo.setPassword = guardIamMutation(repo.setPassword.bind(repo))\n repo.commitPasswordReset = guardIamMutation(repo.commitPasswordReset.bind(repo))\n userRepoInstance = repo\n userRepoSqlOps = reldb.sql\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 /** 数据库时钟在执行最终 SQL 时核验有效期,暂停进程不能复用旧的 Date.now()。 */\n private databaseNow(): string {\n if (reldb.config?.type === 'postgresql')\n return '(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)'\n if (reldb.config?.type === 'mysql')\n return '(UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000)'\n return 'CAST((julianday(\\'now\\') - 2440587.5) * 86400000 AS INTEGER)'\n }\n\n async recordSuccessfulLogin(userId: string): Promise<HaiResult<void>> {\n const result = await reldb.sql.execute(`UPDATE ${TABLE_NAME} SET last_login_at = ? WHERE id = ?`, [reldb.config?.type === 'sqlite' ? Date.now() : new Date(), userId])\n return result.success ? ok(undefined) : this.buildQueryError(result.error, result.error)\n }\n\n async suspendInactive(cutoff: Date): Promise<HaiResult<number>> {\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET account_status = ?, credential_version = ?, reset_version = ?, reset_hash = NULL, reset_expires_at = NULL WHERE account_status = ? AND COALESCE(last_login_at, created_at) <= ?`,\n ['dormant', crypto.randomUUID(), crypto.randomUUID(), 'active', reldb.config?.type === 'sqlite' ? cutoff.getTime() : cutoff],\n )\n return result.success ? ok(result.data.changes) : this.buildQueryError(result.error, result.error)\n }\n\n /** 改密推进凭据代际;会话存储清理失败也不能让旧凭据恢复授权。 */\n async setPassword(input: { userId: string, expectedVersion: string, passwordHash: string, mustChangePassword?: boolean }): Promise<HaiResult<boolean>> {\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET password_hash = ?, password_updated_at = ?, credential_version = ?, reset_version = ?, must_change_password = ?, reset_hash = NULL, reset_expires_at = NULL, reset_attempts = 0 WHERE id = ? AND credential_version = ?`,\n [input.passwordHash, reldb.config?.type === 'sqlite' ? Date.now() : new Date(), crypto.randomUUID(), crypto.randomUUID(), reldb.config?.type === 'postgresql' ? input.mustChangePassword === true : Number(input.mustChangePassword === true), input.userId, input.expectedVersion],\n )\n return result.success ? ok(result.data.changes === 1) : this.buildQueryError(result.error, result.error)\n }\n\n /** 发布只替换读取到的重置代际;旧发送者暂停后不能覆盖接管节点的新令牌。 */\n async publishPasswordReset(input: { user: StoredUser, tokenHash: string, expiresAt: Date }): Promise<HaiResult<boolean>> {\n const expiry = input.expiresAt.getTime()\n if (!Number.isSafeInteger(expiry))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_resetTokenInvalid'))\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET reset_hash = ?, reset_expires_at = ?, reset_attempts = 0, reset_version = ? WHERE id = ? AND credential_version = ? AND reset_version = ? AND account_status = ? AND ? > ${this.databaseNow()}`,\n [input.tokenHash, expiry, crypto.randomUUID(), input.user.id, input.user.credentialVersion ?? '', input.user.resetVersion ?? '', 'active', expiry],\n )\n return result.success ? ok(result.data.changes === 1) : this.buildQueryError(result.error, result.error)\n }\n\n /** 条件计次返回新代际;业务策略失败也消耗尝试次数。 */\n async claimPasswordReset(tokenHash: string, maxAttempts: number): Promise<HaiResult<StoredUser>> {\n const found = await this.findOneBy('reset_hash = ?', [tokenHash])\n if (!found.success)\n return found\n const user = found.data\n if (!user)\n return err(HaiIamError.RESET_TOKEN_INVALID, iamM('iam_resetTokenInvalid'))\n if (!isUserActive(user))\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n if ((user.resetAttempts ?? 0) >= maxAttempts)\n return err(HaiIamError.RESET_TOKEN_MAX_ATTEMPTS, iamM('iam_resetTokenMaxAttempts'))\n const version = crypto.randomUUID()\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET reset_attempts = reset_attempts + 1, reset_version = ? WHERE id = ? AND reset_hash = ? AND reset_version = ? AND credential_version = ? AND reset_attempts < ? AND reset_expires_at > ${this.databaseNow()} AND account_status = ?`,\n [version, user.id, tokenHash, user.resetVersion ?? '', user.credentialVersion ?? '', maxAttempts, 'active'],\n )\n if (!result.success)\n return this.buildQueryError(result.error, result.error)\n if (result.data.changes !== 1)\n return err(HaiIamError.RESET_TOKEN_INVALID, iamM('iam_resetTokenInvalid'))\n return ok({ ...user, resetVersion: version, resetAttempts: (user.resetAttempts ?? 0) + 1 })\n }\n\n /** 密码与令牌消费同一行原子提交,禁止先消费 Redis 凭据再无条件写数据库。 */\n async commitPasswordReset(input: { user: StoredUser, tokenHash: string, passwordHash: string }): Promise<HaiResult<boolean>> {\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET password_hash = ?, password_updated_at = ?, credential_version = ?, reset_version = ?, must_change_password = FALSE, reset_hash = NULL, reset_expires_at = NULL, reset_attempts = 0, login_failed_count = 0, first_login_failed_at = NULL, locked_until = NULL, last_login_failed_at = NULL WHERE id = ? AND reset_hash = ? AND reset_version = ? AND credential_version = ? AND reset_expires_at > ${this.databaseNow()} AND account_status = ?`,\n [input.passwordHash, reldb.config?.type === 'sqlite' ? Date.now() : new Date(), crypto.randomUUID(), crypto.randomUUID(), input.user.id, input.tokenHash, input.user.resetVersion ?? '', input.user.credentialVersion ?? '', 'active'],\n )\n return result.success ? ok(result.data.changes === 1) : this.buildQueryError(result.error, result.error)\n }\n\n async recordLoginFailure(userId: string, policy: LoginFailurePolicy): Promise<HaiResult<void>> {\n if (policy.lockoutEnabled === false)\n return ok(undefined)\n const sqlite = reldb.config?.type === 'sqlite'\n const timestamp = Date.now()\n const now = sqlite ? timestamp : new Date(timestamp)\n const cutoff = timestamp - (policy.failureWindow ?? 86400) * 1000\n const windowStart = sqlite ? cutoff : new Date(cutoff)\n const deadline = timestamp + policy.lockoutDuration * 1000\n const lockedUntil = sqlite ? deadline : new Date(deadline)\n // 到期解锁是条件更新;后续原子递增不读取进程中的旧计数。\n const expired = await reldb.sql.execute(`UPDATE ${TABLE_NAME} SET login_failed_count = 0, locked_until = NULL, first_login_failed_at = ?, last_login_failed_at = NULL WHERE id = ? AND (locked_until <= ? OR (locked_until IS NULL AND (first_login_failed_at IS NULL OR first_login_failed_at <= ?)))`, [now, userId, now, windowStart])\n if (!expired.success)\n return this.buildQueryError(expired.error, expired.error)\n // 先计算锁定期限再递增次数,避免 MySQL 按 SET 顺序读取已更新的计数而提前锁定。\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET locked_until = CASE WHEN COALESCE(login_failed_count, 0) + 1 >= ? THEN ? ELSE locked_until END, login_failed_count = COALESCE(login_failed_count, 0) + 1, last_login_failed_at = ? WHERE id = ? AND locked_until IS NULL`,\n [policy.maxLoginAttempts, lockedUntil, now, userId],\n )\n if (!result.success)\n return this.buildQueryError(result.error, result.error)\n return ok(undefined)\n }\n\n async resetLoginFailures(userId: string, expectedCredentialVersion: string, lockoutEnabled = true): Promise<HaiResult<void>> {\n const params: unknown[] = [userId, expectedCredentialVersion, 'active']\n if (lockoutEnabled)\n params.push(reldb.config?.type === 'sqlite' ? Date.now() : new Date())\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET login_failed_count = 0, first_login_failed_at = NULL, last_login_failed_at = NULL, locked_until = NULL WHERE id = ? AND credential_version = ? AND account_status = ? ${lockoutEnabled ? 'AND (locked_until IS NULL OR locked_until <= ?)' : ''}`,\n params,\n )\n if (!result.success)\n return this.buildQueryError(result.error, result.error)\n if (result.data.changes === 0) {\n const user = await this.findById(userId)\n if (!user.success)\n return user\n if (!user.data || !isUserActive(user.data))\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n if ((user.data.credentialVersion ?? '') !== expectedCredentialVersion)\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n if (lockoutEnabled && user.data.lockedUntil && user.data.lockedUntil > new Date())\n return err(HaiIamError.USER_LOCKED, iamM('iam_accountLocked'))\n }\n return ok(undefined)\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","/** API Key 权限收敛:始终取主体授权与密钥 scopes 的交集。 */\nimport type { Session } from '../../session/iam-session-types.js'\n\nfunction covers(grant: string, permission: string): boolean {\n return grant === '*' || grant === permission || (grant.endsWith(':*') && permission.startsWith(grant.slice(0, -1)))\n}\n\n/**\n * 仅显式全范围 key 保留角色入口;受限 key 通过操作权限授权,防止角色绕过 scopes。\n * @param access - 已从持久用户/RBAC 核验的当前角色与权限。\n * @param scopes - 当前仍有效的 API Key 权限范围,空数组不授予操作权限。\n * @returns 保留输入其他字段的授权副本;权限只取交集,非显式 * 的 Key 清除角色入口。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const restricted = applyApiKeyScopes({ roles: ['admin'], permissions: ['report:read', 'report:write'] }, ['report:read'])\n * const mayRead = restricted.permissions.includes('report:read')\n * const rolesRemoved = restricted.roles.length === 0\n * ```\n */\nexport function applyApiKeyScopes<T extends Pick<Session, 'roles' | 'permissions'>>(access: T, scopes: readonly string[]): T {\n const permissions = new Set<string>()\n for (const permission of access.permissions) {\n for (const scope of scopes) {\n if (covers(permission, scope))\n permissions.add(scope)\n else if (covers(scope, permission))\n permissions.add(permission)\n }\n }\n return { ...access, roles: scopes.includes('*') ? access.roles : [], permissions: [...permissions] }\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'\nimport { crypto } from '@h-ai/crypto'\n\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n/**\n * 不存在、无本地口令或受限账号执行同类哈希工作后统一拒绝凭据,不验证受限账号密码。\n * @returns 凭据错误;底层哈希故障保留为内部错误,不能静默伪装成认证失败。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const rejected = rejectMissingPasswordCredentials()\n * if (!rejected.success) {\n * const code = rejected.error.code\n * }\n * ```\n */\nexport function rejectMissingPasswordCredentials(): HaiResult<never> {\n // 此固定值仅用于计算量填充,不作为任何账号、密钥或业务凭据保存。\n const padded = crypto.password.hash('dummy-password-to-prevent-timing-leak')\n if (!padded.success)\n return err(HaiIamError.INTERNAL_ERROR, padded.error.message)\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n}\n\n/**\n * 校验凭证类型并进行类型收窄\n *\n * 确保传入的凭证对象的 type 字段与预期匹配,\n * 匹配成功后通过 TypeScript 类型收窄返回具体凭证类型。\n *\n * @param credentials - 统一凭证对象\n * @param type - 预期的凭证类型('password' | 'otp' | 'ldap')\n * @returns 类型匹配返回收窄后的凭证;不匹配返回 INVALID_CREDENTIALS 错误\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const result = ensureCredentialType({ type: 'password', identifier: 'alice', password: 'ExampleOnly123!' }, 'password')\n * if (!result.success)\n * return result\n * return result.data.identifier\n * ```\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * const policy: LoginFailurePolicy = { maxLoginAttempts: 5, lockoutDuration: 900 }\n * const maximumFailures = policy.maxLoginAttempts\n * ```\n */\nexport interface LoginFailurePolicy {\n /** 关闭时不累计、不锁定,忽略历史锁。 */\n lockoutEnabled?: boolean\n /** 首次失败起的固定窗口(秒),默认 86400。 */\n failureWindow?: number\n /** 最大登录失败次数 */\n maxLoginAttempts: number\n /** 锁定时长(秒) */\n lockoutDuration: number\n}\n\n/**\n * 判断账户是否被锁定\n *\n * @param user - 内部用户数据(含 lockedUntil 字段)\n * @param policy - 可选锁定开关;默认启用。\n * @returns 锁定中返回 true;未设置或已到期返回 false\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function canAttempt(user: StoredUser): boolean {\n * return user.accountStatus === 'active' && !isAccountLocked(user)\n * }\n * ```\n */\nexport function isAccountLocked(user: StoredUser, policy?: Pick<LoginFailurePolicy, 'lockoutEnabled'>): boolean {\n if (policy?.lockoutEnabled === false || !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 * @returns 成功返回数据,失败返回业务或基础设施错误;调用方必须先判断 success。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function rejected(repository: UserRepository, user: StoredUser) {\n * const result = await recordLoginFailure(repository, user, { maxLoginAttempts: 5, lockoutDuration: 900 })\n * if (!result.success)\n * return result\n * return result.data\n * }\n * ```\n */\nexport async function recordLoginFailure(\n userRepository: UserRepository,\n user: StoredUser,\n policy: LoginFailurePolicy,\n): Promise<HaiResult<void>> {\n return userRepository.recordLoginFailure(user.id, policy)\n}\n\n/**\n * 重置登录失败计数\n *\n * 登录成功后按当前凭据代际提交,仅启用且未锁定的账户可以清除失败状态。\n * 数据库提交失败必须中止后续会话签发,不在本地修改传入快照。\n *\n * @param userRepository - 用户存储实例\n * @param user - 当前用户数据\n * @param policy - 可选锁定开关;关闭时允许清理历史锁。\n * @returns 成功返回数据,失败返回业务或基础设施错误;调用方必须先判断 success。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function authenticated(repository: UserRepository, user: StoredUser) {\n * const result = await resetLoginFailures(repository, user)\n * if (!result.success)\n * return result\n * return result.data\n * }\n * ```\n */\nexport async function resetLoginFailures(\n userRepository: UserRepository,\n user: StoredUser,\n policy?: Pick<LoginFailurePolicy, 'lockoutEnabled'>,\n): Promise<HaiResult<void>> {\n return userRepository.resetLoginFailures(user.id, user.credentialVersion ?? '', policy?.lockoutEnabled)\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, PaginatedResult } from '@h-ai/core'\nimport type { ApiKeyConfig } from '../../iam-config.js'\nimport type { UserRepository } from '../../user/iam-user-repository-user.js'\nimport type { AuthenticatedUser, AuthStrategy, Credentials } from '../iam-authn-types.js'\nimport type { ApiKeyRepository } from './iam-authn-apikey-repository.js'\nimport type { ApiKey, ApiKeyOperations, CreateApiKeyOptions, CreateApiKeyResult, ListApiKeysOptions } from './iam-authn-apikey-types.js'\nimport { createHash, randomBytes } from 'node:crypto'\nimport { core, err, ok } from '@h-ai/core'\nimport { crypto as haiCrypto } from '@h-ai/crypto'\n\nimport { readIamCache } from '../../iam-cache.js'\nimport { ApiKeyConfigSchema } from '../../iam-config.js'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\nimport { isUserActive, 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 * @internal\n * @example 模块内部上下文\n * ```ts\n * function configure(userRepository: UserRepository, apiKeyRepository: ApiKeyRepository) {\n * const config: ApiKeyStrategyConfig = { userRepository, apiKeyRepository }\n * return createApiKeyStrategy(config)\n * }\n * ```\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function checkedIdentity(result: ApiKeyStrategyResult, credentials: Credentials) {\n * const verified = await result.strategy.authenticate(credentials)\n * if (!verified.success)\n * return verified\n * return { userId: verified.data.user.id, apiKeyId: verified.data.apiKey.id, scopes: verified.data.apiKey.scopes }\n * }\n * ```\n */\nexport interface ApiKeyStrategyResult {\n /** 认证策略保留已验证的 key 身份,避免二次验证或丢失 scopes。 */\n strategy: Omit<AuthStrategy, 'authenticate'> & {\n authenticate: (credentials: Credentials) => Promise<HaiResult<{ user: AuthenticatedUser, apiKey: ApiKey }>>\n }\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 * @param config - 已校验的配置及可信运行时依赖。\n * @returns 基于共享用户/API Key 仓储的认证策略和管理操作;创建工厂本身不签发密钥。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function createManagement(config: ApiKeyStrategyConfig) {\n * const result = createApiKeyStrategy(config)\n * return result.apiKeyFunctions.listApiKeys('user-1', { page: 1, pageSize: 20 })\n * }\n * ```\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 loadRawKey(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 async function verifyRawKey(rawKey: string): Promise<HaiResult<ApiKey>> {\n const fingerprint = createHash('sha256').update(rawKey).digest('hex')\n const result = await readIamCache(`verified_apikey:${fingerprint}`, async () => {\n const verified = await loadRawKey(rawKey)\n return verified.success ? ok({ ...verified.data, expiresAt: verified.data.expiresAt?.getTime() ?? null, createdAt: verified.data.createdAt.getTime(), lastUsedAt: verified.data.lastUsedAt?.getTime() ?? null }) : verified\n })\n if (!result.success)\n return result\n if (!result.data.enabled)\n return err(HaiIamError.APIKEY_DISABLED, iamM('iam_apikeyDisabled'))\n if (result.data.expiresAt !== null && result.data.expiresAt <= Date.now())\n return err(HaiIamError.APIKEY_EXPIRED, iamM('iam_apikeyExpired'))\n return ok({ ...result.data, expiresAt: result.data.expiresAt === null ? null : new Date(result.data.expiresAt), createdAt: new Date(result.data.createdAt), lastUsedAt: result.data.lastUsedAt === null ? null : new Date(result.data.lastUsedAt) })\n }\n\n // ─── AuthStrategy 实现 ───\n\n const strategy: ApiKeyStrategyResult['strategy'] = {\n type: 'apikey',\n name: 'apikey-strategy',\n\n async authenticate(credentials: Credentials) {\n const credentialResult = ensureCredentialType(credentials, 'apikey')\n if (!credentialResult.success) {\n return credentialResult\n }\n\n const { key } = credentialResult.data\n\n // 验证 API Key\n const verifyResult = await verifyRawKey(key)\n if (!verifyResult.success) {\n return verifyResult\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 (!isUserActive(userResult.data)) {\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n }\n\n logger.debug('API Key authentication succeeded', { userId: userResult.data.id, keyId: apiKey.id })\n return ok({ user: { ...toUser(userResult.data), credentialVersion: userResult.data.credentialVersion ?? '' }, apiKey })\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, options?: ListApiKeysOptions): Promise<HaiResult<PaginatedResult<ApiKey>>> {\n const result = await apiKeyRepository.findPageByUserId(userId, options ?? {})\n if (!result.success)\n return result as HaiResult<PaginatedResult<ApiKey>>\n return ok({ ...result.data, items: result.data.items.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","/** 登录许可只依赖配置、服务端时间和宿主可信地址;规则在初始化时编译。 */\nimport type { HaiResult } from '@h-ai/core'\nimport type { IamConfig } from '../iam-config.js'\nimport type { AuthRequestContext } from './iam-authn-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\n/**\n * 创建单个 IAM 实例的登录许可检查器。\n * @param policy - 已由 Schema 校验的策略。\n * @returns 使用可信上下文与服务端时钟的检查函数。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const check = createLoginAccessCheck(undefined)\n * const allowed = check({ ip: '192.0.2.10' })\n * ```\n */\nexport function createLoginAccessCheck(policy: IamConfig['loginAccess']): (context?: AuthRequestContext) => HaiResult<void> {\n if (!policy?.enabled)\n return () => ok(undefined)\n const { enabled: _enabled, ...condition } = policy\n const check = core.access.createConditionCheck(condition)\n return context => check(context?.ip).allowed ? ok(undefined) : err(HaiIamError.LOGIN_ACCESS_DENIED, iamM('iam_loginAccessDenied'))\n}\n","/** 自托管 ALTCHA 挑战;共享 Cache 持有签名秘密与单用状态,不提供通用策略层。 */\nimport type { HaiResult } from '@h-ai/core'\nimport type { IamConfig } from '../iam-config.js'\nimport type { CaptchaOperation, IamCaptchaChallenge } from './iam-authn-types.js'\nimport { randomBytes, randomInt } from 'node:crypto'\nimport { cache } from '@h-ai/cache'\nimport { core, err, ok } from '@h-ai/core'\nimport { createChallenge, pbkdf2, verifySolution } from 'altcha/lib'\nimport { z } from 'zod'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'captcha' })\nconst prefix = 'hai:iam:captcha:'\nconst operationSchema = z.enum(['login', 'register', 'sendOtp', 'passwordReset', 'renewPassword'])\nconst proofSchema = z.object({\n id: z.string().regex(/^[a-f0-9]{64}$/),\n solution: z.object({ counter: z.number().int().min(0).max(2000), derivedKey: z.string().regex(/^[a-f0-9]{64}$/i), time: z.number().finite().nonnegative().optional() }),\n})\n\n/**\n * 共享缓存的服务端记录;秘密不进入公开挑战或业务审计。\n * @example 模块内部上下文\n * ```ts\n * function purpose(record: StoredCaptcha) { return record.operation }\n * ```\n */\ninterface StoredCaptcha {\n operation: CaptchaOperation\n challenge: IamCaptchaChallenge['challenge']\n signatureSecret: string\n keySecret: string\n}\n\n/**\n * 生成可公开挑战;配置来自 IAM 已校验的初始化输入。\n * @example 模块内部上下文\n * ```ts\n * async function create(config: IamConfig['captcha']) {\n * return createIamCaptcha(config, { operation: 'login' })\n * }\n * ```\n */\nexport async function createIamCaptcha(config: IamConfig['captcha'], input: { operation: CaptchaOperation }): Promise<HaiResult<IamCaptchaChallenge>> {\n if (!config.enabled)\n return err(HaiIamError.CAPTCHA_DISABLED, iamM('iam_captchaDisabled'))\n const operation = operationSchema.safeParse(input?.operation)\n if (!operation.success)\n return err(HaiIamError.CAPTCHA_INVALID, iamM('iam_captchaInvalid'))\n try {\n const id = randomBytes(32).toString('hex')\n const signatureSecret = randomBytes(32).toString('hex')\n const keySecret = randomBytes(32).toString('hex')\n const challenge = await createChallenge({\n algorithm: 'PBKDF2/SHA-256',\n cost: config.cost,\n counter: randomInt(1, config.maxCounter + 1),\n deriveKey: pbkdf2.deriveKey,\n hmacSignatureSecret: signatureSecret,\n hmacKeySignatureSecret: keySecret,\n data: { operation: operation.data },\n })\n // Cache 自己的相对 TTL 是到期真值,不用各节点的墙钟延长或重签证明。\n const record: StoredCaptcha = { operation: operation.data, challenge, signatureSecret, keySecret }\n const saved = await cache.kv.set(`${prefix}${id}`, record, { nx: true, ex: config.ttlSeconds })\n if (!saved.success || !saved.data)\n return err(HaiIamError.CAPTCHA_UNAVAILABLE, iamM('iam_captchaUnavailable'))\n return ok({ id, challenge })\n }\n catch (error) {\n logger.error('Captcha challenge generation failed', { operation: operation.data, error })\n return err(HaiIamError.CAPTCHA_UNAVAILABLE, iamM('iam_captchaUnavailable'))\n }\n}\n\n/**\n * 在鉴别/通知之前校验并原子消费;只使用服务端缓存的算法、成本、签名与用途。\n * @example 模块内部上下文\n * ```ts\n * async function check(config: IamConfig['captcha'], proof: string) {\n * const verified = await verifyIamCaptcha(config, 'login', proof)\n * if (!verified.success) return verified\n * // 此后才能进行密码鉴别;业务失败也不能重用已消费的证明。\n * return verified\n * }\n * ```\n */\nexport async function verifyIamCaptcha(config: IamConfig['captcha'], operation: CaptchaOperation, proof?: string): Promise<HaiResult<void>> {\n if (!config.enabled)\n return ok(undefined)\n if (!proof)\n return err(HaiIamError.CAPTCHA_REQUIRED, iamM('iam_captchaRequired'))\n if (typeof proof !== 'string' || proof.length > 4096)\n return err(HaiIamError.CAPTCHA_INVALID, iamM('iam_captchaInvalid'))\n let payload: z.output<typeof proofSchema>\n try {\n const parsed = proofSchema.safeParse(JSON.parse(proof))\n if (!parsed.success)\n return err(HaiIamError.CAPTCHA_INVALID, iamM('iam_captchaInvalid'))\n payload = parsed.data\n }\n catch {\n return err(HaiIamError.CAPTCHA_INVALID, iamM('iam_captchaInvalid'))\n }\n try {\n const key = `${prefix}${payload.id}`\n const found = await cache.kv.get<StoredCaptcha>(key)\n if (!found.success)\n return err(HaiIamError.CAPTCHA_UNAVAILABLE, iamM('iam_captchaUnavailable'))\n if (!found.data || found.data.operation !== operation)\n return err(HaiIamError.CAPTCHA_INVALID, iamM('iam_captchaInvalid'))\n const record = found.data\n const result = await verifySolution({ challenge: record.challenge, solution: payload.solution, deriveKey: pbkdf2.deriveKey, hmacSignatureSecret: record.signatureSecret, hmacKeySignatureSecret: record.keySecret })\n if (!result.verified)\n return err(HaiIamError.CAPTCHA_INVALID, iamM('iam_captchaInvalid'))\n const removed = await cache.kv.del(key)\n if (!removed.success)\n return err(HaiIamError.CAPTCHA_UNAVAILABLE, iamM('iam_captchaUnavailable'))\n return removed.data === 1 ? ok(undefined) : err(HaiIamError.CAPTCHA_INVALID, iamM('iam_captchaInvalid'))\n }\n catch (error) {\n logger.error('Captcha verification failed', { operation, error })\n return err(HaiIamError.CAPTCHA_UNAVAILABLE, iamM('iam_captchaUnavailable'))\n }\n}\n","/** LDAP 默认客户端,应用只需配置连接信息;每次认证独立连接并释放。 */\nimport type { LdapClientFactory } from './iam-authn-ldap-strategy.js'\nimport { err, ok } from '@h-ai/core'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\n\n/**\n * 启用 LDAP 时加载可选 SDK;自定义 ldapClientFactory 不经过此入口。\n * @returns 使用 ldapts 创建独立连接的工厂;缺少可选 SDK 或导入失败会拒绝 Promise。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 应用已安装 ldapts;默认工厂每次创建独立连接。\n * const factory = await loadLdapClientFactory()\n * async function connect(config: Parameters<LdapClientFactory>[0]) {\n * const opened = await factory(config)\n * if (!opened.success)\n * return opened\n * return opened.data.unbind()\n * }\n * ```\n */\nexport async function loadLdapClientFactory(): Promise<LdapClientFactory> {\n const { Client } = await import('ldapts')\n return async (config) => {\n const client = new Client({ url: config.url, connectTimeout: config.connectTimeout, timeout: config.connectTimeout })\n try {\n if (config.useTls && config.url.startsWith('ldap://'))\n await client.startTLS({ minVersion: 'TLSv1.2' })\n return ok({\n async bind(dn, password) {\n // 空密码的 simple bind 可能被服务器当作匿名认证,必须先拒绝。\n if (!password)\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n try {\n await client.bind(dn, password)\n return ok(undefined)\n }\n catch (error) {\n return err(HaiIamError.LDAP_BIND_FAILED, iamM('iam_passwordWrong'), error)\n }\n },\n async search(base, filter, attributes) {\n try {\n const result = await client.search(base, { scope: 'sub', filter, attributes })\n return ok(result.searchEntries.map((entry) => {\n const values: Record<string, string | string[]> = {}\n for (const attribute of attributes) {\n const value = entry[attribute]\n if (typeof value === 'string')\n values[attribute] = value\n else if (Array.isArray(value))\n values[attribute] = value.map(item => String(item))\n else if (value !== undefined)\n values[attribute] = String(value)\n }\n return { dn: entry.dn, attributes: values }\n }))\n }\n catch (error) {\n return err(HaiIamError.LDAP_SEARCH_FAILED, iamM('iam_ldapSearchFailed'), error)\n }\n },\n async unbind() {\n try {\n await client.unbind()\n return ok(undefined)\n }\n catch (error) {\n return err(HaiIamError.LDAP_CONNECTION_FAILED, iamM('iam_ldapConnectionFailed'), error)\n }\n },\n })\n }\n catch (error) {\n await client.unbind().catch(() => {})\n return err(HaiIamError.LDAP_CONNECTION_FAILED, iamM('iam_ldapConnectionFailed'), error)\n }\n }\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 } from '../../user/iam-user-types.js'\nimport type { AuthenticatedUser, 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 { isUserActive, 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 * @internal\n * @example 模块内部上下文\n * ```ts\n * const escaped = escapeLdapFilterValue('alice*)(uid=*)')\n * const filter = `(uid=${escaped})` // 用户输入只作为值,不能扩展过滤表达式。\n * ```\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function lookup(client: LdapClient) {\n * const found = await client.search('ou=users,dc=example,dc=com', '(uid=alice)', ['uid', 'mail'])\n * if (!found.success)\n * return found\n * return found.data.map(entry => entry.dn)\n * }\n * ```\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * const entry: LdapSearchEntry = { dn: 'uid=alice,ou=users,dc=example,dc=com', attributes: { uid: 'alice', mail: ['alice@example.com'] } }\n * const username = entry.attributes.uid\n * ```\n */\nexport interface LdapSearchEntry {\n /** DN */\n dn: string\n /** 属性 */\n attributes: Record<string, string | string[]>\n}\n\n/**\n * LDAP 客户端工厂\n * @example\n * ```ts\n * import type { LdapClientFactory, LdapConfig } from '@h-ai/iam'\n * async function check(factory: LdapClientFactory, config: LdapConfig) {\n * const opened = await factory(config)\n * if (!opened.success)\n * return opened\n * const result = await opened.data.bind(config.bindDn, config.bindPassword)\n * const closed = await opened.data.unbind()\n * if (!closed.success)\n * return closed\n * return result\n * }\n * ```\n */\nexport type LdapClientFactory = (config: LdapConfig) => Promise<HaiResult<LdapClient>>\n\n/**\n * LDAP 认证策略配置\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function configure(ldapConfig: LdapConfig, userRepository: UserRepository, ldapClientFactory: LdapClientFactory) {\n * const config: LdapStrategyConfig = { ldapConfig, userRepository, ldapClientFactory, syncUser: true }\n * return createLdapStrategy(config)\n * }\n * ```\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 lockoutEnabled?: boolean\n failureWindow?: number\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<HaiResult<void>>\n /** 新同步账号的初始生命周期;休眠账号需要管理员激活。 */\n defaultAccountStatus?: 'active' | 'dormant'\n}\n\n/**\n * 创建 LDAP 认证策略\n *\n * 通过 LDAP 目录服务进行用户认证。\n * 支持用户同步到本地数据库、登录失败锁定等能力。\n *\n * @param config - LDAP 策略配置(LDAP 配置、用户存储、客户端工厂等)\n * @returns 认证策略实例\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function authenticate(config: LdapStrategyConfig, credentials: Credentials) {\n * return createLdapStrategy(config).authenticate(credentials)\n * }\n * ```\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 const failurePolicy = { maxLoginAttempts, lockoutDuration, lockoutEnabled: config.lockoutEnabled ?? true, failureWindow: config.failureWindow ?? 86400 }\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 return {\n type: 'ldap',\n name: 'ldap-strategy',\n\n async authenticate(credentials: Credentials): Promise<HaiResult<AuthenticatedUser>> {\n // 类型检查\n const credentialResult = ensureCredentialType(credentials, 'ldap')\n if (!credentialResult.success) {\n return credentialResult as HaiResult<AuthenticatedUser>\n }\n\n const { username, password } = credentialResult.data\n if (!username.trim() || !password)\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\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<AuthenticatedUser>\n }\n\n let storedUser = localUserResult.data as StoredUser | null\n\n if (storedUser) {\n if (!isUserActive(storedUser)) {\n return err(\n HaiIamError.ACCOUNT_UNAVAILABLE,\n iamM('iam_accountUnavailable'),\n )\n }\n\n if (isAccountLocked(storedUser, failurePolicy)) {\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 const failureResult = await recordLoginFailure(userRepository, storedUser, failurePolicy)\n if (!failureResult.success)\n return failureResult\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 accountStatus: config.defaultAccountStatus ?? 'active',\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<AuthenticatedUser>\n }\n storedUser = createdResult.data\n\n // LDAP 新用户同步后回调(分配默认角色等)\n if (storedUser && config.onUserAutoRegistered) {\n try {\n const assigned = await config.onUserAutoRegistered(storedUser.id)\n if (!assigned.success) {\n await userRepository.deleteById(storedUser.id)\n return assigned\n }\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 return err(HaiIamError.USER_NOT_FOUND, iamM('iam_userNotExist'))\n\n const resetResult = await resetLoginFailures(userRepository, storedUser, failurePolicy)\n if (!resetResult.success)\n return resetResult\n logger.debug('LDAP authentication succeeded', { userId: storedUser.id })\n\n return ok({ ...toUser(storedUser), credentialVersion: storedUser.credentialVersion ?? '' })\n }\n finally {\n // 确保解除绑定\n await client.unbind()\n }\n },\n }\n}\n","/**\n * @h-ai/iam — 单身份 CAS 验证码状态;不依赖可过期的进程租约。\n * @module iam-authn-otp-repository-otp\n */\nimport type { HaiResult } from '@h-ai/core'\nimport type { IamNotificationContext } from '../../iam-types.js'\nimport { cache } from '@h-ai/cache'\nimport { core, err, ok } from '@h-ai/core'\nimport { iamM } from '../../iam-i18n.js'\nimport { HaiIamError } from '../../iam-types.js'\n\n/**\n * 单次发布的状态;消费保留冷却期,旧版本不能修改后续发布。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const state: OtpState = { version: crypto.randomUUID(), code: null, attempts: 0, expiresAt: 0, cooldownUntil: 0 }\n * const hasChallenge = state.code !== null\n * ```\n */\ninterface OtpState {\n version: string\n code: string | null\n attempts: number\n expiresAt: number\n cooldownUntil: number\n}\n\n/**\n * 验证码存储;发布、次数和消费都在同一共享 key 原子提交。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // Cache 已初始化;示例消费用户提交的验证码,不回传或记录保存值。\n * const repository = createCacheOtpRepository()\n * const result = await repository.consumeOtp('alice@example.com', '123456', 3)\n * if (!result.success)\n * return result\n * return result.data\n * ```\n */\nexport interface OtpRepository {\n /** 发布成功才允许通知;CAS 冲突拒绝,不能覆盖新代。 */\n issueOtp: (input: { identifier: string, code: string, expiresIn: number, resendInterval: number }) => Promise<HaiResult<IamNotificationContext>>\n /** 比较验证码并原子消费;错误次数的 CAS 只重试同一代。 */\n consumeOtp: (identifier: string, code: string, maxAttempts: number) => Promise<HaiResult<void>>\n}\n\n/**\n * 邮箱转小写,电话移除分隔符;同一身份共用发送与消费状态。\n * @param identifier - 用户提交的邮箱或手机号。\n * @returns 去除首尾空白后的邮箱小写值,或移除空白与连字符的手机号。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const email = normalizeOtpIdentifier(' Alice@Example.com ')\n * const sameIdentity = email === normalizeOtpIdentifier('alice@example.com')\n * ```\n */\nexport function normalizeOtpIdentifier(identifier: string): string {\n const trimmed = identifier.trim()\n return trimmed.includes('@') ? trimmed.toLowerCase() : trimmed.replace(/[\\s-]/g, '')\n}\n\nlet otpRepoInstance: OtpRepository | null = null\n\n/**\n * IAM 关闭时释放仓储引用;共享状态由 cache 管理。\n * 仅重置本地引用,不删除共享存储数据。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 所有 OTP 操作结束并关闭 IAM 后重置本地工厂引用,不删除共享挑战。\n * resetOtpRepoSingleton()\n * ```\n */\nexport function resetOtpRepoSingleton(): void {\n otpRepoInstance = null\n}\n\n/**\n * 创建缓存仓储;生产 cache 必须连接同一支持原子 CAS 的共享后端。\n * @returns 已初始化的内部仓储;初始化失败抛出异常,由上层子功能工厂转换为 HaiResult。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // Cache 已初始化;示例消费用户提交的验证码,不回传或记录保存值。\n * const repository = createCacheOtpRepository()\n * const result = await repository.consumeOtp('alice@example.com', '123456', 3)\n * if (!result.success)\n * return result\n * return result.data\n * ```\n */\nexport function createCacheOtpRepository(): OtpRepository {\n if (otpRepoInstance)\n return otpRepoInstance\n\n const keyFor = (identifier: string) => `hai:iam:otp:${normalizeOtpIdentifier(identifier)}`\n const failure = () => err(HaiIamError.REPOSITORY_ERROR, iamM('iam_securityStateFailed'))\n const invalid = () => err(HaiIamError.OTP_INVALID, iamM('iam_otpNotExistOrExpired'))\n otpRepoInstance = {\n async issueOtp(input) {\n const now = Date.now()\n const state: OtpState = {\n version: crypto.randomUUID(),\n code: input.code,\n attempts: 0,\n expiresAt: now + input.expiresIn * 1000,\n cooldownUntil: now + input.resendInterval * 1000,\n }\n const key = keyFor(input.identifier)\n const current = await cache.kv.get<OtpState>(key)\n if (!current.success)\n return failure()\n if (current.data && current.data.cooldownUntil > Date.now()) {\n return err(HaiIamError.OTP_RESEND_TOO_FAST, iamM('iam_otpResendTooFast', { params: { seconds: Math.ceil((current.data.cooldownUntil - Date.now()) / 1000) } }))\n }\n if (Date.now() >= state.expiresAt)\n return invalid()\n const published = await cache.kv.compareAndSwap(key, current.data ?? undefined, state, { px: Math.max(state.expiresAt, state.cooldownUntil) - Date.now() })\n if (!published.success)\n return failure()\n if (!published.data)\n return err(HaiIamError.SECURITY_BUSY, iamM('iam_securityBusy'))\n if (Date.now() >= state.expiresAt)\n return invalid()\n return ok({ idempotencyKey: `iam-otp:${state.version}`, expiresAt: new Date(state.expiresAt) })\n },\n\n async consumeOtp(identifier, code, maxAttempts) {\n const key = keyFor(identifier)\n let version: string | undefined\n for (let attempt = 0; attempt < 16; attempt++) {\n const current = await cache.kv.get<OtpState>(key)\n if (!current.success)\n return failure()\n const state = current.data\n if (!state || state.code === null || state.expiresAt <= Date.now() || state.attempts >= maxAttempts || (version && state.version !== version))\n return invalid()\n version = state.version\n const correct = core.string.constantTimeEqual(state.code, code)\n const attempts = state.attempts + 1\n const next: OtpState = { ...state, attempts, code: correct || attempts >= maxAttempts ? null : state.code }\n // TTL 包含发送冷却期;消费不能删除冷却状态,也不能重建已过期的 key。\n const committed = await cache.kv.compareAndSwap(key, state, next, { keepTtl: true })\n if (!committed.success)\n return failure()\n if (!committed.data)\n continue\n if (!correct || state.expiresAt <= Date.now())\n return err(HaiIamError.OTP_INVALID, iamM('iam_otpWrong'))\n return ok(undefined)\n }\n return err(HaiIamError.SECURITY_BUSY, iamM('iam_securityBusy'))\n },\n }\n return otpRepoInstance\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 { IamNotificationContext } from '../../iam-types.js'\nimport type { UserRepository } from '../../user/iam-user-repository-user.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 { isUserActive, toUser } from '../../user/iam-user-utils.js'\nimport {\n ensureCredentialType,\n isAccountLocked,\n recordLoginFailure,\n resetLoginFailures,\n} from '../iam-authn-utils.js'\nimport { normalizeOtpIdentifier } from './iam-authn-otp-repository-otp.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'otp-strategy' })\nconst PHONE_IDENTIFIER_REGEX = /^\\+?\\d{8,}$/\nconst PHONE_SEPARATOR_REGEX = /[\\s-]/g\n\n/**\n * OTP 认证策略配置\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function configure(userRepository: UserRepository, otpRepository: OtpRepository) {\n * const config: OtpStrategyConfig = { userRepository, otpRepository, autoRegister: false }\n * return createOtpStrategy(config)\n * }\n * ```\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 lockoutEnabled?: boolean\n failureWindow?: number\n maxLoginAttempts?: number\n /** 锁定时间(秒,默认 900 = 15分钟) */\n lockoutDuration?: number\n /**\n * 用户自动注册后的回调\n *\n * 用于分配默认角色等后处理操作。\n *\n * @param userId - 新创建的用户 ID\n */\n onUserAutoRegistered?: (userId: string) => Promise<HaiResult<void>>\n /** OTP 邮件发送回调(由业务层注入) */\n onOtpSendEmail?: (email: string, code: string, context: IamNotificationContext) => Promise<void>\n /** OTP 短信发送回调(由业务层注入) */\n onOtpSendSms?: (phone: string, code: string, context: IamNotificationContext) => 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 (PHONE_IDENTIFIER_REGEX.test(identifier.replace(PHONE_SEPARATOR_REGEX, ''))) {\n return 'phone'\n }\n return 'unknown'\n}\n\n/**\n * OTP 策略工厂返回值\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function challenge(strategy: OtpStrategyResult) {\n * const issued = await strategy.challenge('alice@example.com')\n * if (!issued.success)\n * return issued\n * return issued.data.expiresAt\n * }\n * ```\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * function authenticate(config: OtpStrategyConfig) {\n * const strategy = createOtpStrategy(config)\n * return strategy.strategy.authenticate({ type: 'otp', identifier: 'alice@example.com', code: '123456' })\n * }\n * ```\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 failurePolicy = { maxLoginAttempts, lockoutDuration, lockoutEnabled: config.lockoutEnabled ?? true, failureWindow: config.failureWindow ?? 86400 }\n const registerConfig = config.registerConfig\n const allowAutoRegister = registerConfig?.enabled ?? config.autoRegister ?? false\n const defaultAccountStatus = registerConfig?.defaultAccountStatus ?? 'active'\n\n const strategy: AuthStrategy = {\n type: 'otp',\n name: 'otp-strategy',\n\n async authenticate(credentials: Credentials) {\n // 类型检查\n const credentialResult = ensureCredentialType(credentials, 'otp')\n if (!credentialResult.success) {\n return credentialResult\n }\n\n const identifier = normalizeOtpIdentifier(credentialResult.data.identifier)\n const { code } = credentialResult.data\n if (!isChannelEnabled(identifier))\n return err(HaiIamError.LOGIN_DISABLED, iamM('iam_identifierTypeNotSupported'))\n\n // 预先加载用户用于账户状态判断\n const userResult = await config.userRepository.findByIdentifier(identifier)\n if (!userResult.success) {\n return userResult\n }\n\n let storedUser = userResult.data\n\n if (storedUser) {\n if (!isUserActive(storedUser)) {\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n }\n\n if (isAccountLocked(storedUser, failurePolicy)) {\n return err(HaiIamError.USER_LOCKED, iamM('iam_accountLocked'))\n }\n }\n\n // 单 key CAS 验证并消费;旧读/重放不能删除新验证码。\n const consumed = await config.otpRepository.consumeOtp(identifier, code, otpConfig.maxAttempts)\n if (!consumed.success) {\n if (storedUser && consumed.error.code === HaiIamError.OTP_INVALID.code) {\n const failed = await recordLoginFailure(config.userRepository, storedUser, failurePolicy)\n if (!failed.success)\n return failed\n }\n return consumed\n }\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 accountStatus: defaultAccountStatus,\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\n }\n storedUser = createdResult.data\n\n // 自动注册后回调(分配默认角色等)\n if (storedUser && config.onUserAutoRegistered) {\n try {\n const assigned = await config.onUserAutoRegistered(storedUser.id)\n if (!assigned.success) {\n await config.userRepository.deleteById(storedUser.id)\n return assigned\n }\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 if (!isUserActive(storedUser))\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n const resetResult = await resetLoginFailures(config.userRepository, storedUser, failurePolicy)\n if (!resetResult.success)\n return resetResult\n logger.debug('OTP authentication succeeded', { userId: storedUser.id })\n\n return ok({ ...toUser(storedUser), credentialVersion: storedUser.credentialVersion ?? '' })\n },\n }\n\n // ─── challenge ───\n\n function isChannelEnabled(identifier: string): boolean {\n const type = identifierType(identifier)\n return (type === 'email' && otpConfig.email && !!config.onOtpSendEmail)\n || (type === 'phone' && otpConfig.sms && !!config.onOtpSendSms)\n }\n\n async function challenge(identifier: string): Promise<HaiResult<{ expiresAt: Date }>> {\n identifier = normalizeOtpIdentifier(identifier)\n if (!isChannelEnabled(identifier))\n return err(HaiIamError.LOGIN_DISABLED, iamM('iam_identifierTypeNotSupported'))\n const code = generateOtpCode(otpConfig.length)\n const saved = await config.otpRepository.issueOtp({ identifier, code, expiresIn: otpConfig.expiresIn, resendInterval: otpConfig.resendInterval })\n if (!saved.success)\n return saved\n const context = saved.data\n const expiresAt = context.expiresAt\n\n // 发布成功后最多调用一次通知;接收端按稳定幂等键去重,异常表示投递结果未知。\n const type = identifierType(identifier)\n if (type === 'email' && config.onOtpSendEmail) {\n try {\n await config.onOtpSendEmail(identifier, code, context)\n }\n catch {\n return err(\n HaiIamError.INTERNAL_ERROR,\n iamM('iam_notificationDeliveryUnknown'),\n )\n }\n }\n else if (type === 'phone' && config.onOtpSendSms) {\n try {\n await config.onOtpSendSms(identifier, code, context)\n }\n catch {\n return err(\n HaiIamError.INTERNAL_ERROR,\n iamM('iam_notificationDeliveryUnknown'),\n )\n }\n }\n else {\n return err(\n HaiIamError.INTERNAL_ERROR,\n iamM('iam_identifierTypeNotSupported'),\n )\n }\n\n const result = { 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 } from '../../user/iam-user-types.js'\nimport type { AuthenticatedUser, 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 { checkPasswordState, isUserActive, toUser } from '../../user/iam-user-utils.js'\nimport { ensureCredentialType, isAccountLocked, recordLoginFailure, rejectMissingPasswordCredentials, resetLoginFailures } from '../iam-authn-utils.js'\n\n/**\n * 密码认证策略配置\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function configure(userRepository: UserRepository) {\n * const config: PasswordStrategyConfig = { userRepository, maxLoginAttempts: 5, lockoutDuration: 900 }\n * return createPasswordStrategy(config)\n * }\n * ```\n */\nexport interface PasswordStrategyConfig {\n /** 密码策略 */\n passwordConfig?: PasswordConfig\n /** 用户存储 */\n userRepository: UserRepository\n /** 最大登录失败次数(默认 5) */\n lockoutEnabled?: boolean\n failureWindow?: number\n maxLoginAttempts?: number\n /** 锁定时间(秒,默认 900 = 15分钟) */\n lockoutDuration?: number\n}\n\n/**\n * 密码策略工厂返回值\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function hashNewPassword(strategy: PasswordStrategyResult, password: string) {\n * const valid = strategy.validatePassword(password)\n * if (!valid.success)\n * return valid\n * return strategy.hashPassword(password)\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' })\nconst PASSWORD_UPPERCASE_REGEX = /[A-Z]/\nconst PASSWORD_LOWERCASE_REGEX = /[a-z]/\nconst PASSWORD_DIGIT_REGEX = /\\d/\nconst PASSWORD_SPECIAL_CHAR_REGEX = /[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/\n\n/**\n * 创建密码认证策略\n * @param config - 已校验的配置及可信运行时依赖。\n * @returns 密码认证策略、强度校验、哈希操作与已解析策略;校验和哈希失败均以 HaiResult 表达。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function authenticate(config: PasswordStrategyConfig, credentials: Credentials) {\n * const strategy = createPasswordStrategy(config)\n * return strategy.strategy.authenticate(credentials)\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 failurePolicy = { maxLoginAttempts, lockoutDuration, lockoutEnabled: config.lockoutEnabled ?? true, failureWindow: config.failureWindow ?? 86400 }\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 && !PASSWORD_UPPERCASE_REGEX.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedUppercase'),\n )\n }\n\n if (passwordConfig.requireLowercase && !PASSWORD_LOWERCASE_REGEX.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedLowercase'),\n )\n }\n\n if (passwordConfig.requireNumber && !PASSWORD_DIGIT_REGEX.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedNumber'),\n )\n }\n\n if (passwordConfig.requireSpecialChar && !PASSWORD_SPECIAL_CHAR_REGEX.test(password)) {\n return err(\n HaiIamError.PASSWORD_POLICY_VIOLATION,\n iamM('iam_passwordNeedSpecialChar'),\n )\n }\n\n const classes = [PASSWORD_UPPERCASE_REGEX, PASSWORD_LOWERCASE_REGEX, PASSWORD_DIGIT_REGEX, PASSWORD_SPECIAL_CHAR_REGEX].filter(pattern => pattern.test(password)).length\n if (classes < passwordConfig.minCharacterClasses)\n return err(HaiIamError.PASSWORD_POLICY_VIOLATION, iamM('iam_passwordCharacterClasses', { params: { count: passwordConfig.minCharacterClasses } }))\n\n return ok(undefined)\n }\n\n /**\n * 先拒绝非激活、到期或锁定账号;公开登录边界统一掩码,不能在受限期间继续猜测密码。\n */\n function checkAccountStatus(user: StoredUser): HaiResult<void> {\n if (!isUserActive(user)) {\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n }\n if (isAccountLocked(user, failurePolicy)) {\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 rejectMissingPasswordCredentials()\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 const failureResult = await recordLoginFailure(config.userRepository, user, failurePolicy)\n if (!failureResult.success)\n return failureResult\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<AuthenticatedUser>> {\n const credentialResult = ensureCredentialType(credentials, 'password')\n if (!credentialResult.success) {\n return credentialResult as HaiResult<AuthenticatedUser>\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 return rejectMissingPasswordCredentials()\n\n // 受限账号不继续验证密码;公开登录边界执行计算填充并隐藏具体状态。\n const statusResult = checkAccountStatus(storedUser)\n if (!statusResult.success)\n return statusResult as HaiResult<AuthenticatedUser>\n const pwResult = await verifyUserPassword(storedUser, password)\n if (!pwResult.success)\n return pwResult as HaiResult<AuthenticatedUser>\n\n // 检查密码是否过期\n const passwordState = checkPasswordState(storedUser, passwordConfig)\n if (!passwordState.success)\n return passwordState\n\n // 登录成功,重置失败计数\n const resetResult = await resetLoginFailures(config.userRepository, storedUser, failurePolicy)\n if (!resetResult.success)\n return resetResult\n logger.debug('Password authentication succeeded', { userId: storedUser.id })\n\n return ok({ ...toUser(storedUser), credentialVersion: storedUser.credentialVersion ?? '' })\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 { IamConfigInput } from '../iam-types.js'\nimport type { AuthResult, Session, SessionOperations } from '../session/iam-session-types.js'\nimport type { UserRepository } from '../user/iam-user-repository-user.js'\nimport type { User } from '../user/iam-user-types.js'\nimport type { ApiKeyStrategyResult } from './apikey/iam-authn-apikey-strategy.js'\nimport type { ApiKey, ApiKeyOperations } from './apikey/iam-authn-apikey-types.js'\nimport type { ApiKeyCredentials, AuthenticatedUser, AuthnOperations, AuthRequestContext, 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 { buildAgreementDisplay } from '../iam-agreement.js'\nimport { AgreementConfigSchema, ApiKeyConfigSchema, LoginConfigSchema, OtpConfigSchema, SecurityConfigSchema } from '../iam-config.js'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { createTicketOperations } from '../ticket/iam-ticket-functions.js'\nimport { createDbUserRepository } from '../user/iam-user-repository-user.js'\nimport { checkPasswordState, isUserActive } from '../user/iam-user-utils.js'\nimport { createDbApiKeyRepository } from './apikey/iam-authn-apikey-repository.js'\nimport { applyApiKeyScopes } from './apikey/iam-authn-apikey-scope.js'\nimport { createApiKeyStrategy } from './apikey/iam-authn-apikey-strategy.js'\nimport { createLoginAccessCheck } from './iam-authn-access.js'\nimport { createIamCaptcha, verifyIamCaptcha } from './iam-authn-captcha.js'\nimport { rejectMissingPasswordCredentials } from './iam-authn-utils.js'\nimport { loadLdapClientFactory } from './ldap/iam-authn-ldap-client.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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function assemble(config: IamConfig, sessionFunctions: SessionOperations, authzFunctions: AuthzOperations) {\n * const deps: AuthnOperationsDeps = { config, sessionFunctions, authzFunctions }\n * return createAuthnOperations(deps)\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?: IamConfigInput['onOtpSendEmail']\n /** OTP 短信发送回调(由业务层注入) */\n onOtpSendSms?: IamConfigInput['onOtpSendSms']\n}\n\n/**\n * 认证子功能工厂返回值\n *\n * 将公共 API 与内部依赖分离,避免将密码策略暴露在公共接口上。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function verify(operations: AuthnOperationsResult, token: string) {\n * const result = await operations.authn.verifyToken(token)\n * if (!result.success)\n * return result\n * return result.data.userId\n * }\n * ```\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 loginRegisteredUser: (user: User, context?: AuthRequestContext) => Promise<HaiResult<AuthResult>>\n}\n\n/**\n * 创建认证子功能\n *\n * 内部创建密码/OTP/LDAP 策略,组装成统一的认证操作接口。\n * @param deps - 由 IAM 生命周期按依赖顺序创建的内部组件。\n * @returns 成功返回数据,失败返回业务或基础设施错误;调用方必须先判断 success。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function assemble(deps: AuthnOperationsDeps) {\n * const result = await createAuthnOperations(deps)\n * if (!result.success)\n * return result\n * return result.data.authn.verifyToken('token-from-authorization-header')\n * }\n * ```\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<HaiResult<void>> {\n if (!config.rbac?.enabled || !config.rbac.defaultRole)\n return ok(undefined)\n const roleResult = await authzFunctions.getRoleByCode(config.rbac.defaultRole)\n if (!roleResult.success)\n return roleResult\n if (!roleResult.data)\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n return authzFunctions.assignRole(userId, roleResult.data.id)\n }\n\n // 密码策略\n const passwordResult = createPasswordStrategy({\n passwordConfig: config.password,\n userRepository,\n maxLoginAttempts: securityConfig.maxLoginAttempts,\n lockoutEnabled: securityConfig.lockoutEnabled,\n failureWindow: securityConfig.failureWindow,\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 lockoutEnabled: securityConfig.lockoutEnabled,\n failureWindow: securityConfig.failureWindow,\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) {\n // 仅在启用目录认证且未注入工厂时加载可选 SDK;缺少 SDK 在 init 时返回配置错误。\n const clientFactory = ldapClientFactory ?? await loadLdapClientFactory()\n ldapStrategy = createLdapStrategy({\n ldapConfig: config.ldap,\n userRepository,\n ldapClientFactory: clientFactory,\n syncUser: ldapSyncUser ?? true,\n defaultAccountStatus: config.register.defaultAccountStatus,\n maxLoginAttempts: securityConfig.maxLoginAttempts,\n lockoutEnabled: securityConfig.lockoutEnabled,\n failureWindow: securityConfig.failureWindow,\n lockoutDuration: securityConfig.lockoutDuration,\n onUserAutoRegistered,\n })\n }\n\n // API Key 策略\n let apiKeyStrategy: ApiKeyStrategyResult['strategy'] | 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 userRepository,\n config,\n })\n\n logger.info('Authn sub-feature initialized')\n return ok({ authn: operations.authn, loginRegisteredUser: operations.loginRegisteredUser, 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\n/**\n * 认证操作内部装配依赖;策略只产出可信身份快照,会话发布由统一流程执行。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function passwordLogin(deps: BuildAuthnDeps, credentials: PasswordCredentials) {\n * return deps.passwordStrategy.authenticate({ type: 'password', ...credentials })\n * }\n * ```\n */\ninterface BuildAuthnDeps {\n userRepository: UserRepository\n passwordStrategy: AuthStrategy\n otpStrategy?: AuthStrategy\n otpChallenge?: (identifier: string) => Promise<HaiResult<{ expiresAt: Date }>>\n ldapStrategy?: AuthStrategy\n apiKeyStrategy?: ApiKeyStrategyResult['strategy']\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): Pick<AuthnOperationsResult, 'authn' | 'loginRegisteredUser'> {\n const {\n passwordStrategy,\n otpStrategy,\n otpChallenge,\n ldapStrategy,\n apiKeyStrategy,\n sessionFunctions,\n authzFunctions,\n userRepository,\n config,\n } = deps\n\n const loginConfig = LoginConfigSchema.parse(config.login ?? {})\n const agreementConfig = AgreementConfigSchema.parse(config.agreements ?? {})\n const checkAccess = createLoginAccessCheck(config.loginAccess)\n\n /**\n * 检查指定登录方式是否被禁用\n *\n * @param type - 登录方式类型\n * @returns 禁用时返回错误 HaiResult,否则返回 null\n */\n function loginDisabled(type: 'password' | 'otp' | 'ldap' | 'apikey'): HaiResult<never> | 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 * 解析认证策略实例\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: AuthenticatedUser, apiKey?: ApiKey, context?: AuthRequestContext): Promise<HaiResult<AuthResult>> {\n const permitted = checkAccess(context)\n if (!permitted.success)\n return permitted\n if (!isUserActive(user))\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n const stored = await userRepository.findById(user.id)\n if (!stored.success)\n return stored\n if (!stored.data || !isUserActive(stored.data))\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n const passwordState = checkPasswordState(stored.data, config.password)\n if (!passwordState.success)\n return passwordState\n const authorization = await authzFunctions.getUserAuthorization(user.id)\n if (!authorization.success)\n return authorization\n const access = authorization.data\n const effective = apiKey ? applyApiKeyScopes(access, apiKey.scopes) : access\n const sessionResult = await sessionFunctions.create({\n userId: user.id,\n expectedCredentialVersion: user.credentialVersion,\n username: user.username,\n displayName: user.displayName,\n avatarUrl: user.avatarUrl,\n ...effective,\n apiKeyId: apiKey?.id,\n apiKeyScopes: apiKey?.scopes,\n terminalType: context?.terminalType ?? (apiKey ? 'api' : 'web'),\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 // 只有真正签发会话的登录才刷新最近使用时间;配额/重复登录拒绝不能延缓休眠。\n const recorded = await userRepository.recordSuccessfulLogin(user.id)\n if (!recorded.success) {\n const revoked = await sessionFunctions.delete(session.accessToken)\n if (!revoked.success)\n logger.error('Failed to revoke session after login timestamp write failure', { userId: user.id, error: revoked.error })\n return recorded\n }\n\n const { credentialVersion, ...publicUser } = user\n void credentialVersion\n return ok({\n user: publicUser,\n tokens: tokenPair,\n ...effective,\n agreements: buildAgreementDisplay(agreementConfig, agreementConfig.showOnLogin),\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',\n credentials: PasswordCredentials | OtpCredentials | LdapCredentials,\n strategy?: AuthStrategy,\n context?: AuthRequestContext,\n ): Promise<HaiResult<AuthResult>> {\n const captcha = await verifyIamCaptcha(config.captcha, 'login', credentials.captcha)\n if (!captcha.success)\n return captcha\n const permitted = checkAccess(context)\n if (!permitted.success)\n return permitted\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 // 不公开生命周期或锁定状态,也不让受限账号继续充当密码/验证码猜测的反馈源。\n if (authResult.error.code === HaiIamError.ACCOUNT_UNAVAILABLE.code || authResult.error.code === HaiIamError.USER_LOCKED.code)\n return rejectMissingPasswordCredentials()\n return authResult as HaiResult<AuthResult>\n }\n\n if (credentials.expectedUserId && credentials.expectedUserId !== authResult.data.id)\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n const result = await buildAuthResult(authResult.data, undefined, context)\n if (!result.success && (result.error.code === HaiIamError.ACCOUNT_UNAVAILABLE.code || result.error.code === HaiIamError.USER_LOCKED.code)) {\n logger.warn('Account eligibility changed during login', { type, userId: authResult.data.id, reason: result.error.code })\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n }\n if (result.success) {\n logger.info('Login succeeded', { type, userId: authResult.data.id })\n }\n return result\n }\n\n async function verifyCurrentSession(accessToken: string): Promise<HaiResult<Session>> {\n const session = await sessionFunctions.verifyToken(accessToken)\n if (!session.success)\n return session\n const authorization = await authzFunctions.getUserAuthorization(session.data.userId)\n if (!authorization.success)\n return authorization\n const current = { ...session.data, ...authorization.data }\n return ok(current.apiKeyId ? applyApiKeyScopes(current, current.apiKeyScopes ?? []) : current)\n }\n\n const tickets = createTicketOperations()\n const sensitive = config.reauthentication\n async function requiresProof(operation: string): Promise<HaiResult<boolean>> {\n if (!sensitive?.enabled)\n return ok(false)\n if (sensitive.operations.includes(operation))\n return ok(true)\n const configured = await authzFunctions.getSensitiveOperations(operation)\n if (!configured.success)\n return configured\n return ok(sensitive.operations.includes(operation) || configured.data.includes(operation))\n }\n\n return { loginRegisteredUser: async (user, context) => {\n const stored = await userRepository.findById(user.id)\n if (!stored.success)\n return stored\n if (!stored.data || !isUserActive(stored.data))\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n return buildAuthResult({ ...user, credentialVersion: stored.data.credentialVersion ?? '' }, undefined, context)\n }, authn: {\n createCaptcha: input => createIamCaptcha(config.captcha, input),\n async reauthenticate(accessToken, password, operation) {\n const required = await requiresProof(operation)\n if (!required.success)\n return required\n if (!required.data)\n return err(HaiIamError.PERMISSION_DENIED, iamM('iam_reauthenticationRequired'))\n const current = await verifyCurrentSession(accessToken)\n if (!current.success)\n return current\n const stored = await userRepository.findById(current.data.userId)\n if (!stored.success)\n return stored\n if (!stored.data)\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n const verified = await passwordStrategy.authenticate({ type: 'password', identifier: stored.data.username, password })\n if (!verified.success)\n return verified\n if (verified.data.credentialVersion !== current.data.credentialVersion)\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n return tickets.issue({ subjectId: current.data.userId, purpose: `iam:reauth:${operation}`, ttlMs: sensitive!.ttlSeconds * 1000, grant: { operation, sessionVersion: current.data.version, credentialVersion: current.data.credentialVersion } })\n },\n\n async checkSensitiveOperation(accessToken, operation, ticket) {\n const current = await verifyCurrentSession(accessToken)\n if (!current.success)\n return current\n const required = await requiresProof(operation)\n if (!required.success)\n return required\n if (!required.data)\n return ok(undefined)\n if (!ticket)\n return err(HaiIamError.REAUTHENTICATION_REQUIRED, iamM('iam_reauthenticationRequired'))\n const proof = await tickets.consume(ticket, { purpose: `iam:reauth:${operation}` })\n if (!proof.success)\n return proof\n if (proof.data.subjectId !== current.data.userId || proof.data.grant.operation !== operation || proof.data.grant.sessionVersion !== current.data.version || proof.data.grant.credentialVersion !== current.data.credentialVersion)\n return err(HaiIamError.REAUTHENTICATION_REQUIRED, iamM('iam_reauthenticationRequired'))\n return ok(undefined)\n },\n\n async login(credentials: PasswordCredentials, context?: AuthRequestContext): Promise<HaiResult<AuthResult>> {\n return loginWithStrategy('password', credentials, passwordStrategy, context)\n },\n\n async loginWithOtp(credentials: OtpCredentials, context?: AuthRequestContext): Promise<HaiResult<AuthResult>> {\n return loginWithStrategy('otp', credentials, otpStrategy, context)\n },\n\n async loginWithLdap(credentials: LdapCredentials, context?: AuthRequestContext): Promise<HaiResult<AuthResult>> {\n return loginWithStrategy('ldap', credentials, ldapStrategy, context)\n },\n\n async loginWithApiKey(credentials: ApiKeyCredentials, context?: AuthRequestContext): Promise<HaiResult<AuthResult>> {\n const disabled = loginDisabled('apikey')\n if (disabled)\n return disabled\n if (!apiKeyStrategy)\n return err(HaiIamError.STRATEGY_NOT_SUPPORTED, iamM('iam_featureNotImplemented'))\n const authenticated = await apiKeyStrategy.authenticate({ type: 'apikey', ...credentials })\n if (!authenticated.success)\n return authenticated\n return buildAuthResult(authenticated.data.user, authenticated.data.apiKey, context)\n },\n\n async logout(accessToken: string): Promise<HaiResult<void>> {\n // 不先读取/滑动 access;过期 access 对应的 refresh 也必须在同一次 CAS 中撤销。\n return sessionFunctions.delete(accessToken)\n },\n\n verifyToken: verifyCurrentSession,\n\n async sendOtp(identifier: string, options?: { captcha?: string }): Promise<HaiResult<{ expiresAt: Date }>> {\n const captcha = await verifyIamCaptcha(config.captcha, 'sendOtp', options?.captcha)\n if (!captcha.success)\n return captcha\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * // RelDB 已初始化;后续仓储读取仍可能失败,必须检查 HaiResult。\n * const repository = await createDbPermissionRepository()\n * const found = await repository.findByCode('report:read')\n * if (!found.success)\n * return found\n * return found.data?.id ?? null\n * ```\n */\nexport interface PermissionRepository extends ReldbCrudRepository<Permission> {\n getSensitiveOperations: (operation?: string) => Promise<HaiResult<string[]>>\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 { fieldName: 'sensitiveOperations', columnName: 'sensitive_operations', def: { type: 'JSON' }, select: true, create: true, update: true },\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.sql 引用比较检测 db 生命周期切换) */\nlet permRepoInstance: PermissionRepository | null = null\nlet permRepoSqlOps: unknown = null\n\n/**\n * 重置权限存储单例\n *\n * 在 iam.close() 时调用,释放对旧 db 实例的引用。\n * 仅重置本地引用,不删除共享存储数据。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 所有使用该仓储的 IAM 子功能均已关闭后,才清理工厂缓存。\n * resetPermissionRepoSingleton()\n * ```\n */\nexport function resetPermissionRepoSingleton(): void {\n permRepoInstance = null\n permRepoSqlOps = null\n}\n\n/**\n * 创建基于数据库的权限存储实例\n *\n * 单例模式:同一 db 生命周期内重复调用返回缓存实例,\n * db 重新初始化后自动创建新实例。\n *\n * @returns 权限存储接口实现\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // RelDB 已初始化;后续仓储读取仍可能失败,必须检查 HaiResult。\n * const repository = await createDbPermissionRepository()\n * const found = await repository.findByCode('report:read')\n * if (!found.success)\n * return found\n * return found.data?.id ?? null\n * ```\n */\nexport async function createDbPermissionRepository(): Promise<PermissionRepository> {\n if (permRepoInstance && permRepoSqlOps === reldb.sql)\n return permRepoInstance\n\n const repo = new DbPermissionRepository()\n await repo.count()\n permRepoInstance = repo\n permRepoSqlOps = reldb.sql\n return repo\n}\n\n/**\n * 基于数据库的权限存储实现\n *\n * 继承 BaseReldbCrudRepository,提供按 code 查找权限的能力。\n */\nclass DbPermissionRepository extends BaseReldbCrudRepository<Permission> implements PermissionRepository {\n async getSensitiveOperations(operation?: string): Promise<HaiResult<string[]>> {\n if (operation !== undefined && (typeof operation !== 'string' || !operation.trim() || operation.length > 128))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_sensitiveOperationsInvalid'))\n const match = reldb.config?.type === 'postgresql'\n ? 'sensitive_operations::jsonb @> CAST(? AS jsonb)'\n : reldb.config?.type === 'mysql'\n ? 'JSON_CONTAINS(sensitive_operations, JSON_QUOTE(?))'\n : 'EXISTS (SELECT 1 FROM json_each(sensitive_operations) WHERE type = \\'text\\' AND value = ?)'\n const params = operation === undefined ? [] : [reldb.config?.type === 'postgresql' ? JSON.stringify([operation]) : operation]\n const result = await reldb.sql.query<{ sensitive_operations: unknown }>(`SELECT sensitive_operations FROM hai_iam_permissions WHERE sensitive_operations IS NOT NULL${operation === undefined ? '' : ` AND ${match} LIMIT 1`}`, params)\n if (!result.success)\n return result\n const operations = new Set<string>()\n try {\n for (const row of result.data) {\n const values: unknown = typeof row.sensitive_operations === 'string' ? JSON.parse(row.sensitive_operations) : row.sensitive_operations\n if (!Array.isArray(values) || values.length > 1000)\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_reauthenticationRequired'))\n for (const value of values as unknown[]) {\n if (typeof value !== 'string' || !value.trim() || value.length > 128)\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_reauthenticationRequired'))\n if (operation === undefined || value.trim() === operation)\n operations.add(value.trim())\n }\n }\n return ok([...operations].sort())\n }\n catch {\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_reauthenticationRequired'))\n }\n }\n\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * const repository = await createDbRolePermissionRepository()\n * if (!repository.success)\n * return repository\n * const result = await repository.data.getPermissionCodesForRoles(['role-1', 'role-2'])\n * if (!result.success)\n * return result\n * return result.data\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function currentRoles(roleRepository: RoleRepository) {\n * const repository = await createDbUserRoleRepository(roleRepository)\n * if (!repository.success)\n * return repository\n * const roles = await repository.data.getRoles('user-1')\n * if (!roles.success)\n * return roles\n * return roles.data.map(role => role.code)\n * }\n * ```\n */\nexport interface UserRoleRepository {\n /** 单次 JOIN 获取授权读取需要的角色 ID/code,避免完整角色模型的额外查询。 */\n getRoleSummaries: (userId: string) => Promise<HaiResult<Array<Pick<Role, 'id' | 'code'>>>>\n /** 一次聚合查询多个角色的成员数 */\n getUserCounts: (roleIds: string[]) => Promise<HaiResult<Map<string, number>>>\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * const repository = await createDbRolePermissionRepository()\n * if (!repository.success)\n * return repository\n * const result = await repository.data.getPermissionCodesForRoles(['role-1', 'role-2'])\n * if (!result.success)\n * return result\n * return result.data\n * ```\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<Permission>(\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)\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<Permission>(\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) {\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 ROLE_TABLE = 'hai_iam_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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function currentRoles(roleRepository: RoleRepository) {\n * const repository = await createDbUserRoleRepository(roleRepository)\n * if (!repository.success)\n * return repository\n * const roles = await repository.data.getRoles('user-1')\n * if (!roles.success)\n * return roles\n * return roles.data.map(role => role.code)\n * }\n * ```\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 getRoleSummaries(userId) {\n return reldb.sql.query<Pick<Role, 'id' | 'code'>>(\n `SELECT r.id, r.code FROM ${USER_ROLE_TABLE} ur JOIN ${ROLE_TABLE} r ON r.id = ur.role_id WHERE ur.user_id = ?`,\n [userId],\n )\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 getUserCounts(roleIds: string[]): Promise<HaiResult<Map<string, number>>> {\n const ids = [...new Set(roleIds)]\n const counts = new Map(ids.map(id => [id, 0]))\n if (ids.length === 0)\n return ok(counts)\n const result = await reldb.sql.query<{ role_id: string, user_count: number | string }>(\n `SELECT role_id, COUNT(DISTINCT user_id) AS user_count FROM ${USER_ROLE_TABLE} WHERE role_id IN (${ids.map(() => '?').join(', ')}) GROUP BY role_id`,\n ids,\n )\n if (!result.success)\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_queryRoleFailed', { params: { message: result.error.message } }), result.error)\n for (const row of result.data)\n counts.set(row.role_id, Number(row.user_count))\n return ok(counts)\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, ExecuteResult, 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 * @internal\n * @example 模块内部上下文\n * ```ts\n * // RelDB 已初始化;后续仓储读取仍可能失败,必须检查 HaiResult。\n * const repository = await createDbRoleRepository()\n * const found = await repository.findByCode('user')\n * if (!found.success)\n * return found\n * return found.data?.id ?? null\n * ```\n */\nexport interface RoleRepository extends ReldbCrudRepository<Role> {\n /** 权限单独更新时锁定角色行并推进更新时间,避免并发替换交错 */\n touch: (roleId: string, tx: DmlWithTxOperations) => Promise<HaiResult<ExecuteResult>>\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.sql 引用比较检测 db 生命周期切换) */\nlet roleRepoInstance: RoleRepository | null = null\nlet roleRepoSqlOps: unknown = null\n\n/**\n * 重置角色存储单例\n *\n * 在 iam.close() 时调用,释放对旧 db 实例的引用。\n * 仅重置本地引用,不删除共享存储数据。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // 所有使用该仓储的 IAM 子功能均已关闭后,才清理工厂缓存。\n * resetRoleRepoSingleton()\n * ```\n */\nexport function resetRoleRepoSingleton(): void {\n roleRepoInstance = null\n roleRepoSqlOps = null\n}\n\n/**\n * 创建基于数据库的角色存储实例\n *\n * 单例模式:同一 db 生命周期内重复调用返回缓存实例,\n * db 重新初始化后自动创建新实例。\n *\n * @returns 角色存储接口实现\n * @internal\n * @example 模块内部上下文\n * ```ts\n * // RelDB 已初始化;后续仓储读取仍可能失败,必须检查 HaiResult。\n * const repository = await createDbRoleRepository()\n * const found = await repository.findByCode('user')\n * if (!found.success)\n * return found\n * return found.data?.id ?? null\n * ```\n */\nexport async function createDbRoleRepository(): Promise<RoleRepository> {\n if (roleRepoInstance && roleRepoSqlOps === reldb.sql)\n return roleRepoInstance\n\n const repo = new DbRoleRepository()\n await repo.count()\n roleRepoInstance = repo\n roleRepoSqlOps = reldb.sql\n return repo\n}\n\n/**\n * 基于数据库的角色存储实现\n *\n * 继承 BaseReldbCrudRepository,提供按 code 查找角色的能力。\n */\nclass DbRoleRepository extends BaseReldbCrudRepository<Role> implements RoleRepository {\n async touch(roleId: string, tx: DmlWithTxOperations): Promise<HaiResult<ExecuteResult>> {\n return tx.execute(`UPDATE ${TABLE_NAME} SET updated_at = ? WHERE id = ?`, [new Date().toISOString(), roleId])\n }\n\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 { core, err, ok } from '@h-ai/core'\nimport { HaiReldbError, reldb } from '@h-ai/reldb'\n\nimport { guardIamMutation, readIamCache } from '../iam-cache.js'\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function assemble(config: IamConfig, session: SessionOperations) {\n * const deps: AuthzOperationsDeps = { config, session }\n * return createAuthzOperations(deps)\n * }\n * ```\n */\nexport interface AuthzOperationsDeps {\n config: IamConfig\n session: SessionOperations\n}\n\n/**\n * 创建授权子功能\n *\n * 内部创建 RBAC 所需的存储层,返回授权管理接口。\n * @param deps - 由 IAM 生命周期按依赖顺序创建的内部组件。\n * @returns 成功返回数据,失败返回业务或基础设施错误;调用方必须先判断 success。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function permission(deps: AuthzOperationsDeps) {\n * const result = await createAuthzOperations(deps)\n * if (!result.success)\n * return result\n * return result.data.checkPermission('user-1', 'report:read')\n * }\n * ```\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({\n ...manager,\n assignRole: guardIamMutation(manager.assignRole, 2),\n removeRole: guardIamMutation(manager.removeRole, 2),\n syncRoles: guardIamMutation(manager.syncRoles, 2),\n createRole: guardIamMutation(manager.createRole, 1),\n updateRole: guardIamMutation(manager.updateRole, 2),\n deleteRole: guardIamMutation(manager.deleteRole, 1),\n createPermission: guardIamMutation(manager.createPermission, 1),\n deletePermission: guardIamMutation(manager.deletePermission, 1),\n assignPermissionToRole: guardIamMutation(manager.assignPermissionToRole, 2),\n removePermissionFromRole: guardIamMutation(manager.removePermissionFromRole, 2),\n setPermissionSensitiveOperations: guardIamMutation(manager.setPermissionSensitiveOperations),\n })\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function authorization(config: RbacManagerConfig) {\n * const roles = await config.userRoleRepository.getRoleIds('user-1')\n * if (!roles.success)\n * return roles\n * return config.rolePermissionRepository.getPermissionCodesForRoles(roles.data)\n * }\n * ```\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 /**\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 * 获取用户所有权限(通过角色聚合,批量 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 /** 在调用方事务中完整替换权限,任何一步失败由外层统一回滚。 */\n async function replaceRolePermissions(roleId: string, permissionIds: string[], tx: DmlWithTxOperations): Promise<HaiResult<void>> {\n const uniqueIds = [...new Set(permissionIds)]\n for (const id of uniqueIds) {\n const permission = await permissionRepository.findById(id, tx)\n if (!permission.success)\n return permission\n if (!permission.data)\n return err(HaiIamError.PERMISSION_NOT_FOUND, iamM('iam_permissionNotExist'))\n }\n const removed = await rolePermissionRepository.removeByRoleId(roleId, tx)\n if (!removed.success)\n return removed\n for (const id of uniqueIds) {\n const assigned = await rolePermissionRepository.assign(roleId, id, tx)\n if (!assigned.success)\n return assigned\n }\n return ok(undefined)\n }\n\n async function getUserAuthorization(userId: string): ReturnType<AuthzOperations['getUserAuthorization']> {\n return readIamCache(`authorization:${userId}`, async () => {\n const rows = await reldb.sql.query<{ role_code: string, permission_code: string | null }>('SELECT r.code AS role_code, p.code AS permission_code FROM hai_iam_user_roles ur JOIN hai_iam_roles r ON r.id = ur.role_id LEFT JOIN hai_iam_role_permissions rp ON rp.role_id = r.id LEFT JOIN hai_iam_permissions p ON p.id = rp.permission_id WHERE ur.user_id = ?', [userId])\n return rows.success ? ok({ roles: [...new Set(rows.data.map(row => row.role_code))], permissions: [...new Set(rows.data.flatMap(row => row.permission_code ? [row.permission_code] : []))] }) : rows\n })\n }\n\n return {\n getSensitiveOperations: operation => rbacConfig.enabled ? readIamCache(`sensitive:${operation ?? '*'}`, () => permissionRepository.getSensitiveOperations(operation)) : Promise.resolve(ok([])),\n async setPermissionSensitiveOperations(permissionId, operations) {\n if (!Array.isArray(operations) || operations.length > 1000 || operations.some(value => typeof value !== 'string' || !value.trim() || value.length > 128))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_sensitiveOperationsInvalid'))\n const updated = await permissionRepository.updateById(permissionId, { sensitiveOperations: [...new Set(operations.map(value => value.trim()))] })\n if (!updated.success)\n return updated\n // MySQL 对相同值的幂等更新可能返回 0,需区分记录不存在与内容未变化。\n if (updated.data.changes === 0) {\n const existing = await permissionRepository.findById(permissionId)\n if (!existing.success)\n return existing\n if (!existing.data)\n return err(HaiIamError.PERMISSION_NOT_FOUND, iamM('iam_permissionNotExist'))\n }\n return ok(undefined)\n },\n async checkPermission(userId: string, permission: string): Promise<HaiResult<boolean>> {\n // RBAC 未启用时,所有权限检查直接放行\n if (!rbacConfig.enabled) {\n return ok(true)\n }\n const authorization = await getUserAuthorization(userId)\n if (!authorization.success)\n return authorization\n return ok(authorization.data.roles.includes(rbacConfig.superAdminRole) || authorization.data.permissions.some(code => matchesPermission(permission, code)))\n },\n\n async getUserPermissions(userId: string): Promise<HaiResult<Permission[]>> {\n return getUserPermissionsInternal(userId)\n },\n\n getUserAuthorization,\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 // 仅在非外部事务时同步会话(外部事务由调用方在 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 // 仅在非外部事务时同步会话(外部事务由调用方在 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\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 const { permissionIds, ...metadata } = 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(metadata, tx)\n if (!createResult.success) {\n if (ownTx)\n await tx.rollback()\n if (createResult.error.code === HaiReldbError.DUPLICATE_ENTRY.code) {\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 (permissionIds !== undefined) {\n const replaced = await replaceRolePermissions(createdResult.data.id, permissionIds, tx)\n if (!replaced.success) {\n if (ownTx)\n await tx.rollback()\n return replaced\n }\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\n return ok(createdResult.data)\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\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 getRoleUserCounts(roleIds): Promise<HaiResult<Map<string, number>>> {\n return userRoleRepository.getUserCounts(roleIds)\n },\n\n async updateRole(roleId, data, tx?: DmlWithTxOperations): Promise<HaiResult<Role>> {\n const { permissionIds, ...metadata } = data\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 = Object.values(metadata).some(value => value !== undefined)\n ? await roleRepository.updateById(roleId, metadata, tx)\n : await roleRepository.touch(roleId, 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 if (permissionIds !== undefined) {\n const replaced = await replaceRolePermissions(roleId, permissionIds, tx)\n if (!replaced.success) {\n if (ownTx)\n await tx.rollback()\n return replaced\n }\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 // 角色代码变更后同步受影响用户的会话(仅在自管事务时,外部事务由调用方在 commit 后同步)\n if (ownTx) {\n const affectedUsersResult = await userRoleRepository.getUserIdsByRoleId(roleId)\n if (affectedUsersResult.success) {\n await Promise.allSettled(\n affectedUsersResult.data.map(userId => 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 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 await Promise.allSettled(\n affectedUserIds.map(userId => syncUserSessionAfterRoleChange(userId)),\n )\n }\n\n logger.info('Role deleted', { roleId })\n return ok(undefined)\n },\n\n // ─── 权限管理 ───\n\n async createPermission(permission, tx?: DmlWithTxOperations): Promise<HaiResult<Permission>> {\n const operations = permission.sensitiveOperations ?? []\n if (!Array.isArray(operations) || operations.length > 1000 || operations.some(value => typeof value !== 'string' || !value.trim() || value.length > 128))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_sensitiveOperationsInvalid'))\n permission = { ...permission, sensitiveOperations: [...new Set(operations.map(value => value.trim()))] }\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 if (createResult.error.code === HaiReldbError.DUPLICATE_ENTRY.code) {\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 return ok(createdResult.data)\n }\n catch (error) {\n if (ownTx)\n await tx.rollback()\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 const escaped = options.search.replace(/[%_\\\\]/g, '\\\\$&')\n const pattern = `%${escaped}%`\n whereClauses.push('(code LIKE ? ESCAPE \\'\\\\\\' OR name LIKE ? ESCAPE \\'\\\\\\')')\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 await Promise.allSettled(\n affectedRoleIds.map(roleId => syncSessionPermissionsForRole(roleId)),\n )\n }\n\n logger.info('Permission deleted', { 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 // 仅在非外部事务时同步会话(外部事务由调用方在 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 // 仅在非外部事务时同步会话(外部事务由调用方在 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","/** 关键 IAM 变更的显式审计装配;不代理对象或复制凭据输入。 */\nimport type { CreateAuditLogInput } from '@h-ai/audit'\nimport type { HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations } from '@h-ai/reldb'\nimport type { ApiKeyOperations, AuthnOperations, AuthRequestContext, AuthResult, AuthzOperations, SessionOperations, UserOperations } from './iam-types.js'\nimport { audit } from '@h-ai/audit'\nimport { core } from '@h-ai/core'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'audit' })\n\n/** 审计失败可观察,但不把已经生效的变更伪装成未执行,避免调用端重复提交。 */\nasync function observe<T>(operation: () => Promise<HaiResult<T>>, event: CreateAuditLogInput | ((result: HaiResult<T>) => CreateAuditLogInput | undefined), tx?: DmlWithTxOperations): Promise<HaiResult<T>> {\n const result = await operation()\n // 自动审计仅在宿主已启用该模块时装配;未选用的辅助能力不产生逐操作错误。\n if (!audit.isInitialized)\n return result\n const fields = typeof event === 'function' ? event(result) : event\n if (!fields)\n return result\n if (tx && !result.success) {\n // 失败的事务可能已不可写;回滚后的失败审计由调用入口记录,保留原始失败。\n logger.warn('IAM transactional operation failed', { action: fields.action, resource: fields.resource, reasonCode: result.error.code })\n return result\n }\n const recorded = await audit.capture({\n ...fields,\n category: 'system',\n outcome: result.success ? 'success' : [401, 403, 409, 423, 429].includes(result.error.httpStatus ?? 500) ? 'denied' : 'failure',\n details: { ...fields.details, ...(!result.success ? { reasonCode: result.error.code } : {}) },\n }, { tx })\n if (!recorded.success) {\n logger.error('IAM event audit failed', { action: fields.action, resource: fields.resource, error: recorded.error })\n // 外部事务中的变更尚未提交,审计写入失败必须使调用者能够回滚。\n if (tx)\n return recorded\n }\n return result\n}\n\nfunction loginEvent(method: string, result: HaiResult<AuthResult>, context?: AuthRequestContext): CreateAuditLogInput {\n return {\n action: 'auth.login',\n resource: 'iam.auth',\n details: { method },\n // 登录结果本身已完成鉴别,不把客户端提交的标识声明当成已验证主体。\n userId: result.success ? result.data.user.id : null,\n actorSnapshot: result.success ? { id: result.data.user.id, username: result.data.user.username, displayName: result.data.user.displayName, roles: result.data.roles } : null,\n ipAddress: context?.ip,\n userAgent: context?.userAgent?.slice(0, 4096),\n requestId: context?.requestId,\n }\n}\n\n/**\n * 所有公开认证方式共用结果审计,成功令牌验证不产生重复事件。\n * @example 模块内部上下文\n * ```ts\n * function instrument(operations: AuthnOperations) { return observeAuth(operations) }\n * ```\n */\nexport function observeAuth(operations: AuthnOperations): AuthnOperations {\n return {\n ...operations,\n login: (credentials, context) => observe(() => operations.login(credentials, context), result => loginEvent('password', result, context)),\n loginWithOtp: (credentials, context) => observe(() => operations.loginWithOtp(credentials, context), result => loginEvent('otp', result, context)),\n loginWithLdap: (credentials, context) => observe(() => operations.loginWithLdap(credentials, context), result => loginEvent('ldap', result, context)),\n loginWithApiKey: (credentials, context) => observe(() => operations.loginWithApiKey(credentials, context), result => loginEvent('apikey', result, context)),\n registerAndLogin: (options, context) => observe(() => operations.registerAndLogin(options, context), result => loginEvent('registration', result, context)),\n logout: token => observe(() => operations.logout(token), { action: 'auth.logout', resource: 'iam.auth' }),\n sendOtp: (identifier, options) => observe(() => operations.sendOtp(identifier, options), { action: 'otp.send', resource: 'iam.auth' }),\n reauthenticate: (token, password, operation) => observe(() => operations.reauthenticate(token, password, operation), { action: 'auth.reauthenticate', resource: 'iam.auth', details: { operation } }),\n checkSensitiveOperation: (token, operation, ticket) => observe(() => operations.checkSensitiveOperation(token, operation, ticket), result => !result.success ? { action: 'auth.sensitive-denied', resource: 'iam.auth', details: { operation } } : undefined),\n }\n}\n\n/**\n * 管理端与自助入口只记录安全字段名称或非敏感策略状态,不复制业务资料。\n * @example 模块内部上下文\n * ```ts\n * function instrument(operations: UserOperations) { return observeUsers(operations) }\n * ```\n */\nexport function observeUsers(operations: UserOperations): UserOperations {\n return {\n ...operations,\n register: options => observe(() => operations.register(options), result => ({ action: 'user.register', resource: 'iam.users', resourceId: result.success ? result.data.user.id : undefined })),\n createUser: options => observe(() => operations.createUser(options), result => ({ action: 'user.create', resource: 'iam.users', resourceId: result.success ? result.data.user.id : undefined })),\n inviteUser: options => observe(() => operations.inviteUser(options), result => ({ action: 'user.invite', resource: 'iam.users', resourceId: result.success ? result.data.user.id : undefined })),\n updateUser: (id, data) => observe(() => operations.updateUser(id, data), { action: 'user.update', resource: 'iam.users', resourceId: id, details: { fields: Object.keys(data), ...(data.accountStatus ? { accountStatus: data.accountStatus } : {}), ...(data.accountType ? { accountType: data.accountType } : {}) } }),\n updateCurrentUser: (token, data) => observe(() => operations.updateCurrentUser(token, data), result => ({ action: 'user.profile', resource: 'iam.users', resourceId: result.success ? result.data.id : undefined, details: { fields: Object.keys(data) } })),\n deleteUser: id => observe(() => operations.deleteUser(id), { action: 'user.delete', resource: 'iam.users', resourceId: id }),\n adminResetPassword: (id, password) => observe(() => operations.adminResetPassword(id, password), { action: 'password.admin-reset', resource: 'iam.users', resourceId: id }),\n changePassword: (id, previous, next) => observe(() => operations.changePassword(id, previous, next), { action: 'password.change', resource: 'iam.users', resourceId: id }),\n changeCurrentUserPassword: (token, previous, next) => observe(() => operations.changeCurrentUserPassword(token, previous, next), { action: 'password.change', resource: 'iam.users' }),\n renewPassword: input => observe(() => operations.renewPassword(input), { action: 'password.renew', resource: 'iam.users' }),\n requestPasswordReset: (identifier, options) => observe(() => operations.requestPasswordReset(identifier, options), { action: 'password.reset-request', resource: 'iam.users' }),\n confirmPasswordReset: (token, password) => observe(() => operations.confirmPasswordReset(token, password), { action: 'password.reset-complete', resource: 'iam.users' }),\n scanInactiveAccounts: () => observe(() => operations.scanInactiveAccounts(), result => result.success && result.data === 0 ? undefined : { action: 'account.inactivity-scan', resource: 'iam.users', details: result.success ? { count: result.data } : {} }),\n }\n}\n\n/**\n * 外部事务内使用同一连接记录成功变更;回滚同步移除成功事件。\n * @example 模块内部上下文\n * ```ts\n * function instrument(operations: AuthzOperations) { return observeAuthorization(operations) }\n * ```\n */\nexport function observeAuthorization(operations: AuthzOperations): AuthzOperations {\n return {\n ...operations,\n assignRole: (id, roleId, tx) => observe(() => operations.assignRole(id, roleId, tx), { action: 'role.assign', resource: 'iam.user-roles', resourceId: id, details: { roleId } }, tx),\n removeRole: (id, roleId, tx) => observe(() => operations.removeRole(id, roleId, tx), { action: 'role.remove', resource: 'iam.user-roles', resourceId: id, details: { roleId } }, tx),\n syncRoles: (id, roleIds, tx) => observe(() => operations.syncRoles(id, roleIds, tx), { action: 'role.sync', resource: 'iam.user-roles', resourceId: id, details: { roleIds } }, tx),\n createRole: (input, tx) => observe(() => operations.createRole(input, tx), result => ({ action: 'role.create', resource: 'iam.roles', resourceId: result.success ? result.data.id : undefined, details: { code: input.code } }), tx),\n updateRole: (id, data, tx) => observe(() => operations.updateRole(id, data, tx), { action: 'role.update', resource: 'iam.roles', resourceId: id, details: { fields: Object.keys(data), permissionIds: data.permissionIds } }, tx),\n deleteRole: (id, tx) => observe(() => operations.deleteRole(id, tx), { action: 'role.delete', resource: 'iam.roles', resourceId: id }, tx),\n createPermission: (input, tx) => observe(() => operations.createPermission(input, tx), result => ({ action: 'permission.create', resource: 'iam.permissions', resourceId: result.success ? result.data.id : undefined, details: { code: input.code } }), tx),\n setPermissionSensitiveOperations: (id, operationIds) => observe(() => operations.setPermissionSensitiveOperations(id, operationIds), { action: 'permission.sensitive-operations', resource: 'iam.permissions', resourceId: id, details: { operations: operationIds } }),\n deletePermission: (id, tx) => observe(() => operations.deletePermission(id, tx), { action: 'permission.delete', resource: 'iam.permissions', resourceId: id }, tx),\n assignPermissionToRole: (id, permissionId, tx) => observe(() => operations.assignPermissionToRole(id, permissionId, tx), { action: 'permission.assign', resource: 'iam.role-permissions', resourceId: id, details: { permissionId } }, tx),\n removePermissionFromRole: (id, permissionId, tx) => observe(() => operations.removePermissionFromRole(id, permissionId, tx), { action: 'permission.remove', resource: 'iam.role-permissions', resourceId: id, details: { permissionId } }, tx),\n }\n}\n\n/**\n * 会话本身随机令牌不进入审计;记录主体、会话版本与撤销/刷新结果。\n * @example 模块内部上下文\n * ```ts\n * function instrument(operations: SessionOperations) { return observeSessions(operations) }\n * ```\n */\nexport function observeSessions(operations: SessionOperations): SessionOperations {\n return {\n ...operations,\n create: options => observe(() => operations.create(options), result => ({ action: 'session.create', resource: 'iam.sessions', resourceId: result.success ? result.data.version : options.userId })),\n delete: token => observe(() => operations.delete(token), { action: 'session.delete', resource: 'iam.sessions' }),\n deleteByUserId: id => observe(() => operations.deleteByUserId(id), result => ({ action: 'session.revoke-user', resource: 'iam.sessions', resourceId: id, details: result.success ? { count: result.data } : {} })),\n refresh: token => observe(() => operations.refresh(token), { action: 'session.refresh', resource: 'iam.sessions' }),\n revokeRefresh: token => observe(() => operations.revokeRefresh(token), { action: 'session.revoke-refresh', resource: 'iam.sessions' }),\n }\n}\n\n/**\n * 只记录 API Key ID 与授权范围,明文密钥及哈希从不进入审计输入。\n * @example 模块内部上下文\n * ```ts\n * function instrument(operations: ApiKeyOperations) { return observeApiKeys(operations) }\n * ```\n */\nexport function observeApiKeys(operations: ApiKeyOperations): ApiKeyOperations {\n return {\n ...operations,\n createApiKey: (userId, options) => observe(() => operations.createApiKey(userId, options), result => ({ action: 'apikey.create', resource: 'iam.apikeys', resourceId: result.success ? result.data.apiKey.id : undefined, details: { subjectId: userId, scopes: options.scopes } })),\n revokeApiKey: id => observe(() => operations.revokeApiKey(id), { action: 'apikey.revoke', resource: 'iam.apikeys', resourceId: id }),\n }\n}\n","/** IAM 自己维护持久凭据兼容,不要求业务修改用户表。 */\nimport type { SchemaMigration } from '@h-ai/reldb'\nimport { ok } from '@h-ai/core'\nimport { migrateSchema, reldb, schemaColumns } from '@h-ai/reldb'\n\nconst columns = { credential_version: 'VARCHAR(255) NOT NULL DEFAULT \\'\\'', reset_version: 'VARCHAR(255) NOT NULL DEFAULT \\'\\'', reset_hash: 'TEXT', reset_expires_at: 'BIGINT', reset_attempts: 'INTEGER NOT NULL DEFAULT 0' }\nconst accountColumns = { account_type: 'VARCHAR(16) NOT NULL DEFAULT \\'permanent\\'', account_status: 'VARCHAR(16) NOT NULL DEFAULT \\'active\\'', account_expires_at: 'TIMESTAMP', last_login_at: 'TIMESTAMP' }\nconst steps: SchemaMigration[] = [{\n version: 1,\n name: 'credential-and-reset-versions',\n async needed(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_users', sql)\n return found.success ? ok(found.data.length > 0 && Object.keys(columns).some(name => !found.data.includes(name))) : found\n },\n async apply(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_users', sql)\n if (!found.success)\n return found\n for (const [name, definition] of Object.entries(columns)) {\n if (found.data.includes(name))\n continue\n const added = await sql.execute(`ALTER TABLE hai_iam_users ADD COLUMN ${name} ${definition}`)\n if (!added.success)\n return added\n }\n return ok(undefined)\n },\n}, {\n version: 2,\n name: 'account-lifecycle',\n async needed(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_users', sql)\n return found.success ? ok(found.data.length > 0 && Object.keys(accountColumns).some(name => !found.data.includes(name))) : found\n },\n async apply(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_users', sql)\n if (!found.success)\n return found\n for (const [name, definition] of Object.entries(accountColumns)) {\n if (found.data.includes(name))\n continue\n const added = await sql.execute(`ALTER TABLE hai_iam_users ADD COLUMN ${name} ${definition}`)\n if (!added.success)\n return added\n }\n return ok(undefined)\n },\n}, {\n version: 3,\n name: 'initial-password-state',\n async needed(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_users', sql)\n return found.success ? ok(found.data.length > 0 && !found.data.includes('must_change_password')) : found\n },\n async apply(sql) {\n const added = await sql.execute('ALTER TABLE hai_iam_users ADD COLUMN must_change_password BOOLEAN NOT NULL DEFAULT FALSE')\n return added.success ? ok(undefined) : added\n },\n}, {\n version: 4,\n name: 'login-failure-window',\n async needed(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_users', sql)\n return found.success ? ok(found.data.length > 0 && !found.data.includes('first_login_failed_at')) : found\n },\n async apply(sql) {\n const added = await sql.execute('ALTER TABLE hai_iam_users ADD COLUMN first_login_failed_at TIMESTAMP')\n return added.success ? ok(undefined) : added\n },\n}, {\n version: 5,\n name: 'permission-sensitive-operations',\n async needed(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_permissions', sql)\n return found.success ? ok(found.data.length > 0 && !found.data.includes('sensitive_operations')) : found\n },\n async apply(sql) {\n const added = await sql.execute('ALTER TABLE hai_iam_permissions ADD COLUMN sensitive_operations JSON')\n return added.success ? ok(undefined) : added\n },\n}, {\n version: 6,\n name: 'account-lifecycle-only',\n async needed(sql) {\n const found = await schemaColumns(reldb, 'hai_iam_users', sql)\n return found.success ? ok(found.data.includes('enabled')) : found\n },\n async apply(sql) {\n // 旧停用或空开关不能在删列后变为可登录状态;已休眠/注销的账号保持原状态。\n // 同时推进被转换账号的凭据代际,旧会话和重置凭据不能因升级恢复有效。\n const converted = await sql.execute('UPDATE hai_iam_users SET account_status = ?, credential_version = ?, reset_version = ?, reset_hash = NULL, reset_expires_at = NULL WHERE (enabled = ? OR enabled IS NULL) AND account_status = ?', ['dormant', globalThis.crypto.randomUUID(), globalThis.crypto.randomUUID(), reldb.config?.type === 'postgresql' ? false : 0, 'active'])\n if (!converted.success)\n return converted\n const removed = await sql.execute('ALTER TABLE hai_iam_users DROP COLUMN enabled')\n return removed.success ? ok(undefined) : removed\n },\n}]\n\n/**\n * 预检或迁移 IAM 表。保留用户与密码;旧停用账号转休眠,删除 enabled,旧版 SDK 不可与新表混用。\n * @example\n * ```ts\n * import { migrateIam } from '@h-ai/iam'\n * const plan = await migrateIam({ dryRun: true }) // RelDB 已初始化;只读。\n * ```\n */\nexport function migrateIam(options: { dryRun?: boolean } = {}) {\n return migrateSchema(reldb, 'iam', steps, options)\n}\n","/** 将已初始化 Reach 的标准模板接入 IAM,显式回调可覆盖默认发送。 */\nimport type { IamConfigInput, IamNotificationContext } from './iam-types.js'\nimport { iamM } from './iam-i18n.js'\n\n/**\n * 返回实际可用的回调;SDK/投递异常由 IAM 的公共边界转为 HaiResult。\n * @param input - 应用注入的 IAM 设置与运行时依赖。\n * @returns 已注入或能由现有 Reach 模板提供的通知回调;不具备发送实现的字段保持 undefined。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const callbacks = await resolveIamNotifications({ login: { otp: false }, passwordReset: { enabled: false } })\n * const emailConfigured = callbacks.onOtpSendEmail !== undefined\n * ```\n */\nexport async function resolveIamNotifications(input: IamConfigInput): Promise<Pick<IamConfigInput, 'onOtpSendEmail' | 'onOtpSendSms' | 'onPasswordResetRequest'>> {\n const callbacks = { onOtpSendEmail: input.onOtpSendEmail, onOtpSendSms: input.onOtpSendSms, onPasswordResetRequest: input.onPasswordResetRequest }\n const reach = input.reach\n if (!reach?.isInitialized)\n return callbacks\n // 已关闭的功能和显式回调不依赖 Reach;只为缺少发送实现的通道查询模板。\n const needsEmail = input.login?.otp !== false && !!input.otp && input.otp.email !== false && !callbacks.onOtpSendEmail\n const needsSms = input.login?.otp !== false && !!input.otp && input.otp.sms !== false && !callbacks.onOtpSendSms\n const needsReset = input.passwordReset?.enabled !== false && !callbacks.onPasswordResetRequest\n if (!needsEmail && !needsSms && !needsReset)\n return callbacks\n const templates = await reach.template.list()\n if (!templates.success)\n throw new Error(iamM('iam_securityStateFailed'))\n const configured = new Map(templates.data.map(template => [template.name, template.provider]))\n async function send(template: string, to: string, vars: Record<string, string>, context: IamNotificationContext) {\n const provider = configured.get(template)\n if (!reach?.isInitialized || !provider || !to)\n throw new Error(iamM('iam_passwordResetDeliveryFailed'))\n // Reach 的返回结果与投递状态都必须成功,不能把 HTTP/调用完成当作通知送达。\n const result = await reach.send({ provider, to, template, vars, idempotencyKey: context.idempotencyKey, sensitive: true, expiresAt: context.expiresAt.getTime() })\n if (!result.success || !result.data.success)\n throw new Error(iamM('iam_passwordResetDeliveryFailed'))\n }\n if (needsEmail && configured.has('otp_email'))\n callbacks.onOtpSendEmail = (email, code, context) => send('otp_email', email, { code }, context)\n if (needsSms && configured.has('otp_sms'))\n callbacks.onOtpSendSms = (phone, code, context) => send('otp_sms', phone, { code }, context)\n const resetTemplate = input.passwordReset?.mode === 'phone' ? 'password_reset_sms' : 'password_reset'\n if (needsReset && configured.has(resetTemplate)) {\n callbacks.onPasswordResetRequest = (user, token, context) => {\n const url = input.passwordReset?.resetUrl ? new URL(input.passwordReset.resetUrl) : null\n url?.searchParams.set('token', token)\n const vars = { token, expiresAt: context.expiresAt.toISOString(), resetUrl: url?.toString() ?? token }\n return send(resetTemplate, input.passwordReset?.mode === 'phone' ? user.phone ?? '' : user.email ?? '', vars, context)\n }\n }\n return callbacks\n}\n","/** 提供给认证页面的白名单配置;不含连接信息、密钥及安全状态。 */\nimport type { IamConfig } from './iam-config.js'\nimport type { IamConfigInput } from './iam-types.js'\nimport { AuthUiConfigSchema, OtpConfigSchema, PasswordConfigSchema, SessionConfigSchema } from './iam-config.js'\n\n/**\n * 认证页面可读取的白名单配置;能力开关同时考虑实际运行时依赖,不能用于服务端授权。\n * @example\n * ```ts\n * import { iam, type IamPublicConfig } from '@h-ai/iam'\n * const config: IamPublicConfig | null = iam.publicConfig\n * if (config) {\n * const canOfferEmailOtp = config.login.email\n * const passwordMinLength = config.password.minLength\n * }\n * ```\n */\nexport interface IamPublicConfig {\n /** 只公开是否需要交互挑战,不公开秘密或缓存状态。 */\n captcha: { enabled: boolean }\n /** 页面显示密码策略,不包含密码哈希或账户信息。 */\n password: ReturnType<typeof PasswordConfigSchema.parse>\n /** 自助注册开关;管理端创建账户仍需要独立授权。 */\n register: { enabled: boolean }\n /** 方式开关同时考虑配置和发送回调就绪状态,避免展示无法使用的入口。 */\n login: { password: boolean, otp: boolean, ldap: boolean, email: boolean, sms: boolean }\n /** 重置能力同时要求配置启用和通知发送回调就绪。 */\n passwordReset: { enabled: boolean, mode: 'email' | 'phone' }\n /** 单位:验证码位数、重发间隔秒;安全计数与期限只由服务端执行。 */\n otp: { length: number, resendInterval: number }\n /** 用户协议及隐私政策展示配置。 */\n agreements: IamConfig['agreements']\n /** 已经由外观 Schema 校验的标题、图像 URL 和布局。 */\n ui: ReturnType<typeof AuthUiConfigSchema.parse>\n /** 默认 access 有效时长,单位秒;真实认证期限由服务端会话状态决定。 */\n session: { maxAge: number, endOnPageHide: boolean }\n /** 仅公开操作清单,便于界面在选定操作前请求再鉴别。 */\n reauthentication: { enabled: boolean, operations: string[] }\n /** 邀请入口同时要求开关、密码重置与通知通道就绪。 */\n initialCredentials: { enabled: boolean }\n}\n\n/**\n * 仅公布配置已启用且具备运行时依赖的认证能力。\n * @param config - IamConfigSchema 解析后的设置,不含回调与密钥。\n * @param runtime - 已解析通知回调等运行时依赖;决定哪些已配置入口实际可用。\n * @returns 可序列化给认证页面的配置白名单;不含连接信息与认证凭据。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function availableEmailOtp(settings: IamConfig, runtime: IamConfigInput) {\n * return buildIamPublicConfig(settings, runtime).login.email\n * }\n * ```\n */\nexport function buildIamPublicConfig(config: IamConfig, runtime: IamConfigInput): IamPublicConfig {\n const otp = OtpConfigSchema.parse(config.otp ?? {})\n const session = SessionConfigSchema.parse(config.session ?? {})\n const email = config.login.otp && !!config.otp && otp.email && !!runtime.onOtpSendEmail\n const sms = config.login.otp && !!config.otp && otp.sms && !!runtime.onOtpSendSms\n return {\n captcha: { enabled: config.captcha.enabled },\n password: PasswordConfigSchema.parse(config.password ?? {}),\n register: { enabled: config.register.enabled },\n login: { password: config.login.password, otp: email || sms, ldap: config.login.ldap && !!config.ldap, email, sms },\n passwordReset: { enabled: config.passwordReset?.enabled !== false && !!runtime.onPasswordResetRequest, mode: config.passwordReset?.mode ?? 'email' },\n otp: { length: otp.length, resendInterval: otp.resendInterval },\n agreements: { ...config.agreements },\n ui: AuthUiConfigSchema.parse(config.ui ?? {}),\n session: { maxAge: session.maxAge, endOnPageHide: session.endOnPageHide },\n reauthentication: { enabled: config.reauthentication?.enabled ?? false, operations: [...config.reauthentication?.operations ?? []] },\n initialCredentials: { enabled: Boolean(config.initialCredentials?.enabled && config.passwordReset?.enabled !== false && runtime.onPasswordResetRequest) },\n }\n}\n","import type { UserRepository } from './user/iam-user-repository-user.js'\nimport { ok } from '@h-ai/core'\nimport { readIamCache } from './iam-cache.js'\n\n/**\n * 缓存只包含验证会话所需的非秘密状态;期限每次按当前时间核验。\n * @example 模块内部上下文\n * ```ts\n * async function securityExample(repository: UserRepository) {\n * const result = await readIamUserSecurity(repository, 'user-1')\n * if (!result.success) return result\n * return result.data?.accountStatus\n * }\n * ```\n */\nexport async function readIamUserSecurity(repository: UserRepository, userId: string) {\n // 状态投影升级后不复用包含旧启用开关的缓存;写入仍走同一共享代际栅栏。\n const found = await readIamCache(`user:v2:${userId}`, async () => {\n const row = await repository.findById(userId)\n if (!row.success)\n return row\n const user = row.data\n return ok(user\n ? {\n username: user.username,\n displayName: user.displayName,\n avatarUrl: user.avatarUrl,\n accountType: user.accountType,\n accountStatus: user.accountStatus,\n accountExpiresAt: user.accountExpiresAt ? new Date(user.accountExpiresAt).getTime() : null,\n credentialVersion: user.credentialVersion ?? '',\n mustChangePassword: user.mustChangePassword,\n hasPassword: !!user.passwordHash,\n passwordUpdatedAt: user.passwordUpdatedAt?.getTime() ?? null,\n }\n : null)\n })\n return found.success\n ? ok(found.data\n ? { ...found.data, accountExpiresAt: found.data.accountExpiresAt === null ? null : new Date(found.data.accountExpiresAt), passwordUpdatedAt: found.data.passwordUpdatedAt === null ? undefined : new Date(found.data.passwordUpdatedAt), passwordHash: found.data.hasPassword ? 'present' : undefined }\n : null)\n : found\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function seed(authz: AuthzOperations) {\n * const result = await seedIamData(authz)\n * if (!result.success)\n * return result\n * return result.data\n * }\n * ```\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 if (!existingRoles.success)\n return existingRoles\n const existingRoleMap = new Map<string, string>()\n for (const role of existingRoles.data.items)\n existingRoleMap.set(role.code, role.id)\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 if (result.error.code === HaiIamError.ROLE_ALREADY_EXISTS.code) {\n // 另一个节点已提交相同种子;只复用身份,不覆盖已有角色配置。\n const concurrent = await authz.getRoleByCode(role.code)\n if (!concurrent.success)\n return concurrent\n if (!concurrent.data)\n return result\n roleMap.set(role.code, concurrent.data.id)\n }\n else {\n return result\n }\n }\n\n // 查询现有权限,避免重复创建\n const existingPerms = await authz.getAllPermissions({ page: 1, pageSize: 1000 })\n if (!existingPerms.success)\n return existingPerms\n const existingPermMap = new Map<string, string>()\n for (const perm of existingPerms.data.items)\n existingPermMap.set(perm.code, perm.id)\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 if (result.error.code === HaiIamError.PERMISSION_ALREADY_EXISTS.code) {\n const concurrent = await authz.getPermissionByCode(perm.code)\n if (!concurrent.success)\n return concurrent\n if (!concurrent.data)\n return result\n permMap.set(perm.code, concurrent.data.id)\n }\n else {\n return result\n }\n }\n\n // 管理员分配所有权限\n const adminRoleId = roleMap.get('admin')\n if (adminRoleId) {\n for (const [, permId] of permMap) {\n const assigned = await authz.assignPermissionToRole(adminRoleId, permId)\n if (!assigned.success)\n return assigned\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 const assigned = await authz.assignPermissionToRole(userRoleId, permId)\n if (!assigned.success)\n return assigned\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 * 同一用户的会话、refresh 消费状态与索引放入一个版本化文档,单键 CAS 原子提交。\n * Cluster 只访问一个 slot,不使用进程锁、租约或跨 key 补偿发布认证状态。\n * @module iam-session-repository-cache\n */\nimport type { HaiResult } from '@h-ai/core'\nimport type { SessionConfig } from '../iam-config.js'\nimport type { Session, TokenPair } from './iam-session-types.js'\nimport { cache } from '@h-ai/cache'\nimport { err, ok } from '@h-ai/core'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { applySessionPatch, getTokenSessionScope, getUserSessionScope } from './iam-session-utils.js'\n\n/**\n * 文档内单个会话及 refresh 凭据,不建立可能失配的第二份索引。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function accessExpired(record: StoredSession, now: Date): boolean {\n * return record.session.expiresAt <= now\n * }\n * ```\n */\ninterface StoredSession {\n session: Session\n refreshToken?: string\n refreshExpiresAt: number\n}\n\n/** 单条记录的保留期限;刷新凭据不延长 access 的认证期限。 */\nfunction retainedUntil(entry: StoredSession): number {\n return Math.max(new Date(entry.session.expiresAt).getTime(), entry.refreshToken ? entry.refreshExpiresAt : 0)\n}\n\n/**\n * 用户状态快照;revision 防止删除/重建或同值写入产生 ABA。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const state: SessionState = { revision: crypto.randomUUID(), sessions: {} }\n * const recordCount = Object.keys(state.sessions).length\n * ```\n */\ninterface SessionState {\n revision: string\n sessions: Record<string, StoredSession>\n}\n\n/** 恢复私有 JSON 日期,拒绝损坏的授权数据;错误不包含认证快照。 */\nfunction restoreSession(session: Session): Session {\n const result = { ...session, createdAt: new Date(session.createdAt), startedAt: new Date(session.startedAt ?? session.createdAt), lastActiveAt: new Date(session.lastActiveAt), expiresAt: new Date(session.expiresAt) }\n if ((result.terminalType !== undefined && !['web', 'app', 'desktop', 'api'].includes(result.terminalType)) || typeof result.credentialVersion !== 'string' || !result.version || !Number.isSafeInteger(result.maxAge) || result.maxAge <= 0 || !Array.isArray(result.roles) || !result.roles.every(role => typeof role === 'string')\n || !Array.isArray(result.permissions) || !result.permissions.every(permission => typeof permission === 'string')\n || ![result.createdAt, result.startedAt, result.lastActiveAt, result.expiresAt].every(date => Number.isFinite(date.getTime()))) {\n throw new TypeError('Invalid session state')\n }\n return result\n}\n\n/** 分区仅由经过格式约束的 SHA-256 提示构成,不接受任意 key/hash tag。 */\nfunction stateKey(scope: string): string {\n return `hai:iam:sessions:{${scope}}`\n}\n\n/** 保存基础设施原因,面向调用方的错误不包含认证快照。 */\nfunction repositoryFailure(cause: unknown): HaiResult<never> {\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_sessionStateFailed'), cause)\n}\n\n/**\n * 会话共享仓库;保存与轮换具有原子发布语义。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const repository = createCacheSessionRepository(604800)\n * const found = await repository.getByAccessToken('token-from-authorization-header')\n * if (!found.success)\n * return found\n * return found.data?.userId ?? null\n * ```\n */\nexport interface SessionRepository {\n /** 原子保存;singleDevice 同一次提交替换该用户全部旧会话。 */\n save: (session: Session, tokens: TokenPair, singleDevice?: boolean) => Promise<HaiResult<void>>\n /** 比较旧版本与 refresh 凭据,原子撤销旧会话并发布唯一后继。 */\n rotate: (previous: Session, refreshToken: string, session: Session, tokens: TokenPair) => Promise<HaiResult<void>>\n /** 查询未过期 access;基础设施故障失败关闭。 */\n getByAccessToken: (token: string) => Promise<HaiResult<Session | null>>\n /** 查询待轮换会话,rotate 提交时必须再次核验。 */\n getByRefreshToken: (token: string) => Promise<HaiResult<Session | null>>\n /** 从最新状态合并更新,不重新创建已撤销 token。 */\n updateByAccessToken: (token: string, patch: Partial<Session>, expectedVersion: string) => Promise<HaiResult<void>>\n /** 从最新快照按会话固有 maxAge 单调滑动,返回已提交的真实时间字段。 */\n touchByAccessToken: (token: string, expectedVersion: string, now: Date) => Promise<HaiResult<Session>>\n /** 原子撤销 access 与 refresh,重复操作成功。 */\n removeByAccessToken: (token: string) => Promise<HaiResult<void>>\n /** 原子撤销用户全部会话,返回记录数。 */\n removeByUserId: (userId: string) => Promise<HaiResult<number>>\n /** 原子移除 refresh 凭据,保留 access。 */\n removeRefreshToken: (token: string) => Promise<HaiResult<void>>\n /** 在同一最新文档更新会话,缓存故障返回失败并保留整个分区;损坏数据同样失败关闭,不当作不存在。 */\n patchUserSessions: (userId: string, patch: Record<string, unknown>) => Promise<HaiResult<void>>\n}\n\n/**\n * 创建单键 CAS 会话仓库,支持共享 Redis 和显式测试 Memory provider。\n * @param refreshTokenMaxAge - 新 refresh 的有效期,单位秒\n * @returns 不保存进程会话状态的仓库\n * @internal\n * @example 模块内部上下文\n * ```ts\n * const repository = createCacheSessionRepository(604800)\n * const found = await repository.getByAccessToken('token-from-authorization-header')\n * if (!found.success)\n * return found\n * return found.data?.userId ?? null\n * ```\n */\nexport function createCacheSessionRepository(\n refreshTokenMaxAge: number,\n policy: Partial<Pick<SessionConfig, 'idleTimeout' | 'absoluteTimeout' | 'maxSessions' | 'singleDeviceMode' | 'sliding' | 'terminalLimits' | 'terminalLimitMode'>> = {},\n): SessionRepository {\n const idleTimeout = policy.idleTimeout ?? 0\n const absoluteTimeout = policy.absoluteTimeout ?? 0\n const maxSessions = policy.maxSessions ?? 0\n\n /** 在读取及最终 CAS 提交时重复检查,防止迟到请求或刷新复活过期会话。 */\n function policyExpired(session: Session): boolean {\n const now = Date.now()\n const activeAt = new Date(session.lastActiveAt).getTime()\n const startedAt = new Date(session.startedAt ?? session.createdAt).getTime()\n return (idleTimeout > 0 && activeAt + idleTimeout * 1000 <= now)\n || (absoluteTimeout > 0 && startedAt + absoluteTimeout * 1000 <= now)\n }\n /** 校验缓存快照的路由、主体和日期;损坏数据不能转为认证成功。 */\n async function read(scope: string): Promise<HaiResult<SessionState | undefined>> {\n try {\n const result = await cache.kv.get<SessionState>(stateKey(scope))\n if (!result.success)\n return repositoryFailure(result.error)\n if (result.data === null)\n return ok(undefined)\n const state = result.data\n if (typeof state.revision !== 'string' || !state.revision || !state.sessions || typeof state.sessions !== 'object' || Array.isArray(state.sessions))\n throw new TypeError('Invalid session state')\n for (const [token, entry] of Object.entries(state.sessions)) {\n const session = restoreSession(entry.session)\n if (getTokenSessionScope(token) !== scope || token !== session.accessToken || getUserSessionScope(session.userId) !== scope\n || !Number.isSafeInteger(entry.refreshExpiresAt) || (entry.refreshToken !== undefined && getTokenSessionScope(entry.refreshToken) !== scope)) {\n throw new TypeError('Invalid session state')\n }\n }\n return ok(state)\n }\n catch (cause) { return repositoryFailure(cause) }\n }\n\n /**\n * 读取共享快照后进行单 key CAS;冲突只重新执行无外部副作用的同步状态变换。\n * 缓存读取或提交失败立即传播,不把损坏/未知状态覆盖为空;同值重建由 revision 防止 ABA。\n * @param scope - 已约束为 SHA-256 十六进制的用户分区提示。\n * @param operation - 仅修改私有候选状态的同步函数;不得发送通知、执行业务 SQL 或写入外部系统。\n * @returns CAS 已确认时返回 operation 结果;基础设施失败或冲突耗尽时保留失败结果。\n * @example 模块内部上下文\n * ```ts\n * const revoked = await mutate(getUserSessionScope('user-1'), (state) => {\n * const count = Object.keys(state.sessions).length\n * state.sessions = {}\n * return ok(count)\n * })\n * if (!revoked.success)\n * return revoked\n * return revoked.data\n * ```\n */\n async function mutate<T>(scope: string, operation: (state: SessionState) => HaiResult<T>): Promise<HaiResult<T>> {\n try {\n for (let attempt = 0; attempt < 16; attempt++) {\n const current = await read(scope)\n if (!current.success)\n return current\n // 私有快照由本仓库生成并经 read 校验;复制后修改,避免 Memory 引用别名。\n const next: SessionState = current.data ? JSON.parse(JSON.stringify(current.data)) : { revision: '', sessions: {} }\n for (const [token, entry] of Object.entries(next.sessions)) {\n if (retainedUntil(entry) <= Date.now() || policyExpired(entry.session))\n delete next.sessions[token]\n }\n const outcome = operation(next)\n if (!outcome.success)\n return outcome\n next.revision = crypto.randomUUID()\n const entries = Object.values(next.sessions)\n const px = entries.reduce((ttl, entry) => Math.max(ttl, retainedUntil(entry) - Date.now()), 1)\n const written = await cache.kv.compareAndSwap(stateKey(scope), current.data, entries.length ? next : undefined, { px })\n if (!written.success)\n return repositoryFailure(written.error)\n if (written.data)\n return outcome\n }\n return err(HaiIamError.CONFLICT, iamM('iam_sessionStateConflict'))\n }\n catch (cause) { return repositoryFailure(cause) }\n }\n\n /** 完整随机 token 必须属于当前用户;分区提示本身不构成认证。 */\n function storeSession(state: SessionState, session: Session, tokens: TokenPair): HaiResult<void> {\n const scope = getUserSessionScope(session.userId)\n if (getTokenSessionScope(session.accessToken) !== scope || tokens.accessToken !== session.accessToken || getTokenSessionScope(tokens.refreshToken) !== scope)\n return err(HaiIamError.TOKEN_INVALID, iamM('iam_sessionStateFailed'))\n state.sessions[session.accessToken] = { session, refreshToken: tokens.refreshToken, refreshExpiresAt: session.createdAt.getTime() + refreshTokenMaxAge * 1000 }\n return ok(undefined)\n }\n\n return {\n save: (session, tokens, singleDevice = false) => mutate(getUserSessionScope(session.userId), (state) => {\n // 已被数据库凭据代际撤销的旧记录不占用有效会话配额。\n const active = Object.entries(state.sessions).filter(([, entry]) => entry.session.credentialVersion === session.credentialVersion)\n const terminal = session.terminalType ?? 'web'\n const limits = policy.terminalLimits ?? {}\n const cap = limits[terminal]\n if (Object.keys(limits).length && cap === undefined)\n return err(HaiIamError.SESSION_LIMIT_EXCEEDED, iamM('iam_sessionLimitExceeded'))\n const removed = new Set<string>()\n if (singleDevice) {\n if (policy.singleDeviceMode === 'reject' && active.length)\n return err(HaiIamError.SESSION_LIMIT_EXCEEDED, iamM('iam_sessionLimitExceeded'))\n if (policy.singleDeviceMode !== 'reject')\n Object.keys(state.sessions).forEach(token => removed.add(token))\n }\n else if (cap) {\n const same = active.filter(([, entry]) => (entry.session.terminalType ?? 'web') === terminal)\n .sort(([firstToken, first], [secondToken, second]) => new Date(first.session.startedAt ?? first.session.createdAt).getTime() - new Date(second.session.startedAt ?? second.session.createdAt).getTime() || firstToken.localeCompare(secondToken))\n if (same.length >= cap) {\n if (policy.terminalLimitMode !== 'replace')\n return err(HaiIamError.SESSION_LIMIT_EXCEEDED, iamM('iam_sessionLimitExceeded'))\n same.slice(0, same.length - cap + 1).forEach(([token]) => removed.add(token))\n }\n }\n if (maxSessions > 0 && active.filter(([token]) => !removed.has(token)).length >= maxSessions)\n return err(HaiIamError.SESSION_LIMIT_EXCEEDED, iamM('iam_sessionLimitExceeded'))\n // 所有配额确认后再改候选状态;失败不能撤销已存在的任何终端会话。\n removed.forEach(token => delete state.sessions[token])\n return storeSession(state, session, tokens)\n }),\n rotate: (previous, refreshToken, session, tokens) => mutate(getUserSessionScope(previous.userId), (state) => {\n const old = state.sessions[previous.accessToken]\n if (!old || old.refreshToken !== refreshToken || old.refreshExpiresAt <= Date.now() || policyExpired(old.session))\n return err(HaiIamError.TOKEN_EXPIRED, iamM('iam_refreshTokenExpired'))\n if (old.session.version !== previous.version || session.userId !== previous.userId)\n return err(HaiIamError.CONFLICT, iamM('iam_sessionStateConflict'))\n // 绝对期限从首次签发计算,不随 refresh 创建新 access 重新计时。\n session.startedAt = new Date(old.session.startedAt ?? old.session.createdAt)\n // 自动换票不算业务活动,避免后台定时 refresh 无限延长闲置期限。\n if (idleTimeout > 0)\n session.lastActiveAt = new Date(old.session.lastActiveAt)\n delete state.sessions[previous.accessToken]\n return storeSession(state, session, tokens)\n }),\n async getByAccessToken(token) {\n const scope = getTokenSessionScope(token)\n if (!scope)\n return ok(null)\n const result = await read(scope)\n if (!result.success)\n return result\n const record = result.data?.sessions[token]\n if (!record)\n return ok(null)\n const session = restoreSession(record.session)\n return ok(session.expiresAt.getTime() <= Date.now() || policyExpired(session) ? null : session)\n },\n async getByRefreshToken(token) {\n const scope = getTokenSessionScope(token)\n if (!scope)\n return ok(null)\n const result = await read(scope)\n if (!result.success)\n return result\n const record = Object.values(result.data?.sessions ?? {}).find(entry => entry.refreshToken === token && entry.refreshExpiresAt > Date.now())\n if (!record)\n return ok(null)\n const session = restoreSession(record.session)\n return ok(policyExpired(session) ? null : session)\n },\n async updateByAccessToken(token, patch, expectedVersion) {\n const scope = getTokenSessionScope(token)\n if (!scope)\n return err(HaiIamError.SESSION_NOT_FOUND, iamM('iam_sessionNotExist'))\n return mutate(scope, (state) => {\n const entry = state.sessions[token]\n if (!entry || new Date(entry.session.expiresAt).getTime() <= Date.now() || policyExpired(entry.session))\n return err(HaiIamError.SESSION_NOT_FOUND, iamM('iam_sessionNotExist'))\n if (!expectedVersion || entry.session.version !== expectedVersion)\n return err(HaiIamError.CONFLICT, iamM('iam_sessionStateConflict'))\n if (patch.terminalType !== undefined && patch.terminalType !== (entry.session.terminalType ?? 'web'))\n return err(HaiIamError.CONFLICT, iamM('iam_sessionStateConflict'))\n const updated = applySessionPatch(restoreSession(entry.session), patch)\n if (![updated.expiresAt, updated.lastActiveAt].every(date => Number.isFinite(date.getTime())))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_sessionMaxAgeInvalid'))\n entry.session = { ...updated, version: crypto.randomUUID() }\n return ok(undefined)\n })\n },\n async touchByAccessToken(token, expectedVersion, now) {\n const scope = getTokenSessionScope(token)\n if (!scope)\n return err(HaiIamError.SESSION_NOT_FOUND, iamM('iam_sessionNotExist'))\n return mutate(scope, (state) => {\n const entry = state.sessions[token]\n if (!entry || new Date(entry.session.expiresAt).getTime() <= Date.now() || policyExpired(entry.session))\n return err(HaiIamError.SESSION_NOT_FOUND, iamM('iam_sessionNotExist'))\n if (entry.session.version !== expectedVersion)\n return err(HaiIamError.CONFLICT, iamM('iam_sessionStateConflict'))\n const current = restoreSession(entry.session)\n // 迟到节点只允许延长时间,不能覆盖较晚请求已提交的活动/过期点。\n const next = {\n ...current,\n lastActiveAt: new Date(Math.max(current.lastActiveAt.getTime(), now.getTime())),\n expiresAt: policy.sliding === false ? current.expiresAt : new Date(Math.max(current.expiresAt.getTime(), now.getTime() + current.maxAge * 1000)),\n }\n entry.session = next\n return ok(next)\n })\n },\n async removeByAccessToken(token) {\n const scope = getTokenSessionScope(token)\n if (!scope)\n return ok(undefined)\n return mutate(scope, (state) => {\n delete state.sessions[token]\n return ok(undefined)\n })\n },\n removeByUserId: userId => mutate(getUserSessionScope(userId), (state) => {\n const count = Object.keys(state.sessions).length\n state.sessions = {}\n return ok(count)\n }),\n async removeRefreshToken(token) {\n const scope = getTokenSessionScope(token)\n if (!scope)\n return ok(undefined)\n return mutate(scope, (state) => {\n for (const entry of Object.values(state.sessions)) {\n if (entry.refreshToken === token)\n delete entry.refreshToken\n }\n return ok(undefined)\n })\n },\n patchUserSessions(userId, patch) {\n // 重试绑定最初读取的会话代际;不能把迟到授权覆盖到后续登录或新内容版本。\n let targets: Map<string, string> | undefined\n return mutate(getUserSessionScope(userId), (state) => {\n targets ??= new Map(Object.entries(state.sessions).map(([token, entry]) => [token, entry.session.version]))\n for (const [token, version] of targets) {\n const entry = state.sessions[token]\n if (!entry)\n continue\n if (entry.session.version !== version)\n return err(HaiIamError.CONFLICT, iamM('iam_sessionStateConflict'))\n entry.session = { ...applySessionPatch(restoreSession(entry.session), patch), version: crypto.randomUUID() }\n }\n return ok(undefined)\n })\n },\n }\n}\n","/**\n * @h-ai/iam — 会话子功能工厂\n *\n * 基于缓存存储的会话实现:创建、查询、验证、更新、删除。\n * @module iam-session-functions\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ApiKeyRepository } from '../authn/apikey/iam-authn-apikey-repository.js'\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 { createDbApiKeyRepository } from '../authn/apikey/iam-authn-apikey-repository.js'\nimport { applyApiKeyScopes } from '../authn/apikey/iam-authn-apikey-scope.js'\nimport { readIamCache } from '../iam-cache.js'\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, generateSessionToken } from './iam-session-utils.js'\n\n/**\n * 移除 session 中仅供内部使用的敏感保留字段(如 _tokenPair 中的 refreshToken)。\n *\n * 内部路径(如 authn.buildAuthResult、session.refresh)仍可从 create/repo 原始返回\n * 值读取 _tokenPair;此函数仅作用于对外暴露的 get / verifyToken 出口。\n */\nfunction stripInternalSessionFields(session: Session): Session {\n if (!session.data || !('_tokenPair' in session.data))\n return session\n const { _tokenPair, ...rest } = session.data as { _tokenPair?: unknown, [key: string]: unknown }\n void _tokenPair\n const hasExtraKeys = Object.keys(rest).length > 0\n return { ...session, data: hasExtraKeys ? rest : undefined }\n}\n\nconst logger = core.logger.child({ module: 'iam', scope: 'session' })\n\n// ─── 子功能依赖 ───\n\n/**\n * 会话子功能依赖\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function assemble(config: IamConfig, readCredential: SessionOperationsDeps['readCredential']) {\n * const deps: SessionOperationsDeps = { config, readCredential }\n * return createSessionOperations(deps)\n * }\n * ```\n */\nexport interface SessionOperationsDeps {\n config: IamConfig\n /** 可信用户状态读取口;共享代际缓存与安全回源,缺失/禁用/读失败均拒绝签发和认证。 */\n readCredential: (userId: string) => Promise<HaiResult<{ version: string, available: boolean, profile?: Pick<Session, 'username' | 'displayName' | 'avatarUrl'> } | null>>\n}\n\n/**\n * 创建会话子功能\n *\n * 内部创建缓存会话存储,返回会话管理接口。\n * @param deps - 由 IAM 生命周期按依赖顺序创建的内部组件。\n * @returns 成功返回数据,失败返回业务或基础设施错误;调用方必须先判断 success。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function verify(deps: SessionOperationsDeps, token: string) {\n * const created = await createSessionOperations(deps)\n * if (!created.success)\n * return created\n * return created.data.verifyToken(token)\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.refreshTokenMaxAge ?? 604800,\n sessionConfig,\n )\n\n const functions = buildSessionFunctions({\n readCredential: deps.readCredential,\n maxAge: sessionConfig.maxAge,\n sliding: sessionConfig.sliding,\n singleDevice: sessionConfig.singleDevice,\n idleTimeout: sessionConfig.idleTimeout,\n sessionRepository,\n apiKeyRepository: config.login.apikey ? await createDbApiKeyRepository() : undefined,\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 * @internal\n * @example 模块内部上下文\n * ```ts\n * function lifetime(config: SessionBuilderConfig) {\n * return { maxAgeSeconds: config.maxAge ?? 86400, singleDevice: config.singleDevice ?? false }\n * }\n * ```\n */\ninterface SessionBuilderConfig {\n readCredential: SessionOperationsDeps['readCredential']\n apiKeyRepository?: ApiKeyRepository\n /** 会话最大有效期(秒,默认 86400 = 24小时) */\n maxAge?: number\n /** 是否滑动窗口 */\n sliding?: boolean\n /** 单设备登录(踢掉其他设备) */\n singleDevice?: boolean\n /** access 不滑动时仍需记录活动,以执行独立闲置期限。 */\n idleTimeout?: number\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 /** 只构造候选值;旧凭据撤销与新凭据发布必须由仓库一次原子提交。 */\n function candidate(options: CreateSessionOptions, credentialVersion: string): HaiResult<{ session: Session, tokens: TokenPair }> {\n if (options.terminalType !== undefined && !['web', 'app', 'desktop', 'api'].includes(options.terminalType))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_terminalTypeInvalid'))\n const now = new Date()\n const ttl = options.maxAge ?? maxAge\n if (!Number.isSafeInteger(ttl) || ttl <= 0 || !Number.isFinite(new Date(now.getTime() + ttl * 1000).getTime()))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_sessionMaxAgeInvalid'))\n const accessToken = generateSessionToken(options.userId)\n const tokens: TokenPair = { accessToken, refreshToken: generateSessionToken(options.userId), expiresIn: ttl, tokenType: 'Bearer' }\n const session = buildSession(options, now, ttl, accessToken, credentialVersion)\n session.data = { ...session.data, _tokenPair: tokens }\n return ok({ session, tokens })\n }\n\n /**\n * 凭据代只能来自可信数据库;读取和签发跨库不能同事务,因此会话始终保留旧代,后续认证再次核对。\n * @example await credential('user-1', authenticated.credentialVersion)\n */\n async function credential(userId: string, expected?: string): Promise<HaiResult<{ version: string, profile?: Pick<Session, 'username' | 'displayName' | 'avatarUrl'> }>> {\n try {\n const current = await config.readCredential(userId)\n if (!current.success)\n return current\n if (!current.data || current.data.available !== true)\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n if (typeof current.data.version !== 'string' || (expected !== undefined && current.data.version !== expected))\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n return ok(current.data)\n }\n catch {\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_sessionExpired'))\n }\n }\n\n /** 持久化 key 是派生会话的授权上限;撤销、禁用、到期与读取失败均拒绝访问。 */\n async function validateApiKey(session: Session): Promise<HaiResult<Session>> {\n if (!session.apiKeyId)\n return ok(session)\n if (!config.apiKeyRepository)\n return err(HaiIamError.APIKEY_INVALID, iamM('iam_apikeyInvalid'))\n const found = await readIamCache(`apikey:${session.apiKeyId}`, async () => {\n const row = await config.apiKeyRepository!.findOneById(session.apiKeyId!)\n return row.success ? ok(row.data ? { userId: row.data.userId, enabled: row.data.enabled, expiresAt: row.data.expiresAt?.getTime() ?? null, scopes: row.data.scopes } : null) : row\n })\n if (!found.success)\n return found\n const key = found.data\n if (!key || key.userId !== session.userId)\n return err(HaiIamError.APIKEY_INVALID, iamM('iam_apikeyInvalid'))\n if (!key.enabled)\n return err(HaiIamError.APIKEY_DISABLED, iamM('iam_apikeyDisabled'))\n if (key.expiresAt && Date.now() >= key.expiresAt)\n return err(HaiIamError.APIKEY_EXPIRED, iamM('iam_apikeyExpired'))\n return ok(applyApiKeyScopes({ ...session, apiKeyScopes: key.scopes }, key.scopes))\n }\n\n return {\n async create(options: CreateSessionOptions): Promise<HaiResult<Session>> {\n try {\n const bound = await credential(options.userId, options.expectedCredentialVersion)\n if (!bound.success)\n return bound\n const built = candidate(options, bound.data.version)\n if (!built.success)\n return built\n const { session, tokens } = built.data\n const saveResult = await repo.save(session, tokens, singleDevice)\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 const removeResult = await repo.removeByAccessToken(accessToken)\n if (!removeResult.success) {\n return removeResult as HaiResult<Session | null>\n }\n return ok(null)\n }\n\n if (typeof session.credentialVersion !== 'string')\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n const bound = await credential(session.userId, session.credentialVersion)\n if (!bound.success)\n return bound\n const validated = await validateApiKey({ ...session, ...bound.data.profile })\n if (!validated.success)\n return validated\n let output = validated.data\n\n if (sliding || (config.idleTimeout ?? 0) > 0) {\n const updateResult = await repo.touchByAccessToken(accessToken, session.version, new Date())\n if (!updateResult.success) {\n return updateResult as HaiResult<Session | null>\n }\n // 保留 API Key 已收敛的权限,只使用成功提交后的时间字段。\n output = { ...output, lastActiveAt: updateResult.data.lastActiveAt, expiresAt: updateResult.data.expiresAt }\n }\n\n // 对外不暴露内部保留的 _tokenPair(含 refreshToken),\n // 防止调用方(包括 event.locals.session 等上下文)意外泄漏刷新令牌。\n return ok(stripInternalSessionFields(output))\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>, expectedVersion: string): Promise<HaiResult<void>> {\n return repo.updateByAccessToken(accessToken, data, expectedVersion)\n },\n\n async delete(accessToken: string): Promise<HaiResult<void>> {\n // 注意:不要记录原始 accessToken,token 属于敏感凭据\n logger.debug('Session delete requested')\n return repo.removeByAccessToken(accessToken)\n },\n\n async deleteByUserId(userId: string): Promise<HaiResult<number>> {\n const result = await repo.removeByUserId(userId)\n if (!result.success) {\n return result as HaiResult<number>\n }\n return ok(result.data)\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 if (typeof oldSession.credentialVersion !== 'string')\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n const bound = await credential(oldSession.userId, oldSession.credentialVersion)\n if (!bound.success)\n return bound\n const validated = await validateApiKey(oldSession)\n if (!validated.success)\n return validated\n const effectiveSession = validated.data\n\n // 只构建候选会话;消费旧 refresh 与发布新会话在同一用户分区 CAS 中完成。\n const next = candidate({\n userId: oldSession.userId,\n username: oldSession.username,\n displayName: oldSession.displayName,\n avatarUrl: oldSession.avatarUrl,\n roles: effectiveSession.roles,\n permissions: effectiveSession.permissions,\n apiKeyId: effectiveSession.apiKeyId,\n apiKeyScopes: effectiveSession.apiKeyScopes,\n source: oldSession.source,\n terminalType: oldSession.terminalType ?? 'web',\n maxAge: oldSession.maxAge,\n data: oldSession.data ? { ...oldSession.data, _tokenPair: undefined } : undefined,\n }, oldSession.credentialVersion)\n\n if (!next.success)\n return next\n const rotated = await repo.rotate(oldSession, refreshToken, next.data.session, next.data.tokens)\n if (!rotated.success)\n return rotated\n\n // 改密可能发生在最后一次读取与cache CAS之间;绝不把旧refresh升级到新凭据代。\n const current = await credential(oldSession.userId, oldSession.credentialVersion)\n if (!current.success)\n return current\n logger.debug('Token refreshed', { userId: oldSession.userId })\n return ok(next.data.tokens)\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 * 提供用户管理相关操作:注册、查询、更新、密码管理等。\n * @module iam-user-functions\n */\n\nimport type { HaiError, 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, PasswordResetConfig, RegisterConfig, SecurityConfig } from '../iam-config.js'\nimport type { IamNotificationContext } from '../iam-types.js'\nimport type { SessionOperations } from '../session/iam-session-types.js'\nimport type { UserRepository } from './iam-user-repository-user.js'\nimport type {\n ListUsersOptions,\n RegisterOptions,\n RegisterResult,\n StoredUser,\n UpdateCurrentUserInput,\n User,\n UserOperations,\n UserSortField,\n} from './iam-user-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { crypto } from '@h-ai/crypto'\nimport { HaiReldbError, reldb } from '@h-ai/reldb'\n\nimport { verifyIamCaptcha } from '../authn/iam-authn-captcha.js'\nimport { isAccountLocked, recordLoginFailure, rejectMissingPasswordCredentials, resetLoginFailures } from '../authn/iam-authn-utils.js'\nimport { buildAgreementDisplay } from '../iam-agreement.js'\nimport { AgreementConfigSchema, PasswordResetConfigSchema, RegisterConfigSchema, SecurityConfigSchema } from '../iam-config.js'\nimport { iamM } from '../iam-i18n.js'\nimport { HaiIamError } from '../iam-types.js'\nimport { generateToken } from '../session/iam-session-utils.js'\nimport { createDbUserRepository } from './iam-user-repository-user.js'\nimport { isUserActive, toUser, validateAccountPolicy } from './iam-user-utils.js'\n\nconst logger = core.logger.child({ module: 'iam', scope: 'user' })\n\n/**\n * 用户列表排序字段到数据库列的受控映射。\n *\n * 排序列不能直接使用调用方传入的字符串拼接 SQL;该白名单同时保证 API 契约与存储列名解耦。\n */\nconst USER_SORT_COLUMNS: Record<UserSortField, string> = {\n /** 用户名列。 */\n username: 'username',\n /** 邮箱列。 */\n email: 'email',\n /** 用户显示名称列。 */\n displayName: 'display_name',\n /** 账号生命周期列。 */\n accountStatus: 'account_status',\n /** 用户创建时间列。 */\n createdAt: 'created_at',\n}\n\n// ─── 子功能依赖 ───\n\n/**\n * 用户子功能依赖\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function assemble(deps: UserOperationsDeps) {\n * const result = await createUserOperations(deps)\n * if (!result.success)\n * return result\n * return result.data.getUser('user-1')\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, context: IamNotificationContext) => Promise<void>\n}\n\n/**\n * 创建用户子功能\n *\n * 内部创建用户存储,组装用户管理操作接口。\n * @param deps - 由 IAM 生命周期按依赖顺序创建的内部组件。\n * @returns 成功返回数据,失败返回业务或基础设施错误;调用方必须先判断 success。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * async function list(deps: UserOperationsDeps) {\n * const result = await createUserOperations(deps)\n * if (!result.success)\n * return result\n * return result.data.listUsers({ page: 1, pageSize: 20 })\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\n const functions = buildUserFunctions({\n userRepository,\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 error 底层结构化错误\n * @returns 领域层错误结果\n */\nfunction mapUpdateErrorAsDomainError(error: HaiError): HaiResult<never> {\n if (error.code === HaiReldbError.DUPLICATE_ENTRY.code) {\n return err(\n HaiIamError.USER_ALREADY_EXISTS,\n iamM('iam_userAlreadyExist'),\n )\n }\n\n return mapRepositoryError('iam_updateUserFailed', error.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 * @internal\n * @example 模块内部上下文\n * ```ts\n * async function currentUser(context: UserFnContext) {\n * const stored = await context.userRepository.findByUsername('alice')\n * if (!stored.success)\n * return stored\n * return stored.data ? toUser(stored.data) : null\n * }\n * ```\n */\ninterface UserFnContext {\n userRepository: UserRepository\n validatePassword: (password: string) => HaiResult<void>\n hashPassword: (password: string) => HaiResult<string>\n sessionFunctions: SessionOperations\n authzFunctions: AuthzOperations\n config: IamConfig\n registerConfig: RegisterConfig\n agreementConfig: IamConfig['agreements']\n resetConfig: PasswordResetConfig\n loginConfig: SecurityConfig\n onPasswordResetRequest?: (user: User, token: string, context: IamNotificationContext) => Promise<void>\n}\n\n/** 注册和所有改密入口共用强度规则;首次/过期改密不得以相同密码清除限制。 */\nfunction validatePasswordReplacement(ctx: UserFnContext, user: StoredUser, password: string): HaiResult<void> {\n const strength = ctx.validatePassword(password)\n if (!strength.success)\n return strength\n if (user.passwordHash && ((user.mustChangePassword && ctx.config.password?.requireInitialChange) || ctx.config.password?.preventSamePassword || (ctx.config.password?.expirationDays ?? 0) > 0)) {\n const same = crypto.password.verify(password, user.passwordHash)\n if (!same.success)\n return same\n if (same.data)\n return err(HaiIamError.PASSWORD_REUSE_NOT_ALLOWED, iamM('iam_passwordMustDiffer'))\n }\n return ok(undefined)\n}\n\n// ─── 注册操作 ───\n\n/**\n * 构建用户注册相关操作\n */\nfunction buildRegistrationOps(ctx: UserFnContext): Pick<UserOperations, 'register' | 'createUser' | '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 const accountPolicy = validateAccountPolicy(options)\n if (!accountPolicy.success)\n return accountPolicy\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)\n return existsResult\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)\n return emailExistsResult\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 async function assignDefaultRole(userId: string): Promise<HaiResult<void>> {\n if (!config.rbac?.enabled || !config.rbac.defaultRole)\n return ok(undefined)\n const roleResult = await authzFunctions.getRoleByCode(config.rbac.defaultRole)\n if (!roleResult.success)\n return roleResult\n if (!roleResult.data)\n return err(HaiIamError.ROLE_NOT_FOUND, iamM('iam_roleNotExist'))\n return authzFunctions.assignRole(userId, roleResult.data.id)\n }\n\n async function createUser(options: RegisterOptions, managed = false): 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 accountType: options.accountType ?? 'permanent',\n accountStatus: options.accountStatus ?? 'active',\n accountExpiresAt: options.accountExpiresAt,\n mustChangePassword: managed && config.password?.requireInitialChange === true,\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) 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 const assigned = await assignDefaultRole(createdUser.id)\n if (!assigned.success) {\n await authzFunctions.syncRoles(createdUser.id, [])\n await userRepository.deleteById(createdUser.id)\n return assigned\n }\n\n logger.info('User registered', { userId: createdUser.id, username: options.username })\n return ok({\n user: toUser(createdUser),\n agreements: buildAgreementDisplay(agreementConfig, agreementConfig.showOnRegister),\n })\n }\n\n return {\n createUser: options => createUser(options, true),\n async register(options) {\n const captcha = await verifyIamCaptcha(ctx.config.captcha, 'register', options.captcha)\n if (!captcha.success)\n return captcha\n if (!registerConfig.enabled)\n return Promise.resolve(err(HaiIamError.REGISTER_DISABLED, iamM('iam_registerDisabled')))\n return createUser({ ...options, accountStatus: registerConfig.defaultAccountStatus })\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' | 'getUsers' | 'listUsers'> {\n const { userRepository, sessionFunctions, authzFunctions } = ctx\n\n return {\n async getUsers(userIds, options) {\n if (userIds.length > 1000 || userIds.some(id => typeof id !== 'string' || !id.trim()))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_batchUserIdsInvalid'))\n const ids = [...new Set(userIds)]\n const found = new Map<string, User>()\n // 小批次控制占位符数量,兼容数据库限制;不为每个用户发起查询。\n for (let offset = 0; offset < ids.length; offset += 500) {\n const batch = ids.slice(offset, offset + 500)\n const users = await userRepository.findAll({ where: `id IN (${batch.map(() => '?').join(', ')})`, params: batch })\n if (!users.success)\n return users\n for (const user of users.data)\n found.set(user.id, toUser(user))\n }\n const items = ids.flatMap(id => found.has(id) ? [found.get(id)!] : [])\n if (options?.include?.includes('roles') && items.length) {\n const roles = await authzFunctions.getUserRolesForMany(items.map(user => user.id))\n if (!roles.success)\n return roles\n for (const user of items)\n user.roles = roles.data.get(user.id) ?? []\n }\n return ok(items)\n },\n\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 return rolesResult\n user.roles = rolesResult.data\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 ? ESCAPE \\'\\\\\\' OR email LIKE ? ESCAPE \\'\\\\\\' OR phone LIKE ? ESCAPE \\'\\\\\\' OR display_name LIKE ? ESCAPE \\'\\\\\\')')\n params.push(keyword, keyword, keyword, keyword)\n }\n\n if (options?.accountStatus !== undefined) {\n if (!['active', 'dormant', 'closed'].includes(options.accountStatus))\n return err(HaiIamError.INVALID_ARGUMENT, iamM('iam_accountPolicyInvalid'))\n conditions.push('account_status = ?')\n params.push(options.accountStatus)\n }\n\n if (options?.roleCode) {\n // 关系表属于 IAM 内部;应用只传角色 code,不接触表结构或先分页后过滤。\n conditions.push('EXISTS (SELECT 1 FROM hai_iam_user_roles ur JOIN hai_iam_roles r ON r.id = ur.role_id WHERE ur.user_id = hai_iam_users.id AND r.code = ?)')\n params.push(options.roleCode)\n }\n\n const where = conditions.length > 0 ? conditions.join(' AND ') : undefined\n /** 未指定排序时保持既有的创建时间倒序,避免改变调用方历史结果。 */\n const sortColumn = options?.sortBy ? USER_SORT_COLUMNS[options.sortBy] : USER_SORT_COLUMNS.createdAt\n /** 仅接受声明的 asc;其余情况均为默认 desc,防止将外部输入拼入 SQL。 */\n const sortDirection = options?.sortBy && options.sortDirection === 'asc' ? 'ASC' : 'DESC'\n\n const usersResult = await userRepository.findPage({\n where,\n params: params.length > 0 ? params : undefined,\n orderBy: `${sortColumn} ${sortDirection}`,\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 return rolesMapResult\n for (const user of items)\n user.roles = rolesMapResult.data.get(user.id) ?? []\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) 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 const currentAccount = await userRepository.findById(userId)\n if (!currentAccount.success)\n return currentAccount\n if (!currentAccount.data)\n return err(HaiIamError.USER_NOT_FOUND, iamM('iam_userNotExist'))\n // 部分更新的 undefined 与持久化层一致,表示保留原值;null 才是显式清空到期时间。\n const accountPolicy = validateAccountPolicy({\n accountType: data.accountType === undefined ? currentAccount.data.accountType : data.accountType,\n accountStatus: data.accountStatus === undefined ? currentAccount.data.accountStatus : data.accountStatus,\n accountExpiresAt: data.accountExpiresAt === undefined ? currentAccount.data.accountExpiresAt : data.accountExpiresAt,\n })\n if (!accountPolicy.success)\n return accountPolicy\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 changesSecurity = (data.accountStatus !== undefined && data.accountStatus !== currentAccount.data.accountStatus)\n || (data.accountType !== undefined && data.accountType !== currentAccount.data.accountType)\n || (data.accountExpiresAt !== undefined && (data.accountExpiresAt?.getTime() ?? null) !== (currentAccount.data.accountExpiresAt?.getTime() ?? null))\n // 状态变更与凭据代际同事务提交;重新激活也不能恢复旧会话,仅保存相同状态不撤销会话。\n const transaction = changesSecurity ? await reldb.tx.begin() : undefined\n if (transaction && !transaction.success)\n return transaction\n const tx = transaction?.success ? transaction.data : undefined\n let transactionCommitted = false\n try {\n const updateResult = await userRepository.updateById(userId, data, tx)\n if (!updateResult.success)\n return mapUpdateErrorAsDomainError(updateResult.error) as HaiResult<User>\n if (updateResult.data.changes === 0)\n return err(HaiIamError.USER_NOT_FOUND, iamM('iam_userNotExist'))\n if (tx) {\n const advanced = await tx.execute('UPDATE hai_iam_users SET credential_version = ?, reset_version = ?, reset_hash = NULL, reset_expires_at = NULL WHERE id = ? AND credential_version = ?', [globalThis.crypto.randomUUID(), globalThis.crypto.randomUUID(), userId, currentAccount.data.credentialVersion ?? ''])\n if (!advanced.success || advanced.data.changes !== 1)\n return advanced.success ? err(HaiIamError.CONFLICT, iamM('iam_sessionStateConflict')) : advanced\n const committed = await tx.commit()\n if (!committed.success)\n return committed\n transactionCommitted = true\n }\n }\n catch (cause) {\n return err(HaiIamError.REPOSITORY_ERROR, iamM('iam_accountUpdateFailed'), cause)\n }\n finally {\n // 包括 SDK/编程异常,均释放未提交的事务,防止后续 SQLite 操作等待自身锁。\n if (tx && !transactionCommitted)\n await tx.rollback()\n }\n if (tx) {\n const revoked = await sessionFunctions.deleteByUserId(userId)\n if (!revoked.success)\n logger.warn('Account credentials revoked; session cache cleanup failed', { userId, error: revoked.error })\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 { 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 = validatePasswordReplacement(ctx, userResult.data, 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.setPassword({ userId, expectedVersion: userResult.data.credentialVersion ?? '', passwordHash: hashResult.data, mustChangePassword: ctx.config.password?.requireInitialChange === true })\n if (!updateResult.success)\n return updateResult\n if (!updateResult.data)\n return err(HaiIamError.CONFLICT, iamM('iam_securityStateFailed'))\n\n // 密码重置后注销该用户所有活跃会话\n const revoked = await sessionFunctions.deleteByUserId(userId)\n if (!revoked.success)\n return revoked\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 const active = isUserActive(user)\n const locked = isAccountLocked(user, ctx.loginConfig)\n // 受限期间不比较口令;公开 renewPassword 会掩码,已有会话的操作保留具体错误。\n if (!active)\n return err(HaiIamError.ACCOUNT_UNAVAILABLE, iamM('iam_accountUnavailable'))\n if (locked)\n return err(HaiIamError.USER_LOCKED, iamM('iam_accountLocked'))\n\n // 验证旧密码\n if (!user.passwordHash)\n return rejectMissingPasswordCredentials()\n\n const verifyResult = crypto.password.verify(oldPassword, user.passwordHash)\n if (!verifyResult.success)\n return err(HaiIamError.INTERNAL_ERROR, verifyResult.error.message)\n if (!verifyResult.data) {\n // 记录失败计数 / 触发锁定,防止通过 changePassword 端点暴力枚举旧密码\n const failureResult = await recordLoginFailure(userRepository, user, ctx.loginConfig)\n if (!failureResult.success)\n return failureResult\n return err(\n HaiIamError.INVALID_CREDENTIALS,\n iamM('iam_originalPasswordWrong'),\n )\n }\n\n // 成功验证旧密码后重置失败计数\n const resetResult = await resetLoginFailures(userRepository, user, ctx.loginConfig)\n if (!resetResult.success)\n return resetResult\n\n // 验证新密码强度\n const validateResult = validatePasswordReplacement(ctx, user, 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.setPassword({ userId, expectedVersion: user.credentialVersion ?? '', passwordHash: hashResult.data })\n if (!updateResult.success)\n return updateResult\n if (!updateResult.data)\n return err(HaiIamError.CONFLICT, iamM('iam_securityStateFailed'))\n\n // 密码修改后注销该用户所有活跃会话\n const revoked = await sessionFunctions.deleteByUserId(userId)\n if (!revoked.success)\n return revoked\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/** 已确定用户的凭据通知发布;邀请与公开重置共用持久代际、到期及单次提交。 */\nasync function issuePasswordReset(ctx: UserFnContext, stored: StoredUser): Promise<HaiResult<void>> {\n const { userRepository, onPasswordResetRequest, resetConfig } = ctx\n if (!onPasswordResetRequest)\n return err(HaiIamError.PASSWORD_RESET_DISABLED, iamM('iam_passwordResetDisabled'))\n const user = toUser(stored)\n // 生成 256-bit 加密安全令牌(与 session token 强度一致)\n const token = generateToken()\n const expiresAt = new Date(Date.now() + resetConfig.tokenExpiresIn * 1000)\n\n // 保存新令牌并替换旧令牌,尝试次数与令牌拥有同一有效期。\n const tokenHash = crypto.hash.hash(token)\n if (!tokenHash.success)\n return tokenHash\n const saveResult = await userRepository.publishPasswordReset({ user: stored, tokenHash: tokenHash.data, expiresAt })\n if (!saveResult.success)\n return saveResult\n if (!saveResult.data)\n return err(HaiIamError.CONFLICT, iamM('iam_securityStateFailed'))\n\n // 通过回调通知业务层(如发送邮件)\n try {\n await onPasswordResetRequest(user, token, { expiresAt, idempotencyKey: `iam-reset:${tokenHash.data}` })\n }\n catch {\n logger.error('Password reset callback failed', { userId: user.id })\n return err(HaiIamError.INTERNAL_ERROR, iamM('iam_notificationDeliveryUnknown'))\n }\n\n logger.info('Password reset token generated', { userId: user.id })\n return ok(undefined)\n}\n\n/**\n * 构建密码重置操作(请求重置、确认重置)\n */\nfunction buildPasswordResetOps(ctx: UserFnContext): Pick<UserOperations, 'requestPasswordReset' | 'confirmPasswordReset'> {\n const { userRepository, sessionFunctions, onPasswordResetRequest } = ctx\n const { hashPassword } = ctx\n\n return {\n async requestPasswordReset(identifier: string, options?: { captcha?: string }): Promise<HaiResult<void>> {\n const captcha = await verifyIamCaptcha(ctx.config.captcha, 'passwordReset', options?.captcha)\n if (!captcha.success)\n return captcha\n logger.debug('Password reset requested', { identifier })\n\n const resetConfig = ctx.resetConfig\n if (!resetConfig.enabled || !onPasswordResetRequest)\n return err(HaiIamError.PASSWORD_RESET_DISABLED, iamM('iam_passwordResetDisabled'))\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 if (!isUserActive(user))\n return ok(undefined)\n\n return issuePasswordReset(ctx, userResult.data)\n },\n\n async confirmPasswordReset(token: string, newPassword: string): Promise<HaiResult<void>> {\n logger.debug('Confirming password reset')\n\n const resetConfig = ctx.resetConfig\n if (!resetConfig.enabled)\n return err(HaiIamError.PASSWORD_RESET_DISABLED, iamM('iam_passwordResetDisabled'))\n\n const tokenHash = crypto.hash.hash(token)\n if (!tokenHash.success)\n return tokenHash\n // 每次有效令牌尝试先条件推进重置代际,弱密码也计次;新尝试使迟到提交失效。\n const claimed = await userRepository.claimPasswordReset(tokenHash.data, resetConfig.maxAttempts)\n if (!claimed.success)\n return claimed\n const validateResult = validatePasswordReplacement(ctx, claimed.data, newPassword)\n if (!validateResult.success)\n return validateResult\n const hashResult = hashPassword(newPassword)\n if (!hashResult.success)\n return hashResult\n const committed = await userRepository.commitPasswordReset({ user: claimed.data, tokenHash: tokenHash.data, passwordHash: hashResult.data })\n if (!committed.success)\n return committed\n if (!committed.data)\n return err(HaiIamError.RESET_TOKEN_INVALID, iamM('iam_resetTokenInvalid'))\n // 凭据代际已在数据库推进;缓存清理失败不能重新授权旧会话。\n const revoked = await sessionFunctions.deleteByUserId(claimed.data.id)\n if (!revoked.success)\n return revoked\n logger.info('Password reset confirmed', { userId: claimed.data.id })\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 resetConfig: PasswordResetConfigSchema.parse(deps.config.passwordReset ?? {}),\n loginConfig: SecurityConfigSchema.parse(deps.config.security ?? {}),\n }\n\n const passwordChanges = buildPasswordChangeOps(ctx)\n const registration = buildRegistrationOps(ctx)\n return {\n ...registration,\n ...buildUserQueryOps(ctx),\n ...buildUserMutationOps(ctx),\n ...passwordChanges,\n ...buildPasswordResetOps(ctx),\n async inviteUser(options) {\n const destination = ctx.resetConfig.mode === 'phone' ? options.phone : options.email\n if (!deps.config.initialCredentials?.enabled || !ctx.resetConfig.enabled || !ctx.onPasswordResetRequest || !destination)\n return err(HaiIamError.INVITATION_DISABLED, iamM('iam_invitationDisabled'))\n const policy = deps.passwordStrategyResult.passwordConfig\n const length = Math.min(policy.maxLength, Math.max(32, policy.minLength))\n // 初始秘密只用于内部独立散列,从不返回、投递或写入业务元数据。\n const password = (`Aa1!${Array.from({ length: Math.ceil(length / 32) }, () => generateToken()).join('')}`).slice(0, length)\n const created = await registration.createUser({ ...options, password })\n if (!created.success)\n return created\n const stored = await deps.userRepository.findById(created.data.user.id)\n if (!stored.success || !stored.data)\n return err(HaiIamError.INVITATION_DELIVERY_UNKNOWN, iamM('iam_invitationDeliveryUnknown'))\n const delivered = await issuePasswordReset(ctx, stored.data)\n if (!delivered.success)\n return err(HaiIamError.INVITATION_DELIVERY_UNKNOWN, iamM('iam_invitationDeliveryUnknown'), delivered.error)\n return created\n },\n async renewPassword(input) {\n const captcha = await verifyIamCaptcha(deps.config.captcha, 'renewPassword', input.captcha)\n if (!captcha.success)\n return captcha\n const found = await deps.userRepository.findByIdentifier(input.identifier)\n if (!found.success)\n return found\n if (!found.data)\n return rejectMissingPasswordCredentials()\n const changed = await passwordChanges.changePassword(found.data.id, input.password, input.newPassword)\n // 公开改密接口不以错误文案区分不存在账号、无本地口令或错误原密码。\n if (!changed.success) {\n if ([HaiIamError.ACCOUNT_UNAVAILABLE.code, HaiIamError.USER_LOCKED.code, HaiIamError.USER_NOT_FOUND.code].includes(changed.error.code))\n return rejectMissingPasswordCredentials()\n if (changed.error.code === HaiIamError.INVALID_CREDENTIALS.code)\n return err(HaiIamError.INVALID_CREDENTIALS, iamM('iam_passwordWrong'))\n }\n return changed\n },\n async scanInactiveAccounts() {\n const days = deps.config.accounts?.dormantAfterDays ?? 0\n if (days === 0)\n return ok(0)\n return deps.userRepository.suspendInactive(new Date(Date.now() - days * 86400_000))\n },\n }\n}\n\n/**\n * 用户操作构建依赖;只能由 IAM 生命周期完成可信依赖装配。\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function build(deps: UserBuilderDeps) {\n * return buildUserFunctions(deps)\n * }\n * ```\n */\ninterface UserBuilderDeps {\n userRepository: UserRepository\n passwordStrategyResult: PasswordStrategyResult\n sessionFunctions: SessionOperations\n authzFunctions: AuthzOperations\n config: IamConfig\n onPasswordResetRequest?: (user: User, token: string, context: IamNotificationContext) => 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 { IamPublicConfig } from './iam-public-config.js'\nimport type { ApiKeyOperations, AuthnOperations, AuthResult, AuthzOperations, IamConfigInput, IamFunctions, SessionOperations, TicketOperations, 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 { observeApiKeys, observeAuth, observeAuthorization, observeSessions, observeUsers } from './iam-audit.js'\nimport { IamConfigSchema } from './iam-config.js'\nimport { iamM } from './iam-i18n.js'\nimport { migrateIam } from './iam-migration.js'\nimport { resolveIamNotifications } from './iam-notifications.js'\nimport { buildIamPublicConfig } from './iam-public-config.js'\nimport { readIamUserSecurity } from './iam-security-cache.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 { createTicketOperations } from './ticket/iam-ticket-functions.js'\nimport { createUserOperations } from './user/iam-user-functions.js'\nimport { createDbUserRepository, resetUserRepoSingleton } from './user/iam-user-repository-user.js'\nimport { checkPasswordState, isUserActive } from './user/iam-user-utils.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 currentPublicConfig: IamPublicConfig | 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\nlet currentTicket: TicketOperations | null = null\nlet accountScanTimer: ReturnType<typeof setInterval> | undefined\nlet accountScanRunning: Promise<void> | undefined\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>()\nconst notInitializedTicket = notInitialized.proxy<TicketOperations>()\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\n/**\n * IAM 服务单例;应用先初始化共享 RelDB/Cache,再 init → use → close,子功能返回 HaiResult。\n * @example\n * ```ts\n * import { iam } from '@h-ai/iam'\n * // Cache、RelDB、Crypto 已由应用按顺序初始化。\n * const initialized = await iam.init({ seedDefaultData: false })\n * if (initialized.success) {\n * const result = await iam.user.getUser('user-1')\n * if (result.success && result.data)\n * result.data.username\n * await iam.close()\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 } = 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 // Schema 只保留声明的设置字段,运行时模块和发送回调不会进入配置快照。\n const parseResult = IamConfigSchema.safeParse(config)\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 // Reach 是可选的外部依赖;通知回调解析在基础依赖和配置验证成功后执行。\n const { onPasswordResetRequest, onOtpSendEmail, onOtpSendSms } = await resolveIamNotifications(config)\n logger.info('IAM notification channels resolved', { email: Boolean(onOtpSendEmail), sms: Boolean(onOtpSendSms), passwordReset: Boolean(onPasswordResetRequest) })\n\n // 创建子功能(按依赖顺序),使用局部变量暂存,全部成功后再原子性赋值\n const migration = await migrateIam()\n if (!migration.success)\n return migration\n const credentialUsers = await createDbUserRepository()\n const sessionResult = await createSessionOperations({\n config: parsed,\n readCredential: async (userId) => {\n const found = await readIamUserSecurity(credentialUsers, userId)\n if (!found.success)\n return found\n if (found.data) {\n const passwordState = checkPasswordState(found.data, parsed.password)\n if (!passwordState.success)\n return passwordState\n }\n return ok(found.data ? { version: found.data.credentialVersion ?? '', available: isUserActive(found.data), profile: { username: found.data.username, displayName: found.data.displayName, avatarUrl: found.data.avatarUrl } } : null)\n },\n })\n if (!sessionResult.success) {\n return sessionResult\n }\n const sessions = observeSessions(sessionResult.data)\n\n const authzResult = await createAuthzOperations({ config: parsed, session: sessions })\n if (!authzResult.success) {\n return authzResult\n }\n const authorization = observeAuthorization(authzResult.data)\n\n const authnResult = await createAuthnOperations({\n config: parsed,\n sessionFunctions: sessions,\n authzFunctions: authorization,\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: sessions,\n authzFunctions: authorization,\n onPasswordResetRequest,\n })\n if (!userResult.success) {\n return userResult\n }\n const users = observeUsers(userResult.data)\n\n // 种子数据\n if (parsed.seedDefaultData) {\n const seedResult = await seedIamData(authorization)\n if (!seedResult.success) {\n return seedResult\n }\n }\n\n // 所有子功能创建成功,原子性赋值到模块状态\n currentSession = sessions\n currentAuthz = authorization\n currentUser = users\n currentConfig = parsed\n currentPublicConfig = buildIamPublicConfig(parsed, { ...config, onPasswordResetRequest, onOtpSendEmail, onOtpSendSms })\n currentApiKey = authnResult.data.apiKeyFunctions ? observeApiKeys(authnResult.data.apiKeyFunctions) : null\n // 一次性票据能力(仅依赖 cache + crypto,随 IAM 初始化即可用)\n currentTicket = createTicketOperations()\n\n // 组合 auth:注入 registerAndLogin(依赖 user + auth 两个子功能)\n const authn = authnResult.data.authn\n currentAuth = observeAuth({\n ...authn,\n async registerAndLogin(options, context) {\n const regResult = await currentUser!.register(options)\n if (!regResult.success) {\n return regResult as HaiResult<AuthResult>\n }\n return authnResult.data.loginRegisteredUser(regResult.data.user, context)\n },\n })\n if ((parsed.accounts?.dormantAfterDays ?? 0) > 0) {\n accountScanTimer = setInterval(() => {\n if (accountScanRunning)\n return\n accountScanRunning = users.scanInactiveAccounts().then((result) => {\n if (!result.success)\n logger.error('Inactive account scan failed', { error: result.error })\n }).catch((error: unknown) => {\n logger.error('Inactive account scan failed', { error })\n }).finally(() => { accountScanRunning = undefined })\n }, (parsed.accounts?.scanIntervalSeconds ?? 3600) * 1000)\n accountScanTimer.unref()\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 {\n return currentAuth ?? notInitializedAuth\n },\n async getPublicConfig() {\n const snapshot = currentPublicConfig ? structuredClone(currentPublicConfig) : null\n const authz = currentAuthz\n if (!snapshot || !authz)\n return notInitialized.result<IamPublicConfig>()\n if (!snapshot.reauthentication.enabled)\n return ok(snapshot)\n const configured = await authz.getSensitiveOperations()\n if (!configured.success)\n return configured\n return ok({ ...snapshot, reauthentication: { ...snapshot.reauthentication, operations: [...new Set([...snapshot.reauthentication.operations, ...configured.data])].sort() } })\n },\n get user(): UserOperations {\n return currentUser ?? notInitializedUser\n },\n get authz(): AuthzOperations {\n return currentAuthz ?? notInitializedAuthz\n },\n get session(): SessionOperations {\n return currentSession ?? notInitializedSession\n },\n get apiKey(): ApiKeyOperations {\n return currentApiKey ?? notInitializedApiKey\n },\n get ticket(): TicketOperations {\n return currentTicket ?? notInitializedTicket\n },\n get config() {\n return currentConfig ? core.sanitize.sanitizeSensitiveFields(currentConfig) : null\n },\n get publicConfig() {\n return currentPublicConfig ? structuredClone(currentPublicConfig) : null\n },\n get isInitialized() {\n return currentConfig !== null\n },\n get isRegisterEnabled() {\n return currentConfig?.register?.enabled !== false\n },\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 clearInterval(accountScanTimer)\n accountScanTimer = undefined\n await accountScanRunning\n\n currentAuth = null\n currentUser = null\n currentAuthz = null\n currentSession = null\n currentApiKey = null\n currentTicket = null\n currentConfig = null\n currentPublicConfig = null\n\n // 重置所有仓库单例,释放对旧 db 实例的引用\n resetApiKeyRepoSingleton()\n resetOtpRepoSingleton()\n resetUserRepoSingleton()\n resetRoleRepoSingleton()\n resetPermissionRepoSingleton()\n\n logger.info('IAM module closed')\n },\n}\n"]}