UNPKG

better-auth

Version:

The most comprehensive authentication framework for TypeScript.

1 lines 3.51 kB
{"version":3,"file":"rate-limit.mjs","names":[],"sources":["../../../src/plugins/api-key/rate-limit.ts"],"sourcesContent":["import { ERROR_CODES } from \".\";\nimport type { PredefinedApiKeyOptions } from \"./routes\";\nimport type { ApiKey } from \"./types\";\n\ninterface RateLimitResult {\n\tsuccess: boolean;\n\tmessage: string | null;\n\ttryAgainIn: number | null;\n\tupdate: Partial<ApiKey> | null;\n}\n\n/**\n * Determines if a request is allowed based on rate limiting parameters.\n *\n * @returns An object indicating whether the request is allowed and, if not,\n * a message and updated ApiKey data.\n */\nexport function isRateLimited(\n\t/**\n\t * The ApiKey object containing rate limiting information\n\t */\n\tapiKey: ApiKey,\n\topts: PredefinedApiKeyOptions,\n): RateLimitResult {\n\tconst now = new Date();\n\tconst lastRequest = apiKey.lastRequest;\n\tconst rateLimitTimeWindow = apiKey.rateLimitTimeWindow;\n\tconst rateLimitMax = apiKey.rateLimitMax;\n\tlet requestCount = apiKey.requestCount;\n\n\tif (opts.rateLimit.enabled === false)\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: null,\n\t\t\tupdate: { lastRequest: now },\n\t\t\ttryAgainIn: null,\n\t\t};\n\n\tif (apiKey.rateLimitEnabled === false)\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: null,\n\t\t\tupdate: { lastRequest: now },\n\t\t\ttryAgainIn: null,\n\t\t};\n\n\tif (rateLimitTimeWindow === null || rateLimitMax === null) {\n\t\t// Rate limiting is disabled.\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: null,\n\t\t\tupdate: null,\n\t\t\ttryAgainIn: null,\n\t\t};\n\t}\n\n\tif (lastRequest === null) {\n\t\t// No previous requests, so allow the first one.\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: null,\n\t\t\tupdate: { lastRequest: now, requestCount: 1 },\n\t\t\ttryAgainIn: null,\n\t\t};\n\t}\n\n\tconst timeSinceLastRequest = now.getTime() - new Date(lastRequest).getTime();\n\n\tif (timeSinceLastRequest > rateLimitTimeWindow) {\n\t\t// Time window has passed, reset the request count.\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tmessage: null,\n\t\t\tupdate: { lastRequest: now, requestCount: 1 },\n\t\t\ttryAgainIn: null,\n\t\t};\n\t}\n\n\tif (requestCount >= rateLimitMax) {\n\t\t// Rate limit exceeded.\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\tmessage: ERROR_CODES.RATE_LIMIT_EXCEEDED,\n\t\t\tupdate: null,\n\t\t\ttryAgainIn: Math.ceil(rateLimitTimeWindow - timeSinceLastRequest),\n\t\t};\n\t}\n\n\t// Request is allowed.\n\trequestCount++;\n\treturn {\n\t\tsuccess: true,\n\t\tmessage: null,\n\t\ttryAgainIn: null,\n\t\tupdate: { lastRequest: now, requestCount: requestCount },\n\t};\n}\n"],"mappings":";;;;;;;;;AAiBA,SAAgB,cAIf,QACA,MACkB;CAClB,MAAM,sBAAM,IAAI,MAAM;CACtB,MAAM,cAAc,OAAO;CAC3B,MAAM,sBAAsB,OAAO;CACnC,MAAM,eAAe,OAAO;CAC5B,IAAI,eAAe,OAAO;AAE1B,KAAI,KAAK,UAAU,YAAY,MAC9B,QAAO;EACN,SAAS;EACT,SAAS;EACT,QAAQ,EAAE,aAAa,KAAK;EAC5B,YAAY;EACZ;AAEF,KAAI,OAAO,qBAAqB,MAC/B,QAAO;EACN,SAAS;EACT,SAAS;EACT,QAAQ,EAAE,aAAa,KAAK;EAC5B,YAAY;EACZ;AAEF,KAAI,wBAAwB,QAAQ,iBAAiB,KAEpD,QAAO;EACN,SAAS;EACT,SAAS;EACT,QAAQ;EACR,YAAY;EACZ;AAGF,KAAI,gBAAgB,KAEnB,QAAO;EACN,SAAS;EACT,SAAS;EACT,QAAQ;GAAE,aAAa;GAAK,cAAc;GAAG;EAC7C,YAAY;EACZ;CAGF,MAAM,uBAAuB,IAAI,SAAS,GAAG,IAAI,KAAK,YAAY,CAAC,SAAS;AAE5E,KAAI,uBAAuB,oBAE1B,QAAO;EACN,SAAS;EACT,SAAS;EACT,QAAQ;GAAE,aAAa;GAAK,cAAc;GAAG;EAC7C,YAAY;EACZ;AAGF,KAAI,gBAAgB,aAEnB,QAAO;EACN,SAAS;EACT,SAAS,YAAY;EACrB,QAAQ;EACR,YAAY,KAAK,KAAK,sBAAsB,qBAAqB;EACjE;AAIF;AACA,QAAO;EACN,SAAS;EACT,SAAS;EACT,YAAY;EACZ,QAAQ;GAAE,aAAa;GAAmB;GAAc;EACxD"}