fix: incorrect initialization of remaining value within API key (#3648)

* Fixes #3640 - Resolves issue related to incorrect initialization of remaining value within API key.

* Adding test cases for fix of #3640.

* chore: update changeset

---------

Co-authored-by: Bereket Engida <86073083+Bekacru@users.noreply.github.com>
This commit is contained in:
Earl Oliver
2025-08-01 03:22:15 -04:00
committed by GitHub
parent 4d85d8709d
commit 4833a4b395
3 changed files with 73 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"better-auth": patch
---
fix(api key): key creation bug where remaining was incorrectly defaulting to a capped value instead of allowing null

View File

@@ -600,6 +600,72 @@ describe("api-key", async () => {
expect(apiKey.remaining).toEqual(remaining);
});
it("should create API Key with remaining explicitly set to null", async () => {
const apiKey = await auth.api.createApiKey({
body: {
remaining: null,
userId: user.id,
},
});
expect(apiKey).not.toBeNull();
expect(apiKey.remaining).toBeNull();
});
it("should create API Key with remaining explicitly set to null and refillAmount and refillInterval are also set", async () => {
const refillAmount = 10; // Arbitrary non-null value
const refillInterval = 1000;
const apiKey = await auth.api.createApiKey({
body: {
remaining: null,
refillAmount: refillAmount,
refillInterval: refillInterval,
userId: user.id,
},
});
expect(apiKey).not.toBeNull();
expect(apiKey.remaining).toBeNull();
expect(apiKey.refillAmount).toBe(refillAmount);
expect(apiKey.refillInterval).toBe(refillInterval);
});
it("should create API Key with remaining explicitly set to 0 and refillAmount also set", async () => {
const remaining = 0;
const refillAmount = 10; // Arbitrary non-null value
const refillInterval = 1000;
const apiKey = await auth.api.createApiKey({
body: {
remaining: remaining,
refillAmount: refillAmount,
refillInterval: refillInterval,
userId: user.id,
},
});
expect(apiKey).not.toBeNull();
expect(apiKey.remaining).toBe(remaining);
expect(apiKey.refillAmount).toBe(refillAmount);
expect(apiKey.refillInterval).toBe(refillInterval);
});
it("should create API Key with remaining undefined and default value of null is respected with refillAmount and refillInterval provided", async () => {
const refillAmount = 10; // Arbitrary non-null value
const refillInterval = 1000;
const apiKey = await auth.api.createApiKey({
body: {
refillAmount: refillAmount,
refillInterval: refillInterval,
userId: user.id,
},
});
expect(apiKey).not.toBeNull();
expect(apiKey.remaining).toBeNull();
expect(apiKey.refillAmount).toBe(refillAmount);
expect(apiKey.refillInterval).toBe(refillInterval);
});
it("should create API key with invalid metadata", async () => {
let result: { data: ApiKey | null; error: Err | null } = {
data: null,

View File

@@ -419,7 +419,8 @@ export function createApiKey({
rateLimitMax: rateLimitMax ?? opts.rateLimit.maxRequests ?? null,
rateLimitTimeWindow:
rateLimitTimeWindow ?? opts.rateLimit.timeWindow ?? null,
remaining: remaining || refillAmount || null,
remaining:
remaining === null ? remaining : remaining ?? refillAmount ?? null,
refillAmount: refillAmount ?? null,
refillInterval: refillInterval ?? null,
rateLimitEnabled: