@h-ai/iam 0.1.0-alpha.18 → 0.1.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -86,6 +86,8 @@ const hasPermission = await iam.authz.checkPermission(
86
86
  await iam.close()
87
87
  ```
88
88
 
89
+ `iam.config` 返回的是**脱敏后的配置快照**:LDAP `url` / `bindPassword` 等敏感配置会自动隐藏,便于状态检查但不能代替原始配置源。
90
+
89
91
  ## 设计说明
90
92
 
91
93
  ### 架构概览
package/dist/index.d.ts CHANGED
@@ -1364,7 +1364,7 @@ interface IamFunctions {
1364
1364
  * 关闭后访问 `iam.auth` 等属性将返回未初始化错误。
1365
1365
  */
1366
1366
  close: () => Promise<void>;
1367
- /** 当前配置(未初始化时为 null) */
1367
+ /** 当前脱敏后的配置快照(未初始化时为 null) */
1368
1368
  readonly config: IamConfig | null;
1369
1369
  /** 是否已初始化 */
1370
1370
  readonly isInitialized: boolean;
package/dist/index.js CHANGED
@@ -663,18 +663,18 @@ var API_KEY_FIELDS = [
663
663
  }
664
664
  ];
665
665
  var apiKeyRepoInstance = null;
666
- var apiKeyRepoDbConfig = null;
666
+ var apiKeyRepoSqlOps = null;
667
667
  function resetApiKeyRepoSingleton() {
668
668
  apiKeyRepoInstance = null;
669
- apiKeyRepoDbConfig = null;
669
+ apiKeyRepoSqlOps = null;
670
670
  }
671
671
  async function createDbApiKeyRepository() {
672
- if (apiKeyRepoInstance && apiKeyRepoDbConfig === reldb.config)
672
+ if (apiKeyRepoInstance && apiKeyRepoSqlOps === reldb.sql)
673
673
  return apiKeyRepoInstance;
674
674
  const repo = new DbApiKeyRepository();
675
675
  await repo.count();
676
676
  apiKeyRepoInstance = repo;
677
- apiKeyRepoDbConfig = reldb.config;
677
+ apiKeyRepoSqlOps = reldb.sql;
678
678
  return repo;
679
679
  }
680
680
  var DbApiKeyRepository = class extends BaseReldbCrudRepository {
@@ -753,6 +753,20 @@ var DbApiKeyRepository = class extends BaseReldbCrudRepository {
753
753
  );
754
754
  }
755
755
  };
756
+
757
+ // src/iam-agreement.ts
758
+ function buildAgreementDisplay(config, enabled) {
759
+ if (!enabled)
760
+ return void 0;
761
+ if (!config.userAgreementUrl && !config.privacyPolicyUrl)
762
+ return void 0;
763
+ return {
764
+ userAgreementUrl: config.userAgreementUrl,
765
+ privacyPolicyUrl: config.privacyPolicyUrl,
766
+ showOnRegister: config.showOnRegister,
767
+ showOnLogin: config.showOnLogin
768
+ };
769
+ }
756
770
  var TABLE_NAME2 = "hai_iam_users";
757
771
  var USER_FIELDS = [
758
772
  {
@@ -893,18 +907,18 @@ var USER_FIELDS = [
893
907
  }
894
908
  ];
895
909
  var userRepoInstance = null;
896
- var userRepoDbConfig = null;
910
+ var userRepoSqlOps = null;
897
911
  function resetUserRepoSingleton() {
898
912
  userRepoInstance = null;
899
- userRepoDbConfig = null;
913
+ userRepoSqlOps = null;
900
914
  }
901
915
  async function createDbUserRepository() {
902
- if (userRepoInstance && userRepoDbConfig === reldb.config)
916
+ if (userRepoInstance && userRepoSqlOps === reldb.sql)
903
917
  return userRepoInstance;
904
918
  const repo = new DbUserRepository();
905
919
  await repo.count();
906
920
  userRepoInstance = repo;
907
- userRepoDbConfig = reldb.config;
921
+ userRepoSqlOps = reldb.sql;
908
922
  return repo;
909
923
  }
910
924
  var DbUserRepository = class extends BaseReldbCrudRepository {
@@ -1503,9 +1517,6 @@ function createOtpStrategy(config) {
1503
1517
  const registerConfig = config.registerConfig;
1504
1518
  const allowAutoRegister = registerConfig?.enabled ?? config.autoRegister ?? false;
1505
1519
  const defaultEnabled = registerConfig?.defaultEnabled ?? true;
1506
- function buildChallengeResult(expiresAt) {
1507
- return { expiresAt };
1508
- }
1509
1520
  const strategy = {
1510
1521
  type: "otp",
1511
1522
  name: "otp-strategy",
@@ -1633,7 +1644,7 @@ function createOtpStrategy(config) {
1633
1644
  iamM("iam_identifierTypeNotSupported")
1634
1645
  );
1635
1646
  }
1636
- const result = buildChallengeResult(expiresAt);
1647
+ const result = { expiresAt };
1637
1648
  logger3.debug("OTP challenge sent", { identifier, expiresAt });
1638
1649
  return ok(result);
1639
1650
  }
@@ -1870,20 +1881,6 @@ function buildAuthnOperations(deps) {
1870
1881
  } = deps;
1871
1882
  const loginConfig = LoginConfigSchema.parse(config.login ?? {});
1872
1883
  const agreementConfig = AgreementConfigSchema.parse(config.agreements ?? {});
1873
- function buildAgreementDisplay() {
1874
- if (!agreementConfig.showOnLogin) {
1875
- return void 0;
1876
- }
1877
- if (!agreementConfig.userAgreementUrl && !agreementConfig.privacyPolicyUrl) {
1878
- return void 0;
1879
- }
1880
- return {
1881
- userAgreementUrl: agreementConfig.userAgreementUrl,
1882
- privacyPolicyUrl: agreementConfig.privacyPolicyUrl,
1883
- showOnRegister: agreementConfig.showOnRegister,
1884
- showOnLogin: agreementConfig.showOnLogin
1885
- };
1886
- }
1887
1884
  function loginDisabled(type) {
1888
1885
  if (!loginConfig[type]) {
1889
1886
  return err(
@@ -1960,7 +1957,7 @@ function buildAuthnOperations(deps) {
1960
1957
  tokens: tokenPair,
1961
1958
  roles: roleCodesResult.data,
1962
1959
  permissions: permCodesResult.data,
1963
- agreements: buildAgreementDisplay()
1960
+ agreements: buildAgreementDisplay(agreementConfig, agreementConfig.showOnLogin)
1964
1961
  });
1965
1962
  }
1966
1963
  async function loginWithStrategy(type, credentials, strategy) {
@@ -2103,18 +2100,18 @@ var PERMISSION_FIELDS = [
2103
2100
  }
2104
2101
  ];
2105
2102
  var permRepoInstance = null;
2106
- var permRepoDbConfig = null;
2103
+ var permRepoSqlOps = null;
2107
2104
  function resetPermissionRepoSingleton() {
2108
2105
  permRepoInstance = null;
2109
- permRepoDbConfig = null;
2106
+ permRepoSqlOps = null;
2110
2107
  }
2111
2108
  async function createDbPermissionRepository() {
2112
- if (permRepoInstance && permRepoDbConfig === reldb.config)
2109
+ if (permRepoInstance && permRepoSqlOps === reldb.sql)
2113
2110
  return permRepoInstance;
2114
2111
  const repo = new DbPermissionRepository();
2115
2112
  await repo.count();
2116
2113
  permRepoInstance = repo;
2117
- permRepoDbConfig = reldb.config;
2114
+ permRepoSqlOps = reldb.sql;
2118
2115
  return repo;
2119
2116
  }
2120
2117
  var DbPermissionRepository = class extends BaseReldbCrudRepository {
@@ -2619,18 +2616,18 @@ var ROLE_FIELDS = [
2619
2616
  }
2620
2617
  ];
2621
2618
  var roleRepoInstance = null;
2622
- var roleRepoDbConfig = null;
2619
+ var roleRepoSqlOps = null;
2623
2620
  function resetRoleRepoSingleton() {
2624
2621
  roleRepoInstance = null;
2625
- roleRepoDbConfig = null;
2622
+ roleRepoSqlOps = null;
2626
2623
  }
2627
2624
  async function createDbRoleRepository() {
2628
- if (roleRepoInstance && roleRepoDbConfig === reldb.config)
2625
+ if (roleRepoInstance && roleRepoSqlOps === reldb.sql)
2629
2626
  return roleRepoInstance;
2630
2627
  const repo = new DbRoleRepository();
2631
2628
  await repo.count();
2632
2629
  roleRepoInstance = repo;
2633
- roleRepoDbConfig = reldb.config;
2630
+ roleRepoSqlOps = reldb.sql;
2634
2631
  return repo;
2635
2632
  }
2636
2633
  var DbRoleRepository = class extends BaseReldbCrudRepository {
@@ -3561,6 +3558,13 @@ function restoreSessionDates(session) {
3561
3558
  expiresAt: session.expiresAt instanceof Date ? session.expiresAt : new Date(session.expiresAt)
3562
3559
  };
3563
3560
  }
3561
+ function buildRepositoryError(messageKey, message, cause) {
3562
+ return err(
3563
+ HaiIamError.REPOSITORY_ERROR,
3564
+ iamM(messageKey, { params: { message } }),
3565
+ cause
3566
+ );
3567
+ }
3564
3568
  function createCacheSessionRepository(sessionMaxAge, refreshTokenMaxAge) {
3565
3569
  const repo = {
3566
3570
  async save(session, tokenPair) {
@@ -3639,31 +3643,82 @@ function createCacheSessionRepository(sessionMaxAge, refreshTokenMaxAge) {
3639
3643
  return ok(void 0);
3640
3644
  },
3641
3645
  async removeByAccessToken(accessToken) {
3642
- const sessionResult = await cache.kv.get(buildTokenKey(accessToken));
3643
- if (sessionResult.success && sessionResult.data) {
3646
+ const tokenKey = buildTokenKey(accessToken);
3647
+ const sessionResult = await cache.kv.get(tokenKey);
3648
+ if (!sessionResult.success) {
3649
+ return buildRepositoryError(
3650
+ "iam_querySessionMappingCacheFailed",
3651
+ sessionResult.error.message,
3652
+ sessionResult.error
3653
+ );
3654
+ }
3655
+ if (sessionResult.data) {
3644
3656
  const session = sessionResult.data;
3645
- await cache.set_.srem(buildUserTokensKey(session.userId), accessToken);
3657
+ const removeUserTokenResult = await cache.set_.srem(buildUserTokensKey(session.userId), accessToken);
3658
+ if (!removeUserTokenResult.success) {
3659
+ return buildRepositoryError(
3660
+ "iam_deleteUserSessionCacheFailed",
3661
+ removeUserTokenResult.error.message,
3662
+ removeUserTokenResult.error
3663
+ );
3664
+ }
3646
3665
  const tokenPair = session.data?._tokenPair;
3647
3666
  if (tokenPair?.refreshToken) {
3648
- await cache.kv.del(buildRefreshKey(tokenPair.refreshToken));
3667
+ const removeRefreshTokenResult = await cache.kv.del(buildRefreshKey(tokenPair.refreshToken));
3668
+ if (!removeRefreshTokenResult.success) {
3669
+ return buildRepositoryError(
3670
+ "iam_deleteSessionMappingCacheFailed",
3671
+ removeRefreshTokenResult.error.message,
3672
+ removeRefreshTokenResult.error
3673
+ );
3674
+ }
3649
3675
  }
3650
3676
  }
3651
- await cache.kv.del(buildTokenKey(accessToken));
3677
+ const removeSessionResult = await cache.kv.del(tokenKey);
3678
+ if (!removeSessionResult.success) {
3679
+ return buildRepositoryError(
3680
+ "iam_deleteSessionMappingCacheFailed",
3681
+ removeSessionResult.error.message,
3682
+ removeSessionResult.error
3683
+ );
3684
+ }
3652
3685
  return ok(void 0);
3653
3686
  },
3654
3687
  async removeByUserId(userId) {
3655
3688
  const tokensResult = await cache.set_.smembers(buildUserTokensKey(userId));
3689
+ if (!tokensResult.success) {
3690
+ return buildRepositoryError(
3691
+ "iam_queryUserSessionCacheFailed",
3692
+ tokensResult.error.message,
3693
+ tokensResult.error
3694
+ );
3695
+ }
3656
3696
  let removed = 0;
3657
- if (tokensResult.success && tokensResult.data.length > 0) {
3697
+ if (tokensResult.data.length > 0) {
3658
3698
  const results = await Promise.allSettled(
3659
3699
  tokensResult.data.map((token) => repo.removeByAccessToken(token))
3660
3700
  );
3661
3701
  for (const r of results) {
3662
- if (r.status === "fulfilled" && r.value.success)
3663
- removed += 1;
3702
+ if (r.status === "rejected") {
3703
+ return buildRepositoryError(
3704
+ "iam_deleteSessionFailed",
3705
+ String(r.reason),
3706
+ r.reason
3707
+ );
3708
+ }
3709
+ if (!r.value.success)
3710
+ return r.value;
3711
+ removed += 1;
3664
3712
  }
3665
3713
  }
3666
- await cache.kv.del(buildUserTokensKey(userId));
3714
+ const removeUserTokensKeyResult = await cache.kv.del(buildUserTokensKey(userId));
3715
+ if (!removeUserTokensKeyResult.success) {
3716
+ return buildRepositoryError(
3717
+ "iam_deleteUserSessionCacheFailed",
3718
+ removeUserTokensKeyResult.error.message,
3719
+ removeUserTokensKeyResult.error
3720
+ );
3721
+ }
3667
3722
  return ok(removed);
3668
3723
  },
3669
3724
  async getByRefreshToken(refreshToken) {
@@ -3714,8 +3769,13 @@ function createCacheSessionRepository(sessionMaxAge, refreshTokenMaxAge) {
3714
3769
  const staleTokens = [];
3715
3770
  const writeOps = [];
3716
3771
  for (const entry of readResults) {
3717
- if (entry.status === "rejected")
3718
- continue;
3772
+ if (entry.status === "rejected") {
3773
+ return buildRepositoryError(
3774
+ "iam_queryUserSessionCacheFailed",
3775
+ String(entry.reason),
3776
+ entry.reason
3777
+ );
3778
+ }
3719
3779
  const { token, sessionKey, sessionResult, ttlResult } = entry.value;
3720
3780
  if (!sessionResult.success || !sessionResult.data || !ttlResult.success || ttlResult.data <= 0) {
3721
3781
  staleTokens.push(token);
@@ -3725,16 +3785,31 @@ function createCacheSessionRepository(sessionMaxAge, refreshTokenMaxAge) {
3725
3785
  writeOps.push(cache.kv.set(sessionKey, updated, { ex: ttlResult.data }));
3726
3786
  }
3727
3787
  const writeResults = await Promise.allSettled(writeOps);
3728
- const failedWrite = writeResults.find((r) => r.status === "fulfilled" && !r.value.success);
3729
- if (failedWrite) {
3730
- const failedResult = failedWrite.value;
3731
- return err(
3732
- HaiIamError.REPOSITORY_ERROR,
3733
- iamM("iam_saveUserSessionCacheFailed", { params: { message: failedResult.error.message } })
3734
- );
3788
+ for (const writeResult of writeResults) {
3789
+ if (writeResult.status === "rejected") {
3790
+ return buildRepositoryError(
3791
+ "iam_saveUserSessionCacheFailed",
3792
+ String(writeResult.reason),
3793
+ writeResult.reason
3794
+ );
3795
+ }
3796
+ if (!writeResult.value.success) {
3797
+ return buildRepositoryError(
3798
+ "iam_saveUserSessionCacheFailed",
3799
+ writeResult.value.error.message,
3800
+ writeResult.value.error
3801
+ );
3802
+ }
3735
3803
  }
3736
3804
  if (staleTokens.length > 0) {
3737
- await cache.set_.srem(buildUserTokensKey(userId), ...staleTokens);
3805
+ const staleCleanupResult = await cache.set_.srem(buildUserTokensKey(userId), ...staleTokens);
3806
+ if (!staleCleanupResult.success) {
3807
+ return buildRepositoryError(
3808
+ "iam_deleteUserSessionCacheFailed",
3809
+ staleCleanupResult.error.message,
3810
+ staleCleanupResult.error
3811
+ );
3812
+ }
3738
3813
  }
3739
3814
  return ok(void 0);
3740
3815
  }
@@ -3825,15 +3900,21 @@ function buildSessionFunctions(config) {
3825
3900
  return ok(null);
3826
3901
  }
3827
3902
  if (/* @__PURE__ */ new Date() > session.expiresAt) {
3828
- await repo.removeByAccessToken(accessToken);
3903
+ const removeResult = await repo.removeByAccessToken(accessToken);
3904
+ if (!removeResult.success) {
3905
+ return removeResult;
3906
+ }
3829
3907
  return ok(null);
3830
3908
  }
3831
3909
  if (sliding) {
3832
3910
  const now = /* @__PURE__ */ new Date();
3833
- await repo.updateByAccessToken(accessToken, {
3911
+ const updateResult = await repo.updateByAccessToken(accessToken, {
3834
3912
  lastActiveAt: now,
3835
3913
  expiresAt: new Date(now.getTime() + maxAge * 1e3)
3836
3914
  });
3915
+ if (!updateResult.success) {
3916
+ return updateResult;
3917
+ }
3837
3918
  }
3838
3919
  return ok(stripInternalSessionFields(session));
3839
3920
  },
@@ -3877,7 +3958,10 @@ function buildSessionFunctions(config) {
3877
3958
  iamM("iam_refreshTokenExpired")
3878
3959
  );
3879
3960
  }
3880
- await repo.removeByAccessToken(oldSession.accessToken);
3961
+ const removeOldSessionResult = await repo.removeByAccessToken(oldSession.accessToken);
3962
+ if (!removeOldSessionResult.success) {
3963
+ return removeOldSessionResult;
3964
+ }
3881
3965
  const newSessionResult = await this.create({
3882
3966
  userId: oldSession.userId,
3883
3967
  username: oldSession.username,
@@ -3929,12 +4013,23 @@ function hashResetToken(token) {
3929
4013
  }
3930
4014
  var RESET_TOKEN_KEY_PREFIX = "hai:iam:reset:";
3931
4015
  var RESET_ATTEMPTS_KEY_PREFIX = "hai:iam:reset:attempts:";
4016
+ var RESET_USER_TOKEN_KEY_PREFIX = "hai:iam:reset:user:";
3932
4017
  function buildResetTokenKey(hashedToken) {
3933
4018
  return `${RESET_TOKEN_KEY_PREFIX}${hashedToken}`;
3934
4019
  }
3935
4020
  function buildAttemptsKey(userId) {
3936
4021
  return `${RESET_ATTEMPTS_KEY_PREFIX}${userId}`;
3937
4022
  }
4023
+ function buildUserTokenKey(userId) {
4024
+ return `${RESET_USER_TOKEN_KEY_PREFIX}${userId}`;
4025
+ }
4026
+ function buildResetTokenRepositoryError(messageKey, message, cause) {
4027
+ return err(
4028
+ HaiIamError.REPOSITORY_ERROR,
4029
+ iamM(messageKey, { params: { message } }),
4030
+ cause
4031
+ );
4032
+ }
3938
4033
  var resetTokenRepoInstance = null;
3939
4034
  function resetResetTokenRepoSingleton() {
3940
4035
  resetTokenRepoInstance = null;
@@ -3942,6 +4037,22 @@ function resetResetTokenRepoSingleton() {
3942
4037
  function createCacheResetTokenRepository() {
3943
4038
  if (resetTokenRepoInstance)
3944
4039
  return resetTokenRepoInstance;
4040
+ async function clearTokenState(hashedToken, userId) {
4041
+ const cleanupResults = await Promise.all([
4042
+ cache.kv.del(buildResetTokenKey(hashedToken)),
4043
+ cache.kv.del(buildAttemptsKey(userId)),
4044
+ cache.kv.del(buildUserTokenKey(userId))
4045
+ ]);
4046
+ const failedCleanup = cleanupResults.find((result) => !result.success);
4047
+ if (failedCleanup && !failedCleanup.success) {
4048
+ return buildResetTokenRepositoryError(
4049
+ "iam_saveResetTokenFailed",
4050
+ failedCleanup.error.message,
4051
+ failedCleanup.error
4052
+ );
4053
+ }
4054
+ return ok(void 0);
4055
+ }
3945
4056
  const repo = {
3946
4057
  async saveToken(token, userId, expiresAt) {
3947
4058
  const hashResult = hashResetToken(token);
@@ -3950,6 +4061,25 @@ function createCacheResetTokenRepository() {
3950
4061
  }
3951
4062
  const hashedToken = hashResult.data;
3952
4063
  const ttlSeconds = Math.max(1, Math.ceil((expiresAt.getTime() - Date.now()) / 1e3));
4064
+ const userTokenKey = buildUserTokenKey(userId);
4065
+ const existingTokenResult = await cache.kv.get(userTokenKey);
4066
+ if (!existingTokenResult.success) {
4067
+ return buildResetTokenRepositoryError(
4068
+ "iam_queryResetTokenFailed",
4069
+ existingTokenResult.error.message,
4070
+ existingTokenResult.error
4071
+ );
4072
+ }
4073
+ if (existingTokenResult.data && existingTokenResult.data !== hashedToken) {
4074
+ const removeExistingTokenResult = await cache.kv.del(buildResetTokenKey(existingTokenResult.data));
4075
+ if (!removeExistingTokenResult.success) {
4076
+ return buildResetTokenRepositoryError(
4077
+ "iam_saveResetTokenFailed",
4078
+ removeExistingTokenResult.error.message,
4079
+ removeExistingTokenResult.error
4080
+ );
4081
+ }
4082
+ }
3953
4083
  const setResult = await cache.kv.set(buildResetTokenKey(hashedToken), userId, { ex: ttlSeconds });
3954
4084
  if (!setResult.success) {
3955
4085
  return err(
@@ -3958,11 +4088,24 @@ function createCacheResetTokenRepository() {
3958
4088
  setResult.error
3959
4089
  );
3960
4090
  }
4091
+ const saveUserTokenResult = await cache.kv.set(userTokenKey, hashedToken, { ex: ttlSeconds });
4092
+ if (!saveUserTokenResult.success) {
4093
+ await cache.kv.del(buildResetTokenKey(hashedToken));
4094
+ return buildResetTokenRepositoryError(
4095
+ "iam_saveResetTokenFailed",
4096
+ saveUserTokenResult.error.message,
4097
+ saveUserTokenResult.error
4098
+ );
4099
+ }
3961
4100
  const attemptsResult = await cache.kv.set(buildAttemptsKey(userId), 0, { ex: ttlSeconds });
3962
4101
  if (!attemptsResult.success) {
3963
- return err(
3964
- HaiIamError.REPOSITORY_ERROR,
3965
- iamM("iam_saveResetTokenFailed", { params: { message: attemptsResult.error.message } }),
4102
+ await Promise.all([
4103
+ cache.kv.del(buildResetTokenKey(hashedToken)),
4104
+ cache.kv.del(userTokenKey)
4105
+ ]);
4106
+ return buildResetTokenRepositoryError(
4107
+ "iam_saveResetTokenFailed",
4108
+ attemptsResult.error.message,
3966
4109
  attemptsResult.error
3967
4110
  );
3968
4111
  }
@@ -3992,10 +4135,19 @@ function createCacheResetTokenRepository() {
3992
4135
  const userId = result.data;
3993
4136
  const attemptsKey = buildAttemptsKey(userId);
3994
4137
  const incrResult = await cache.kv.incr(attemptsKey);
3995
- const nextAttempts = incrResult.success ? incrResult.data : 1;
4138
+ if (!incrResult.success) {
4139
+ return buildResetTokenRepositoryError(
4140
+ "iam_saveResetTokenFailed",
4141
+ incrResult.error.message,
4142
+ incrResult.error
4143
+ );
4144
+ }
4145
+ const nextAttempts = incrResult.data;
3996
4146
  if (nextAttempts > maxAttempts) {
3997
- await cache.kv.del(tokenKey);
3998
- await cache.kv.del(attemptsKey);
4147
+ const clearResult = await clearTokenState(hashedToken, userId);
4148
+ if (!clearResult.success) {
4149
+ return clearResult;
4150
+ }
3999
4151
  return err(
4000
4152
  HaiIamError.RESET_TOKEN_MAX_ATTEMPTS,
4001
4153
  iamM("iam_resetTokenMaxAttempts")
@@ -4011,11 +4163,17 @@ function createCacheResetTokenRepository() {
4011
4163
  const hashedToken = hashResult.data;
4012
4164
  const tokenKey = buildResetTokenKey(hashedToken);
4013
4165
  const result = await cache.kv.get(tokenKey);
4014
- if (result.success && result.data) {
4015
- await cache.kv.del(buildAttemptsKey(result.data));
4166
+ if (!result.success) {
4167
+ return buildResetTokenRepositoryError(
4168
+ "iam_queryResetTokenFailed",
4169
+ result.error.message,
4170
+ result.error
4171
+ );
4016
4172
  }
4017
- await cache.kv.del(tokenKey);
4018
- return ok(void 0);
4173
+ if (!result.data) {
4174
+ return ok(void 0);
4175
+ }
4176
+ return clearTokenState(hashedToken, result.data);
4019
4177
  }
4020
4178
  };
4021
4179
  resetTokenRepoInstance = repo;
@@ -4136,18 +4294,6 @@ function buildRegistrationOps(ctx) {
4136
4294
  }
4137
4295
  return ok(void 0);
4138
4296
  }
4139
- function buildAgreementDisplay() {
4140
- if (!agreementConfig.showOnRegister)
4141
- return void 0;
4142
- if (!agreementConfig.userAgreementUrl && !agreementConfig.privacyPolicyUrl)
4143
- return void 0;
4144
- return {
4145
- userAgreementUrl: agreementConfig.userAgreementUrl,
4146
- privacyPolicyUrl: agreementConfig.privacyPolicyUrl,
4147
- showOnRegister: agreementConfig.showOnRegister,
4148
- showOnLogin: agreementConfig.showOnLogin
4149
- };
4150
- }
4151
4297
  async function assignDefaultRole(userId) {
4152
4298
  if (!config.rbac?.defaultRole)
4153
4299
  return;
@@ -4202,7 +4348,7 @@ function buildRegistrationOps(ctx) {
4202
4348
  logger9.info("User registered", { userId: createdUser.id, username: options.username });
4203
4349
  return ok({
4204
4350
  user: toUser(createdUser),
4205
- agreements: buildAgreementDisplay()
4351
+ agreements: buildAgreementDisplay(agreementConfig, agreementConfig.showOnRegister)
4206
4352
  });
4207
4353
  },
4208
4354
  validatePassword(password) {
@@ -4789,7 +4935,7 @@ var iam = {
4789
4935
  return currentApiKey ?? notInitializedApiKey;
4790
4936
  },
4791
4937
  get config() {
4792
- return currentConfig;
4938
+ return currentConfig ? core.sanitize.sanitizeSensitiveFields(currentConfig) : null;
4793
4939
  },
4794
4940
  get isInitialized() {
4795
4941
  return currentConfig !== null;