@h-ai/iam 0.1.0-alpha.70 → 0.1.0-alpha.71

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":["../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/iam-i18n.ts","../src/authn/apikey/iam-authn-apikey-repository.ts","../src/iam-agreement.ts","../src/user/iam-user-repository-user.ts","../src/authn/apikey/iam-authn-apikey-scope.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-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-notifications.ts","../src/iam-public-config.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/ticket/iam-ticket-functions.ts","../src/user/iam-user-functions.ts","../src/iam-main.ts"],"names":["TABLE_NAME","reldb","BaseReldbCrudRepository","ok","err","core","haiCrypto","logger","mapRepositoryError","cache","crypto"],"mappings":"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","file":"index.js","sourcesContent":["{\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_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_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\": \"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 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_notificationDeliveryUnknown\": \"Notification delivery is unknown and may have succeeded; do not resend automatically.\"\n}\n","{\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_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_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_notificationDeliveryUnknown\": \"通知の配信結果は不明で、成功した可能性があります。自動で再送しないでください。\"\n}\n","{\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_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_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_notificationDeliveryUnknown\": \"通知可能已送达,结果未知;请勿自动重发。\"\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","/**\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 { 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 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 *\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 * @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 setPassword: (input: { userId: string, expectedVersion: string, passwordHash: string }) => 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: { maxLoginAttempts: number, lockoutDuration: number }) => Promise<HaiResult<void>>\n /** 仅未锁定且启用的账户可以清除失败计数。 */\n resetLoginFailures: (userId: string, expectedCredentialVersion: string) => 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: '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: '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.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 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 /** 改密推进凭据代际;会话存储清理失败也不能让旧凭据恢复授权。 */\n async setPassword(input: { userId: string, expectedVersion: 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 = ?, reset_hash = NULL, reset_expires_at = NULL, reset_attempts = 0 WHERE id = ? AND credential_version = ? AND enabled = ?`,\n [input.passwordHash, reldb.config?.type === 'sqlite' ? Date.now() : new Date(), crypto.randomUUID(), crypto.randomUUID(), input.userId, input.expectedVersion, reldb.config?.type === 'postgresql' ? true : 1],\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 enabled = ? AND ? > ${this.databaseNow()}`,\n [input.tokenHash, expiry, crypto.randomUUID(), input.user.id, input.user.credentialVersion ?? '', input.user.resetVersion ?? '', reldb.config?.type === 'postgresql' ? true : 1, 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 (!user.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\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 enabled = ?`,\n [version, user.id, tokenHash, user.resetVersion ?? '', user.credentialVersion ?? '', maxAttempts, reldb.config?.type === 'postgresql' ? true : 1],\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 = ?, reset_hash = NULL, reset_expires_at = NULL, reset_attempts = 0, login_failed_count = 0, 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 enabled = ?`,\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 ?? '', reldb.config?.type === 'postgresql' ? true : 1],\n )\n return result.success ? ok(result.data.changes === 1) : this.buildQueryError(result.error, result.error)\n }\n\n async recordLoginFailure(userId: string, policy: { maxLoginAttempts: number, lockoutDuration: number }): Promise<HaiResult<void>> {\n const sqlite = reldb.config?.type === 'sqlite'\n const now = sqlite ? Date.now() : new Date()\n const deadline = Date.now() + 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, last_login_failed_at = NULL WHERE id = ? AND locked_until <= ?`, [userId, now])\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): Promise<HaiResult<void>> {\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET login_failed_count = 0, last_login_failed_at = NULL, locked_until = NULL WHERE id = ? AND credential_version = ? AND enabled = ? AND (locked_until IS NULL OR locked_until <= ?)`,\n [userId, expectedCredentialVersion, reldb.config?.type === 'postgresql' ? true : 1, reldb.config?.type === 'sqlite' ? Date.now() : new Date()],\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?.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n if ((user.data.credentialVersion ?? '') !== expectedCredentialVersion)\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n if (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-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 * @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 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 * @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 maxLoginAttempts: number\n /** 锁定时长(秒) */\n lockoutDuration: number\n}\n\n/**\n * 判断账户是否被锁定\n *\n * @param user - 内部用户数据(含 lockedUntil 字段)\n * @returns 锁定中返回 true;未设置或已到期返回 false\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function canAttempt(user: StoredUser): boolean {\n * return user.enabled && !isAccountLocked(user)\n * }\n * ```\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 * @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 * @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): Promise<HaiResult<void>> {\n return userRepository.resetLoginFailures(user.id, user.credentialVersion ?? '')\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 { 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 * @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 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: 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 (!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({ 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","/** 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 { 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 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 defaultEnabled?: boolean\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\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 (!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 const failureResult = await recordLoginFailure(userRepository, storedUser, { maxLoginAttempts, lockoutDuration })\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 enabled: config.defaultEnabled ?? 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<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)\n if (!resetResult.success)\n return resetResult\n logger.info('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 { 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 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 registerConfig = config.registerConfig\n const allowAutoRegister = registerConfig?.enabled ?? config.autoRegister ?? false\n const defaultEnabled = registerConfig?.defaultEnabled ?? true\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 (!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 // 单 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, { maxLoginAttempts, lockoutDuration })\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 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\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 (!storedUser.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n const resetResult = await resetLoginFailures(config.userRepository, storedUser)\n if (!resetResult.success)\n return resetResult\n logger.info('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 { toUser } from '../../user/iam-user-utils.js'\nimport { ensureCredentialType, isAccountLocked, recordLoginFailure, 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 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 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 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 const failureResult = await recordLoginFailure(config.userRepository, user, { maxLoginAttempts, lockoutDuration })\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 // 防止用户枚举:执行伪哈希验证以消除时序差异,统一返回 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<AuthenticatedUser>\n\n // 验证密码\n const pwResult = await verifyUserPassword(storedUser, password)\n if (!pwResult.success)\n return pwResult as HaiResult<AuthenticatedUser>\n\n // 检查密码是否过期\n if (isPasswordExpired(storedUser)) {\n return err(HaiIamError.PASSWORD_EXPIRED, iamM('iam_passwordExpired'))\n }\n\n // 登录成功,重置失败计数\n const resetResult = await resetLoginFailures(config.userRepository, storedUser)\n if (!resetResult.success)\n return resetResult\n logger.info('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, 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 { createDbUserRepository } from '../user/iam-user-repository-user.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 { 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) => 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 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) {\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 defaultEnabled: config.register.defaultEnabled,\n maxLoginAttempts: securityConfig.maxLoginAttempts,\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\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): Promise<HaiResult<AuthResult>> {\n if (!user.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\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 })\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 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 ): 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 { loginRegisteredUser: async (user) => {\n const stored = await userRepository.findById(user.id)\n if (!stored.success)\n return stored\n if (!stored.data?.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n return buildAuthResult({ ...user, credentialVersion: stored.data.credentialVersion ?? '' })\n }, authn: {\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 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)\n },\n\n async logout(accessToken: string): Promise<HaiResult<void>> {\n // 不先读取/滑动 access;过期 access 对应的 refresh 也必须在同一次 CAS 中撤销。\n return sessionFunctions.delete(accessToken)\n },\n\n async verifyToken(accessToken: string): Promise<HaiResult<Session>> {\n const session = await sessionFunctions.verifyToken(accessToken)\n if (!session.success)\n return session\n const [user, authorization] = await Promise.all([\n userRepository.findById(session.data.userId),\n authzFunctions.getUserAuthorization(session.data.userId),\n ])\n if (!user.success)\n return user\n if (!user.data?.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n if (session.data.credentialVersion !== (user.data.credentialVersion ?? ''))\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n if (!authorization.success)\n return authorization\n const current = { ...session.data, username: user.data.username, displayName: user.data.displayName, avatarUrl: user.data.avatarUrl, ...authorization.data }\n return ok(current.apiKeyId ? applyApiKeyScopes(current, current.apiKeyScopes ?? []) : current)\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 * @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 /**\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.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 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 { 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 * @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(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 * @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 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 /** 在调用方事务中完整替换权限,任何一步失败由外层统一回滚。 */\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 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 getUserAuthorization(userId) {\n const roles = await userRoleRepository.getRoleSummaries(userId)\n if (!roles.success)\n return roles\n const permissions = roles.data.length\n ? await rolePermissionRepository.getPermissionCodesForRoles(roles.data.map(role => role.id))\n : ok<string[]>([])\n if (!permissions.success)\n return permissions\n return ok({ roles: roles.data.map(role => role.code), permissions: permissions.data })\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 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 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 (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 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 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 // 角色代码可能变更,强制下次 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","/** 将已初始化 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 })\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 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 }\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 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 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: SessionConfigSchema.parse(config.session ?? {}).maxAge },\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 * @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 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'\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 accessToken,\n createdAt: 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 * 同一用户的会话、refresh 消费状态与索引放入一个版本化文档,单键 CAS 原子提交。\n * Cluster 只访问一个 slot,不使用进程锁、租约或跨 key 补偿发布认证状态。\n * @module iam-session-repository-cache\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'\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), lastActiveAt: new Date(session.lastActiveAt), expiresAt: new Date(session.expiresAt) }\n if (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.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(refreshTokenMaxAge: number): SessionRepository {\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())\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 if (singleDevice)\n state.sessions = {}\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())\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 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() ? 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 return ok(restoreSession(record.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())\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 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())\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: 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 { 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 /** 可信持久用户读取口;生产绑定RelDB,缺失/禁用/读失败均拒绝签发和认证。 */\n readCredential: (userId: string) => Promise<HaiResult<{ version: string, enabled: boolean } | 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 )\n\n const functions = buildSessionFunctions({\n readCredential: deps.readCredential,\n maxAge: sessionConfig.maxAge,\n sliding: sessionConfig.sliding,\n singleDevice: sessionConfig.singleDevice,\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 /** 会话存储 */\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 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<string>> {\n try {\n const current = await config.readCredential(userId)\n if (!current.success)\n return current\n if (!current.data || current.data.enabled !== true)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\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.version)\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 config.apiKeyRepository.findOneById(session.apiKeyId)\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 && new Date() >= 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)\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)\n if (!validated.success)\n return validated\n let output = validated.data\n\n if (sliding) {\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 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 * 基于 @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-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 { 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 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 { reldb } from '@h-ai/reldb'\n\nimport { isAccountLocked, recordLoginFailure, 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 { toUser } 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 enabled: 'enabled',\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 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 * @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: { enabled: boolean, defaultEnabled: boolean }\n agreementConfig: IamConfig['agreements']\n resetConfig: { enabled: boolean, tokenExpiresIn: number, maxAttempts: number }\n loginConfig: { maxLoginAttempts: number, lockoutDuration: number }\n onPasswordResetRequest?: (user: User, token: string, context: IamNotificationContext) => Promise<void>\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 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, enabled: boolean): 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,\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 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 register(options) {\n if (!registerConfig.enabled)\n return Promise.resolve(err(HaiIamError.REGISTER_DISABLED, iamM('iam_registerDisabled')))\n return createUser(options, registerConfig.defaultEnabled)\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?.enabled !== undefined) {\n conditions.push('enabled = ?')\n params.push(options.enabled ? 1 : 0)\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.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.setPassword({ userId, expectedVersion: userResult.data.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('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.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\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 // 记录失败计数 / 触发锁定,防止通过 changePassword 端点暴力枚举旧密码\n const failureResult = await recordLoginFailure(userRepository, user, {\n maxLoginAttempts: ctx.loginConfig.maxLoginAttempts,\n lockoutDuration: ctx.loginConfig.lockoutDuration,\n })\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)\n if (!resetResult.success)\n return resetResult\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.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/**\n * 构建密码重置操作(请求重置、确认重置)\n */\nfunction buildPasswordResetOps(ctx: UserFnContext): Pick<UserOperations, 'requestPasswordReset' | 'confirmPasswordReset'> {\n const { userRepository, sessionFunctions, 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 = 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 (!user.enabled)\n return ok(undefined)\n\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: userResult.data, 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 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 = validatePassword(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 return {\n ...buildRegistrationOps(ctx),\n ...buildUserQueryOps(ctx),\n ...buildUserMutationOps(ctx),\n ...buildPasswordChangeOps(ctx),\n ...buildPasswordResetOps(ctx),\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 { IamConfigSchema } from './iam-config.js'\nimport { iamM } from './iam-i18n.js'\nimport { resolveIamNotifications } from './iam-notifications.js'\nimport { buildIamPublicConfig } from './iam-public-config.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'\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\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 credentialUsers = await createDbUserRepository()\n const sessionResult = await createSessionOperations({\n config: parsed,\n readCredential: async (userId) => {\n const found = await credentialUsers.findById(userId)\n if (!found.success)\n return found\n return ok(found.data ? { version: found.data.credentialVersion ?? '', enabled: found.data.enabled } : null)\n },\n })\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 currentPublicConfig = buildIamPublicConfig(parsed, { ...config, onPasswordResetRequest, onOtpSendEmail, onOtpSendSms })\n currentApiKey = authnResult.data.apiKeyFunctions\n // 一次性票据能力(仅依赖 cache + crypto,随 IAM 初始化即可用)\n currentTicket = createTicketOperations()\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 authnResult.data.loginRegisteredUser(regResult.data.user)\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 ticket(): TicketOperations { return currentTicket ?? notInitializedTicket },\n get config() { return currentConfig ? core.sanitize.sanitizeSensitiveFields(currentConfig) : null },\n get publicConfig() { return currentPublicConfig ? structuredClone(currentPublicConfig) : null },\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 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"]}
1
+ {"version":3,"sources":["../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/iam-i18n.ts","../src/authn/apikey/iam-authn-apikey-repository.ts","../src/iam-agreement.ts","../src/user/iam-user-repository-user.ts","../src/authn/apikey/iam-authn-apikey-scope.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-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-migration.ts","../src/iam-notifications.ts","../src/iam-public-config.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/ticket/iam-ticket-functions.ts","../src/user/iam-user-functions.ts","../src/iam-main.ts"],"names":["TABLE_NAME","reldb","BaseReldbCrudRepository","ok","err","core","haiCrypto","logger","mapRepositoryError","cache","HaiReldbError","crypto"],"mappings":"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","file":"index.js","sourcesContent":["{\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_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_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\": \"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 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_notificationDeliveryUnknown\": \"Notification delivery is unknown and may have succeeded; do not resend automatically.\"\n}\n","{\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_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_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_notificationDeliveryUnknown\": \"通知の配信結果は不明で、成功した可能性があります。自動で再送しないでください。\"\n}\n","{\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_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_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_notificationDeliveryUnknown\": \"通知可能已送达,结果未知;请勿自动重发。\"\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","/**\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 { 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 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 *\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 * @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 setPassword: (input: { userId: string, expectedVersion: string, passwordHash: string }) => 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: { maxLoginAttempts: number, lockoutDuration: number }) => Promise<HaiResult<void>>\n /** 仅未锁定且启用的账户可以清除失败计数。 */\n resetLoginFailures: (userId: string, expectedCredentialVersion: string) => 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: '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: '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.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 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 /** 改密推进凭据代际;会话存储清理失败也不能让旧凭据恢复授权。 */\n async setPassword(input: { userId: string, expectedVersion: 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 = ?, reset_hash = NULL, reset_expires_at = NULL, reset_attempts = 0 WHERE id = ? AND credential_version = ? AND enabled = ?`,\n [input.passwordHash, reldb.config?.type === 'sqlite' ? Date.now() : new Date(), crypto.randomUUID(), crypto.randomUUID(), input.userId, input.expectedVersion, reldb.config?.type === 'postgresql' ? true : 1],\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 enabled = ? AND ? > ${this.databaseNow()}`,\n [input.tokenHash, expiry, crypto.randomUUID(), input.user.id, input.user.credentialVersion ?? '', input.user.resetVersion ?? '', reldb.config?.type === 'postgresql' ? true : 1, 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 (!user.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\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 enabled = ?`,\n [version, user.id, tokenHash, user.resetVersion ?? '', user.credentialVersion ?? '', maxAttempts, reldb.config?.type === 'postgresql' ? true : 1],\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 = ?, reset_hash = NULL, reset_expires_at = NULL, reset_attempts = 0, login_failed_count = 0, 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 enabled = ?`,\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 ?? '', reldb.config?.type === 'postgresql' ? true : 1],\n )\n return result.success ? ok(result.data.changes === 1) : this.buildQueryError(result.error, result.error)\n }\n\n async recordLoginFailure(userId: string, policy: { maxLoginAttempts: number, lockoutDuration: number }): Promise<HaiResult<void>> {\n const sqlite = reldb.config?.type === 'sqlite'\n const now = sqlite ? Date.now() : new Date()\n const deadline = Date.now() + 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, last_login_failed_at = NULL WHERE id = ? AND locked_until <= ?`, [userId, now])\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): Promise<HaiResult<void>> {\n const result = await reldb.sql.execute(\n `UPDATE ${TABLE_NAME} SET login_failed_count = 0, last_login_failed_at = NULL, locked_until = NULL WHERE id = ? AND credential_version = ? AND enabled = ? AND (locked_until IS NULL OR locked_until <= ?)`,\n [userId, expectedCredentialVersion, reldb.config?.type === 'postgresql' ? true : 1, reldb.config?.type === 'sqlite' ? Date.now() : new Date()],\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?.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n if ((user.data.credentialVersion ?? '') !== expectedCredentialVersion)\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n if (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-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 * @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 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 * @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 maxLoginAttempts: number\n /** 锁定时长(秒) */\n lockoutDuration: number\n}\n\n/**\n * 判断账户是否被锁定\n *\n * @param user - 内部用户数据(含 lockedUntil 字段)\n * @returns 锁定中返回 true;未设置或已到期返回 false\n * @internal\n * @example 模块内部上下文\n * ```ts\n * function canAttempt(user: StoredUser): boolean {\n * return user.enabled && !isAccountLocked(user)\n * }\n * ```\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 * @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 * @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): Promise<HaiResult<void>> {\n return userRepository.resetLoginFailures(user.id, user.credentialVersion ?? '')\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 { 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 * @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 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: 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 (!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({ 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","/** 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 { 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 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 defaultEnabled?: boolean\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\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 (!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 const failureResult = await recordLoginFailure(userRepository, storedUser, { maxLoginAttempts, lockoutDuration })\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 enabled: config.defaultEnabled ?? 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<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)\n if (!resetResult.success)\n return resetResult\n logger.info('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 { 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 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 registerConfig = config.registerConfig\n const allowAutoRegister = registerConfig?.enabled ?? config.autoRegister ?? false\n const defaultEnabled = registerConfig?.defaultEnabled ?? true\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 (!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 // 单 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, { maxLoginAttempts, lockoutDuration })\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 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\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 (!storedUser.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n const resetResult = await resetLoginFailures(config.userRepository, storedUser)\n if (!resetResult.success)\n return resetResult\n logger.info('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 { toUser } from '../../user/iam-user-utils.js'\nimport { ensureCredentialType, isAccountLocked, recordLoginFailure, 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 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 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 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 const failureResult = await recordLoginFailure(config.userRepository, user, { maxLoginAttempts, lockoutDuration })\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 // 防止用户枚举:执行伪哈希验证以消除时序差异,统一返回 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<AuthenticatedUser>\n\n // 验证密码\n const pwResult = await verifyUserPassword(storedUser, password)\n if (!pwResult.success)\n return pwResult as HaiResult<AuthenticatedUser>\n\n // 检查密码是否过期\n if (isPasswordExpired(storedUser)) {\n return err(HaiIamError.PASSWORD_EXPIRED, iamM('iam_passwordExpired'))\n }\n\n // 登录成功,重置失败计数\n const resetResult = await resetLoginFailures(config.userRepository, storedUser)\n if (!resetResult.success)\n return resetResult\n logger.info('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, 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 { createDbUserRepository } from '../user/iam-user-repository-user.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 { 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) => 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 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) {\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 defaultEnabled: config.register.defaultEnabled,\n maxLoginAttempts: securityConfig.maxLoginAttempts,\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\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): Promise<HaiResult<AuthResult>> {\n if (!user.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\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 })\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 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 ): 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 { loginRegisteredUser: async (user) => {\n const stored = await userRepository.findById(user.id)\n if (!stored.success)\n return stored\n if (!stored.data?.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n return buildAuthResult({ ...user, credentialVersion: stored.data.credentialVersion ?? '' })\n }, authn: {\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 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)\n },\n\n async logout(accessToken: string): Promise<HaiResult<void>> {\n // 不先读取/滑动 access;过期 access 对应的 refresh 也必须在同一次 CAS 中撤销。\n return sessionFunctions.delete(accessToken)\n },\n\n async verifyToken(accessToken: string): Promise<HaiResult<Session>> {\n const session = await sessionFunctions.verifyToken(accessToken)\n if (!session.success)\n return session\n const [user, authorization] = await Promise.all([\n userRepository.findById(session.data.userId),\n authzFunctions.getUserAuthorization(session.data.userId),\n ])\n if (!user.success)\n return user\n if (!user.data?.enabled)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\n if (session.data.credentialVersion !== (user.data.credentialVersion ?? ''))\n return err(HaiIamError.SESSION_INVALID, iamM('iam_sessionExpired'))\n if (!authorization.success)\n return authorization\n const current = { ...session.data, username: user.data.username, displayName: user.data.displayName, avatarUrl: user.data.avatarUrl, ...authorization.data }\n return ok(current.apiKeyId ? applyApiKeyScopes(current, current.apiKeyScopes ?? []) : current)\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 * @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 /**\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.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 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 { audit } from '@h-ai/audit'\nimport { core, err, ok } from '@h-ai/core'\nimport { HaiReldbError, 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 * @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(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 * @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 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 /** 在调用方事务中完整替换权限,任何一步失败由外层统一回滚。 */\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 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 getUserAuthorization(userId) {\n const roles = await userRoleRepository.getRoleSummaries(userId)\n if (!roles.success)\n return roles\n const permissions = roles.data.length\n ? await rolePermissionRepository.getPermissionCodesForRoles(roles.data.map(role => role.id))\n : ok<string[]>([])\n if (!permissions.success)\n return permissions\n return ok({ roles: roles.data.map(role => role.code), permissions: permissions.data })\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 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 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 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 // 角色代码可能变更,强制下次 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 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 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 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","/** 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 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\n/**\n * 预检或迁移 IAM 表。升级保留用户和密码;旧版无安全代次的会话需重新登录。\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 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 }\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 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 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: SessionConfigSchema.parse(config.session ?? {}).maxAge },\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 * @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 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'\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 accessToken,\n createdAt: 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 * 同一用户的会话、refresh 消费状态与索引放入一个版本化文档,单键 CAS 原子提交。\n * Cluster 只访问一个 slot,不使用进程锁、租约或跨 key 补偿发布认证状态。\n * @module iam-session-repository-cache\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'\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), lastActiveAt: new Date(session.lastActiveAt), expiresAt: new Date(session.expiresAt) }\n if (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.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(refreshTokenMaxAge: number): SessionRepository {\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())\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 if (singleDevice)\n state.sessions = {}\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())\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 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() ? 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 return ok(restoreSession(record.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())\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 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())\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: 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 { 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 /** 可信持久用户读取口;生产绑定RelDB,缺失/禁用/读失败均拒绝签发和认证。 */\n readCredential: (userId: string) => Promise<HaiResult<{ version: string, enabled: boolean } | 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 )\n\n const functions = buildSessionFunctions({\n readCredential: deps.readCredential,\n maxAge: sessionConfig.maxAge,\n sliding: sessionConfig.sliding,\n singleDevice: sessionConfig.singleDevice,\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 /** 会话存储 */\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 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<string>> {\n try {\n const current = await config.readCredential(userId)\n if (!current.success)\n return current\n if (!current.data || current.data.enabled !== true)\n return err(HaiIamError.USER_DISABLED, iamM('iam_accountDisabled'))\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.version)\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 config.apiKeyRepository.findOneById(session.apiKeyId)\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 && new Date() >= 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)\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)\n if (!validated.success)\n return validated\n let output = validated.data\n\n if (sliding) {\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 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 * 基于 @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-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 } 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 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 { isAccountLocked, recordLoginFailure, 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 { toUser } 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 enabled: 'enabled',\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: { enabled: boolean, defaultEnabled: boolean }\n agreementConfig: IamConfig['agreements']\n resetConfig: { enabled: boolean, tokenExpiresIn: number, maxAttempts: number }\n loginConfig: { maxLoginAttempts: number, lockoutDuration: number }\n onPasswordResetRequest?: (user: User, token: string, context: IamNotificationContext) => Promise<void>\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 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, enabled: boolean): 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,\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 register(options) {\n if (!registerConfig.enabled)\n return Promise.resolve(err(HaiIamError.REGISTER_DISABLED, iamM('iam_registerDisabled')))\n return createUser(options, registerConfig.defaultEnabled)\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?.enabled !== undefined) {\n conditions.push('enabled = ?')\n params.push(options.enabled ? 1 : 0)\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 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) 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.setPassword({ userId, expectedVersion: userResult.data.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('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.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\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 // 记录失败计数 / 触发锁定,防止通过 changePassword 端点暴力枚举旧密码\n const failureResult = await recordLoginFailure(userRepository, user, {\n maxLoginAttempts: ctx.loginConfig.maxLoginAttempts,\n lockoutDuration: ctx.loginConfig.lockoutDuration,\n })\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)\n if (!resetResult.success)\n return resetResult\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.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/**\n * 构建密码重置操作(请求重置、确认重置)\n */\nfunction buildPasswordResetOps(ctx: UserFnContext): Pick<UserOperations, 'requestPasswordReset' | 'confirmPasswordReset'> {\n const { userRepository, sessionFunctions, 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 = 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 (!user.enabled)\n return ok(undefined)\n\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: userResult.data, 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 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 = validatePassword(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 return {\n ...buildRegistrationOps(ctx),\n ...buildUserQueryOps(ctx),\n ...buildUserMutationOps(ctx),\n ...buildPasswordChangeOps(ctx),\n ...buildPasswordResetOps(ctx),\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 { 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 { 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'\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\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 credentialUsers.findById(userId)\n if (!found.success)\n return found\n return ok(found.data ? { version: found.data.credentialVersion ?? '', enabled: found.data.enabled } : null)\n },\n })\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 currentPublicConfig = buildIamPublicConfig(parsed, { ...config, onPasswordResetRequest, onOtpSendEmail, onOtpSendSms })\n currentApiKey = authnResult.data.apiKeyFunctions\n // 一次性票据能力(仅依赖 cache + crypto,随 IAM 初始化即可用)\n currentTicket = createTicketOperations()\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 authnResult.data.loginRegisteredUser(regResult.data.user)\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 {\n return currentAuth ?? notInitializedAuth\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\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"]}