@tachybase/module-auth 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,79 +17,57 @@ var __copyProps = (to, from, except, desc) => {
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
  var user_status_exports = {};
19
19
  __export(user_status_exports, {
20
- UserStatusService: () => UserStatusService,
21
- default: () => user_status_default
20
+ UserStatusService: () => UserStatusService
22
21
  });
23
22
  module.exports = __toCommonJS(user_status_exports);
24
- var import_server = require("@tego/server");
25
23
  var import_preset = require("../preset");
24
+ const localeNamespace = import_preset.namespace;
26
25
  class UserStatusService {
27
- constructor(app) {
26
+ constructor({ cache, app, logger }) {
27
+ this.cache = cache;
28
28
  this.app = app;
29
- this.db = app.db;
30
- this.cache = app.cache;
31
- this.logger = app.logger;
29
+ this.logger = logger;
30
+ this.userCollection = app.db.getCollection("users");
31
+ this.userStatusCollection = app.db.getCollection("userStatuses");
32
+ this.userStatusHistoryCollection = app.db.getCollection("userStatusHistories");
33
+ this.registerStatusChangeInterceptor();
32
34
  }
33
- /**
34
- * 获取用户状态缓存键
35
- */
36
- getUserStatusCacheKey(userId) {
37
- return `userStatus:${userId}`;
35
+ get userRepository() {
36
+ return this.userCollection.repository;
38
37
  }
39
- /**
40
- * 从缓存获取用户状态
41
- */
42
- async getUserStatusFromCache(userId) {
43
- try {
44
- const cacheKey = this.getUserStatusCacheKey(userId);
45
- const cached = await this.cache.get(cacheKey);
46
- return cached ? JSON.parse(cached) : null;
47
- } catch (error) {
48
- this.logger.error("Error getting user status from cache:", error);
49
- return null;
50
- }
38
+ get userStatusRepository() {
39
+ return this.userStatusCollection.repository;
51
40
  }
52
- /**
53
- * 设置用户状态缓存
54
- */
55
- async setUserStatusCache(userId, data) {
56
- try {
57
- const cacheKey = this.getUserStatusCacheKey(userId);
58
- await this.cache.set(cacheKey, JSON.stringify(data), 300 * 1e3);
59
- } catch (error) {
60
- this.logger.error("Error setting user status cache:", error);
61
- }
41
+ get userStatusHistoryRepository() {
42
+ return this.userStatusHistoryCollection.repository;
62
43
  }
63
44
  /**
64
- * 清除用户状态缓存
45
+ * 翻译消息
65
46
  */
66
- async clearUserStatusCache(userId) {
67
- try {
68
- const cacheKey = this.getUserStatusCacheKey(userId);
69
- await this.cache.del(cacheKey);
70
- } catch (error) {
71
- this.logger.error("Error clearing user status cache:", error);
72
- }
47
+ t(key, options) {
48
+ var _a, _b;
49
+ const language = (options == null ? void 0 : options.lng) || ((_a = this.app.i18n) == null ? void 0 : _a.language) || "en-US";
50
+ return ((_b = this.app.i18n) == null ? void 0 : _b.t(key, { ...options, lng: language })) || key;
73
51
  }
74
- /**
75
- * 检查用户状态是否允许登录
76
- * @param userId 用户ID
77
- * @returns 检查结果
78
- */
79
52
  async checkUserStatus(userId) {
80
53
  try {
81
54
  let cached = await this.getUserStatusFromCache(userId);
82
55
  if (!cached) {
83
- const userRepo = this.db.getRepository("users");
84
- const user = await userRepo.findOne({
85
- filterByTk: userId,
56
+ const user = await this.userRepository.findOne({
57
+ filter: { id: userId },
86
58
  fields: ["id", "status", "statusExpireAt", "previousStatus"]
87
59
  });
88
60
  if (!user) {
89
61
  return {
90
62
  allowed: false,
91
63
  status: "unknown",
92
- errorMessage: this.app.i18n.t("User not found")
64
+ statusInfo: {
65
+ title: this.t("User not found. Please sign in again to continue.", { ns: localeNamespace }),
66
+ color: "red",
67
+ allowLogin: false
68
+ },
69
+ errorMessage: this.t("User not found. Please sign in again to continue.", { ns: localeNamespace }),
70
+ isExpired: false
93
71
  };
94
72
  }
95
73
  cached = {
@@ -103,9 +81,8 @@ class UserStatusService {
103
81
  }
104
82
  if (cached.expireAt && new Date(cached.expireAt) <= /* @__PURE__ */ new Date()) {
105
83
  await this.restoreUserStatus(userId);
106
- const userRepo = this.db.getRepository("users");
107
- const user = await userRepo.findOne({
108
- filterByTk: userId,
84
+ const user = await this.userRepository.findOne({
85
+ filter: { id: userId },
109
86
  fields: ["status"]
110
87
  });
111
88
  cached.status = user.status || "active";
@@ -113,9 +90,8 @@ class UserStatusService {
113
90
  cached.previousStatus = null;
114
91
  await this.setUserStatusCache(userId, cached);
115
92
  }
116
- const statusRepo = this.db.getRepository("userStatuses");
117
- const statusInfo = await statusRepo.findOne({
118
- filterByTk: cached.status
93
+ const statusInfo = await this.userStatusRepository.findOne({
94
+ filter: { key: cached.status }
119
95
  });
120
96
  if (!statusInfo) {
121
97
  this.logger.warn(`Status definition not found: ${cached.status}`);
@@ -123,36 +99,34 @@ class UserStatusService {
123
99
  allowed: false,
124
100
  status: cached.status,
125
101
  statusInfo: {
126
- title: this.app.i18n.t("Invalid status", { ns: import_preset.namespace }),
102
+ title: this.t("Invalid status", { ns: localeNamespace }),
127
103
  color: "red",
128
- allowLogin: false,
129
- loginErrorMessage: this.app.i18n.t("User status is invalid, please contact administrator", {
130
- ns: import_preset.namespace
131
- })
104
+ allowLogin: false
132
105
  },
133
- errorMessage: this.app.i18n.t("User status is invalid, please contact administrator", { ns: import_preset.namespace })
106
+ errorMessage: this.t("User status is invalid, please contact administrator", { ns: localeNamespace }),
107
+ isExpired: true
134
108
  };
135
109
  }
136
110
  const translateMessage = (message) => {
137
111
  if (!message) return "";
138
112
  const match = message.match(/\{\{t\("([^"]+)"\)\}\}/);
139
113
  if (match && match[1]) {
140
- return this.app.i18n.t(match[1], { ns: import_preset.namespace });
114
+ return this.t(match[1], { ns: localeNamespace });
141
115
  }
142
116
  return message;
143
117
  };
144
118
  const translatedTitle = translateMessage(statusInfo.title);
145
- const translatedLoginErrorMessage = translateMessage(statusInfo.loginErrorMessage);
119
+ const translatedLoginErrorMessage = translateMessage(statusInfo.loginErrorMessage) || this.t("User status does not allow login", { ns: localeNamespace });
146
120
  return {
147
121
  allowed: statusInfo.allowLogin,
148
122
  status: cached.status,
149
123
  statusInfo: {
150
124
  title: translatedTitle,
151
125
  color: statusInfo.color,
152
- allowLogin: statusInfo.allowLogin,
153
- loginErrorMessage: translatedLoginErrorMessage
126
+ allowLogin: statusInfo.allowLogin
154
127
  },
155
- errorMessage: !statusInfo.allowLogin ? translatedLoginErrorMessage || this.app.i18n.t("User status does not allow login", { ns: import_preset.namespace }) : void 0
128
+ errorMessage: statusInfo.allowLogin ? null : translatedLoginErrorMessage || null,
129
+ isExpired: false
156
130
  };
157
131
  } catch (error) {
158
132
  this.logger.error(`Error checking user status for userId=${userId}: ${error}`);
@@ -160,106 +134,73 @@ class UserStatusService {
160
134
  allowed: false,
161
135
  status: "unknown",
162
136
  statusInfo: {
163
- title: this.app.i18n.t("Unknown status", { ns: import_preset.namespace }),
137
+ title: this.t("Unknown status", { ns: localeNamespace }),
164
138
  color: "red",
165
- allowLogin: false,
166
- loginErrorMessage: this.app.i18n.t("System error, please contact administrator", { ns: import_preset.namespace })
139
+ allowLogin: false
167
140
  },
168
- errorMessage: this.app.i18n.t("System error, please contact administrator", { ns: import_preset.namespace })
141
+ errorMessage: this.t("System error, please contact administrator", { ns: localeNamespace }),
142
+ isExpired: false
169
143
  };
170
144
  }
171
145
  }
172
- /**
173
- * 记录状态变更历史(如果不存在相同记录)
174
- * @param params 状态变更参数
175
- */
176
- async recordStatusHistoryIfNotExists(params) {
177
- const { userId, fromStatus, toStatus, reason, expireAt, operationType, createdBy, transaction } = params;
146
+ async setUserStatusCache(userId, data) {
178
147
  try {
179
- const historyRepo = this.db.getRepository("userStatusHistories");
180
- const fiveSecondsAgo = new Date(Date.now() - 5e3);
181
- const existing = await historyRepo.findOne({
182
- filter: {
183
- userId,
184
- fromStatus,
185
- toStatus,
186
- createdAt: {
187
- $gte: fiveSecondsAgo
188
- }
189
- },
190
- sort: ["-createdAt"],
191
- transaction
192
- });
193
- if (existing) {
194
- this.logger.warn(
195
- `Skipping duplicate history record: userId=${userId}, ${fromStatus} \u2192 ${toStatus}, operationType=${operationType}`
196
- );
197
- return;
198
- }
199
- await historyRepo.create({
200
- values: {
201
- userId,
202
- fromStatus,
203
- toStatus,
204
- reason,
205
- expireAt,
206
- operationType,
207
- createdBy
208
- },
209
- transaction
210
- });
211
- this.logger.debug(
212
- `History recorded: userId=${userId}, ${fromStatus} \u2192 ${toStatus}, operationType=${operationType}`
213
- );
214
- await this.clearUserStatusCache(userId);
215
- this.logger.debug(`Cache cleared for userId=${userId}`);
148
+ const cacheKey = this.getUserStatusCacheKey(userId);
149
+ await this.cache.set(cacheKey, JSON.stringify(data), 300 * 1e3);
216
150
  } catch (error) {
217
- this.logger.error("Failed to record status history:", error);
218
- throw error;
151
+ this.logger.error("Error setting user status cache:", error);
219
152
  }
220
153
  }
221
- /**
222
- * 恢复过期的用户状态
223
- * @param userId 用户ID
224
- */
154
+ async getUserStatusFromCache(userId) {
155
+ try {
156
+ const cacheKey = this.getUserStatusCacheKey(userId);
157
+ const cached = await this.cache.get(cacheKey);
158
+ return cached ? JSON.parse(cached) : null;
159
+ } catch (error) {
160
+ this.logger.error("Error getting user status from cache:", error);
161
+ return null;
162
+ }
163
+ }
164
+ getUserStatusCacheKey(userId) {
165
+ return `userStatus:${userId}`;
166
+ }
225
167
  async restoreUserStatus(userId) {
226
168
  try {
227
- const userRepo = this.db.getRepository("users");
228
- const user = await userRepo.findOne({
229
- filterByTk: userId,
169
+ const user = await this.userRepository.findOne({
170
+ filter: { id: userId },
230
171
  fields: ["id", "status", "statusExpireAt", "previousStatus"]
231
172
  });
232
173
  if (!user) {
233
- throw new Error(this.app.i18n.t("User not found"));
174
+ throw new Error(this.t("User not found. Please sign in again to continue.", { ns: localeNamespace }));
234
175
  }
235
176
  if (!user.statusExpireAt || new Date(user.statusExpireAt) > /* @__PURE__ */ new Date()) {
236
177
  return;
237
178
  }
238
179
  const oldStatus = user.status;
239
180
  const restoreToStatus = user.previousStatus || "active";
240
- await this.db.sequelize.transaction(async (transaction) => {
181
+ await this.app.db.sequelize.transaction(async (transaction) => {
241
182
  await this.recordStatusHistoryIfNotExists({
242
183
  userId,
243
184
  fromStatus: oldStatus,
244
185
  toStatus: restoreToStatus,
245
- reason: this.app.i18n.t("Status expired, auto restored"),
186
+ reason: this.t("Status expired, auto restored", { ns: localeNamespace }),
246
187
  operationType: "auto",
247
188
  createdBy: null,
248
189
  expireAt: null,
249
190
  transaction
250
191
  });
251
- await userRepo.update({
252
- filterByTk: userId,
192
+ await this.userRepository.update({
193
+ filter: { id: userId },
253
194
  values: {
254
195
  status: restoreToStatus,
255
196
  statusExpireAt: null,
256
197
  previousStatus: null,
257
- statusReason: this.app.i18n.t("Status expired, auto restored")
198
+ statusReason: this.t("Status expired, auto restored", { ns: localeNamespace })
258
199
  },
259
200
  transaction
260
201
  });
261
202
  });
262
- this.app.emitAsync("user:statusRestored", {
203
+ await this.app.emitAsync("user:statusRestored", {
263
204
  userId,
264
205
  fromStatus: oldStatus,
265
206
  toStatus: restoreToStatus
@@ -270,321 +211,57 @@ class UserStatusService {
270
211
  throw error;
271
212
  }
272
213
  }
273
- /**
274
- * 注册新的用户状态(供插件使用)
275
- * @param config 状态配置
276
- */
277
- async registerStatus(config) {
214
+ async clearUserStatusCache(userId) {
278
215
  try {
279
- const statusRepo = this.db.getRepository("userStatuses");
280
- const existing = await statusRepo.findOne({
281
- filterByTk: config.key
282
- });
283
- if (existing) {
284
- if (existing.packageName === config.packageName) {
285
- await statusRepo.update({
286
- filterByTk: config.key,
287
- values: {
288
- title: config.title,
289
- color: config.color || "default",
290
- allowLogin: config.allowLogin,
291
- loginErrorMessage: config.loginErrorMessage || null,
292
- description: config.description || null,
293
- sort: config.sort || 0,
294
- config: config.config || {}
295
- }
296
- });
297
- this.logger.info(`Updated status: ${config.key} by ${config.packageName}`);
298
- } else {
299
- this.logger.warn(`Status ${config.key} already registered by ${existing.packageName}, skipping`);
300
- }
301
- return;
302
- }
303
- await statusRepo.create({
304
- values: {
305
- key: config.key,
306
- title: config.title,
307
- color: config.color || "default",
308
- allowLogin: config.allowLogin,
309
- loginErrorMessage: config.loginErrorMessage || null,
310
- isSystemDefined: false,
311
- // 插件注册的状态不是系统内置
312
- packageName: config.packageName,
313
- description: config.description || null,
314
- sort: config.sort || 0,
315
- config: config.config || {}
316
- }
317
- });
318
- this.logger.info(`Registered new status: ${config.key} by ${config.packageName}`);
216
+ const cacheKey = this.getUserStatusCacheKey(userId);
217
+ await this.cache.del(cacheKey);
319
218
  } catch (error) {
320
- this.logger.error("Error registering status:", error);
321
- throw error;
219
+ this.logger.error("Error clearing user status cache:", error);
322
220
  }
323
221
  }
324
- /**
325
- * 获取每个状态的用户数量统计
326
- */
327
- async getStatusStatistics() {
222
+ async recordStatusHistoryIfNotExists(params) {
223
+ const { userId, fromStatus, toStatus, reason, expireAt, operationType, createdBy, transaction } = params;
328
224
  try {
329
- const userRepo = this.db.getRepository("users");
330
- const result = await userRepo.find({
331
- attributes: ["status", [this.db.sequelize.fn("COUNT", "id"), "count"]],
332
- group: ["status"],
333
- raw: true
225
+ const fiveSecondsAgo = new Date(Date.now() - 5e3);
226
+ const existing = await this.userStatusHistoryRepository.findOne({
227
+ filter: {
228
+ userId,
229
+ fromStatus,
230
+ toStatus,
231
+ createdAt: {
232
+ $gte: fiveSecondsAgo
233
+ }
234
+ },
235
+ sort: ["-createdAt"],
236
+ transaction
334
237
  });
335
- const statistics = {};
336
- for (const row of result) {
337
- statistics[row.status] = parseInt(row.count, 10);
238
+ if (existing) {
239
+ this.logger.warn(
240
+ `Skipping duplicate history record: userId=${userId}, ${fromStatus} \u2192 ${toStatus}, operationType=${operationType}`
241
+ );
242
+ return;
338
243
  }
339
- return statistics;
340
- } catch (error) {
341
- this.logger.error("Error getting status statistics:", error);
342
- return {};
343
- }
344
- }
345
- /**
346
- * 注入登录检查
347
- */
348
- injectLoginCheck() {
349
- const userStatusService = this;
350
- import_server.BaseAuth.prototype.signNewToken = async function(userId, options) {
351
- const user = await this.userRepository.findOne({
352
- filter: { id: userId },
353
- fields: ["id", "status"]
354
- });
355
- const userStatus = (user == null ? void 0 : user.status) || "active";
356
- const tokenInfo = await this.tokenController.add({ userId });
357
- const expiresIn = Math.floor((await this.tokenController.getConfig()).tokenExpirationTime / 1e3);
358
- const token = this.jwt.sign(
359
- {
244
+ await this.userStatusHistoryRepository.create({
245
+ values: {
360
246
  userId,
361
- userStatus,
362
- // 将用户状态写入 JWT payload
363
- temp: true,
364
- iat: Math.floor(tokenInfo.issuedTime / 1e3),
365
- signInTime: tokenInfo.signInTime
247
+ fromStatus,
248
+ toStatus,
249
+ reason,
250
+ expireAt,
251
+ operationType,
252
+ createdBy
366
253
  },
367
- {
368
- jwtid: tokenInfo.jti,
369
- expiresIn
370
- }
254
+ transaction
255
+ });
256
+ this.logger.debug(
257
+ `History recorded: userId=${userId}, ${fromStatus} \u2192 ${toStatus}, operationType=${operationType}`
371
258
  );
372
- userStatusService.logger.debug(`[signNewToken] userId=${userId}, userStatus=${userStatus}, jti=${tokenInfo.jti}`);
373
- return token;
374
- };
375
- import_server.BaseAuth.prototype.signIn = async function() {
376
- let user;
377
- try {
378
- user = await this.validate();
379
- } catch (err) {
380
- this.ctx.throw(err.status || 401, err.message, {
381
- ...err
382
- });
383
- }
384
- if (!user) {
385
- this.ctx.throw(401, {
386
- message: this.ctx.t("User not found. Please sign in again to continue.", { ns: import_preset.namespace }),
387
- code: import_server.AuthErrorCode.NOT_EXIST_USER
388
- });
389
- }
390
- const statusCheckResult = await userStatusService.checkUserStatus(user.id);
391
- if (!statusCheckResult.allowed) {
392
- this.ctx.throw(403, {
393
- message: this.ctx.t(statusCheckResult.statusInfo.loginErrorMessage, { ns: import_preset.namespace }),
394
- code: import_server.AuthErrorCode.INVALID_TOKEN
395
- });
396
- }
397
- const token = await this.signNewToken(user.id);
398
- return {
399
- user,
400
- token
401
- };
402
- };
403
- const originalCheck = import_server.BaseAuth.prototype.check;
404
- import_server.BaseAuth.prototype.check = async function() {
405
- const user = await originalCheck.call(this);
406
- if (!user) {
407
- return null;
408
- }
409
- const token = this.ctx.getBearerToken();
410
- if (!token) {
411
- return user;
412
- }
413
- try {
414
- const decoded = await this.jwt.decode(token);
415
- const tokenUserStatus = decoded.userStatus || "active";
416
- const currentUserStatus = user.status || "active";
417
- if (tokenUserStatus !== currentUserStatus) {
418
- userStatusService.logger.warn(
419
- `[check] Status mismatch, userId=${user.id}, token=${tokenUserStatus}, current=${currentUserStatus}`
420
- );
421
- this.ctx.throw(401, {
422
- message: this.ctx.t("Your account status has changed. Please sign in again.", { ns: import_preset.namespace }),
423
- code: import_server.AuthErrorCode.INVALID_TOKEN
424
- });
425
- }
426
- const statusCheckResult = await this.checkUserStatusInContext(user.id);
427
- if (!statusCheckResult.allowed) {
428
- userStatusService.logger.warn(`[check] Status not allowed, userId=${user.id}, status=${currentUserStatus}`);
429
- this.ctx.throw(403, {
430
- message: this.ctx.t(statusCheckResult.statusInfo.loginErrorMessage, { ns: import_preset.namespace }),
431
- code: import_server.AuthErrorCode.INVALID_TOKEN
432
- });
433
- }
434
- userStatusService.logger.debug(`[check] Passed, userId=${user.id}, status=${currentUserStatus}`);
435
- } catch (err) {
436
- if (err.status) {
437
- throw err;
438
- }
439
- userStatusService.logger.error("[check] Token validation error:", err);
440
- throw err;
441
- }
442
- return user;
443
- };
444
- import_server.BaseAuth.prototype.checkUserStatusInContext = async function(userId) {
445
- try {
446
- if (!userStatusService) {
447
- throw new Error("userStatusService is undefined");
448
- }
449
- if (!userStatusService.app) {
450
- throw new Error("userStatusService.app is undefined");
451
- }
452
- if (!userStatusService.app.db) {
453
- throw new Error("userStatusService.app.db is undefined");
454
- }
455
- if (!userStatusService.app.cache) {
456
- throw new Error("userStatusService.app.cache is undefined");
457
- }
458
- const contextDb = userStatusService.app.db;
459
- const contextCache = userStatusService.app.cache;
460
- let cached = null;
461
- try {
462
- const cacheKey = `userStatus:${userId}`;
463
- const cachedData = await contextCache.get(cacheKey);
464
- cached = cachedData ? JSON.parse(cachedData) : null;
465
- } catch (error) {
466
- userStatusService.logger.error("Error getting user status from cache:", error);
467
- cached = null;
468
- }
469
- if (!cached) {
470
- const userRepo = contextDb.getRepository("users");
471
- const user = await userRepo.findOne({
472
- filterByTk: userId,
473
- fields: ["id", "status", "statusExpireAt", "previousStatus"]
474
- });
475
- if (!user) {
476
- return {
477
- allowed: false,
478
- status: "unknown",
479
- errorMessage: userStatusService.app.i18n.t("User not found")
480
- };
481
- }
482
- cached = {
483
- userId: user.id,
484
- status: user.status || "active",
485
- expireAt: user.statusExpireAt,
486
- previousStatus: user.previousStatus,
487
- lastChecked: /* @__PURE__ */ new Date()
488
- };
489
- try {
490
- const cacheKey = `userStatus:${userId}`;
491
- await contextCache.set(cacheKey, JSON.stringify(cached), 300 * 1e3);
492
- } catch (error) {
493
- userStatusService.logger.error("Error setting user status cache:", error);
494
- }
495
- }
496
- if (cached.expireAt && new Date(cached.expireAt) <= /* @__PURE__ */ new Date()) {
497
- const userRepo = contextDb.getRepository("users");
498
- const user = await userRepo.findOne({
499
- filterByTk: userId,
500
- fields: ["id", "status", "statusExpireAt", "previousStatus"]
501
- });
502
- if (!user) {
503
- return {
504
- allowed: false,
505
- status: "unknown",
506
- errorMessage: userStatusService.app.i18n.t("User not found")
507
- };
508
- }
509
- if (!user.statusExpireAt || new Date(user.statusExpireAt) > /* @__PURE__ */ new Date()) {
510
- return userStatusService.checkUserStatus(userId);
511
- }
512
- await userStatusService.restoreUserStatus(userId);
513
- const restoredUser = await userRepo.findOne({
514
- filterByTk: userId,
515
- fields: ["status"]
516
- });
517
- cached.status = restoredUser.status || "active";
518
- cached.expireAt = null;
519
- cached.previousStatus = null;
520
- try {
521
- const cacheKey = `userStatus:${userId}`;
522
- await contextCache.set(cacheKey, JSON.stringify(cached), 300 * 1e3);
523
- } catch (error) {
524
- userStatusService.logger.error("Error setting user status cache:", error);
525
- }
526
- }
527
- const statusRepo = contextDb.getRepository("userStatuses");
528
- const statusInfo = await statusRepo.findOne({
529
- filterByTk: cached.status
530
- });
531
- if (!statusInfo) {
532
- userStatusService.logger.warn(`Status definition not found: ${cached.status}`);
533
- return {
534
- allowed: false,
535
- status: cached.status,
536
- statusInfo: {
537
- title: userStatusService.app.i18n.t("Invalid status", { ns: import_preset.namespace }),
538
- color: "red",
539
- allowLogin: false,
540
- loginErrorMessage: userStatusService.app.i18n.t("User status is invalid, please contact administrator", {
541
- ns: import_preset.namespace
542
- })
543
- },
544
- errorMessage: userStatusService.app.i18n.t("User status is invalid, please contact administrator", {
545
- ns: import_preset.namespace
546
- })
547
- };
548
- }
549
- const translateMessage = (message) => {
550
- if (!message) return "";
551
- const match = message.match(/\{\{t\("([^"]+)"\)\}\}/);
552
- if (match && match[1]) {
553
- return userStatusService.app.i18n.t(match[1], { ns: import_preset.namespace });
554
- }
555
- return message;
556
- };
557
- const translatedTitle = translateMessage(statusInfo.title);
558
- const translatedLoginErrorMessage = translateMessage(statusInfo.loginErrorMessage);
559
- return {
560
- allowed: statusInfo.allowLogin,
561
- status: cached.status,
562
- statusInfo: {
563
- title: translatedTitle,
564
- color: statusInfo.color,
565
- allowLogin: statusInfo.allowLogin,
566
- loginErrorMessage: translatedLoginErrorMessage
567
- },
568
- errorMessage: !statusInfo.allowLogin ? translatedLoginErrorMessage || userStatusService.app.i18n.t("User status does not allow login", { ns: import_preset.namespace }) : void 0
569
- };
570
- } catch (error) {
571
- userStatusService.logger.error(`Error checking user status for userId=${userId}: ${error}`);
572
- return {
573
- allowed: false,
574
- status: "unknown",
575
- statusInfo: {
576
- title: userStatusService.app.i18n.t("Unknown status", { ns: import_preset.namespace }),
577
- color: "red",
578
- allowLogin: false,
579
- loginErrorMessage: userStatusService.app.i18n.t("System error, please contact administrator", {
580
- ns: import_preset.namespace
581
- })
582
- },
583
- errorMessage: userStatusService.app.i18n.t("System error, please contact administrator", { ns: import_preset.namespace })
584
- };
585
- }
586
- };
587
- this.logger.info("signIn, signNewToken and check methods injected with UserStatusService integration");
259
+ await this.clearUserStatusCache(userId);
260
+ this.logger.debug(`Cache cleared for userId=${userId}`);
261
+ } catch (error) {
262
+ this.logger.error("Failed to record status history:", error);
263
+ throw error;
264
+ }
588
265
  }
589
266
  /**
590
267
  * 注册用户状态变更拦截器
@@ -592,7 +269,7 @@ class UserStatusService {
592
269
  */
593
270
  registerStatusChangeInterceptor() {
594
271
  const userStatusService = this;
595
- this.db.on("users.beforeUpdate", async (model, options) => {
272
+ this.app.db.on("users.beforeUpdate", async (model, options) => {
596
273
  if (model.changed("status")) {
597
274
  const oldStatus = model._previousDataValues.status || "active";
598
275
  const newStatus = model.status;
@@ -615,7 +292,7 @@ class UserStatusService {
615
292
  }
616
293
  }
617
294
  });
618
- this.db.on("users.afterUpdate", async (model, options) => {
295
+ this.app.db.on("users.afterUpdate", async (model, options) => {
619
296
  var _a, _b, _c, _d, _e;
620
297
  const statusChange = (_b = (_a = options == null ? void 0 : options.transaction) == null ? void 0 : _a.__statusChange) == null ? void 0 : _b[model.id];
621
298
  if (statusChange) {
@@ -640,7 +317,6 @@ class UserStatusService {
640
317
  this.logger.info("User status change interceptor registered");
641
318
  }
642
319
  }
643
- var user_status_default = UserStatusService;
644
320
  // Annotate the CommonJS export names for ESM import in node:
645
321
  0 && (module.exports = {
646
322
  UserStatusService