(keyString: string)
| 481 | } |
| 482 | |
| 483 | export async function findActiveKeyByKeyString(keyString: string): Promise<Key | null> { |
| 484 | const vfSaysMissing = apiKeyVacuumFilter.isDefinitelyNotPresent(keyString) === true; |
| 485 | |
| 486 | // Redis 缓存命中:避免打 DB |
| 487 | const cached = await getCachedActiveKey(keyString); |
| 488 | if (cached) { |
| 489 | // 多实例一致性:若 Vacuum Filter 判定缺失但 Redis 命中,说明本机 filter 可能滞后。 |
| 490 | // 最佳努力将 key 写入本机 filter(不影响正确性,仅提升后续性能)。 |
| 491 | if (vfSaysMissing) { |
| 492 | apiKeyVacuumFilter.noteExistingKey(keyString); |
| 493 | } |
| 494 | return cached; |
| 495 | } |
| 496 | |
| 497 | // Vacuum Filter 负向短路:肯定不存在则直接返回 null,避免打 DB |
| 498 | // 注意:此处必须放在 Redis 读取之后,避免多实例环境中新建 key 的短暂误拒绝窗口。 |
| 499 | if (vfSaysMissing) { |
| 500 | return null; |
| 501 | } |
| 502 | |
| 503 | const [key] = await db |
| 504 | .select({ |
| 505 | id: keys.id, |
| 506 | userId: keys.userId, |
| 507 | key: keys.key, |
| 508 | name: keys.name, |
| 509 | isEnabled: keys.isEnabled, |
| 510 | expiresAt: keys.expiresAt, |
| 511 | canLoginWebUi: keys.canLoginWebUi, |
| 512 | limit5hUsd: keys.limit5hUsd, |
| 513 | limit5hResetMode: keys.limit5hResetMode, |
| 514 | limitDailyUsd: keys.limitDailyUsd, |
| 515 | dailyResetMode: keys.dailyResetMode, |
| 516 | dailyResetTime: keys.dailyResetTime, |
| 517 | limitWeeklyUsd: keys.limitWeeklyUsd, |
| 518 | limitMonthlyUsd: keys.limitMonthlyUsd, |
| 519 | limitTotalUsd: keys.limitTotalUsd, |
| 520 | costResetAt: keys.costResetAt, |
| 521 | limitConcurrentSessions: keys.limitConcurrentSessions, |
| 522 | providerGroup: keys.providerGroup, |
| 523 | cacheTtlPreference: keys.cacheTtlPreference, |
| 524 | createdAt: keys.createdAt, |
| 525 | updatedAt: keys.updatedAt, |
| 526 | deletedAt: keys.deletedAt, |
| 527 | }) |
| 528 | .from(keys) |
| 529 | .where( |
| 530 | and( |
| 531 | eq(keys.key, keyString), |
| 532 | isNull(keys.deletedAt), |
| 533 | eq(keys.isEnabled, true), |
| 534 | or(isNull(keys.expiresAt), gt(keys.expiresAt, new Date())) |
| 535 | ) |
| 536 | ); |
| 537 | |
| 538 | if (!key) return null; |
| 539 | const active = toKey(key); |
| 540 | cacheActiveKey(active).catch(() => {}); |
no test coverage detected