kroxt 1.2.1 → 1.3.0

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.
Files changed (91) hide show
  1. package/README.md +29 -96
  2. package/dist/adapters/drizzle.d.ts +2 -1
  3. package/dist/adapters/drizzle.d.ts.map +1 -1
  4. package/dist/adapters/index.d.ts +9 -0
  5. package/dist/adapters/index.d.ts.map +1 -1
  6. package/dist/adapters/memory.d.ts.map +1 -1
  7. package/dist/adapters/mongoose.d.ts +7 -1
  8. package/dist/adapters/mongoose.d.ts.map +1 -1
  9. package/dist/adapters/prisma.d.ts +2 -1
  10. package/dist/adapters/prisma.d.ts.map +1 -1
  11. package/dist/{adapters → auth/adapters}/drizzle.cjs +33 -2
  12. package/dist/auth/adapters/drizzle.cjs.map +7 -0
  13. package/dist/auth/adapters/drizzle.js +58 -0
  14. package/dist/auth/adapters/drizzle.js.map +7 -0
  15. package/dist/auth/adapters/index.cjs.map +7 -0
  16. package/dist/{adapters → auth/adapters}/memory.cjs +28 -0
  17. package/dist/auth/adapters/memory.cjs.map +7 -0
  18. package/dist/auth/adapters/memory.js +59 -0
  19. package/dist/auth/adapters/memory.js.map +7 -0
  20. package/dist/auth/adapters/mongoose.cjs +99 -0
  21. package/dist/auth/adapters/mongoose.cjs.map +7 -0
  22. package/dist/auth/adapters/mongoose.js +74 -0
  23. package/dist/auth/adapters/mongoose.js.map +7 -0
  24. package/dist/{adapters → auth/adapters}/prisma.cjs +36 -2
  25. package/dist/auth/adapters/prisma.cjs.map +7 -0
  26. package/dist/auth/adapters/prisma.js +68 -0
  27. package/dist/auth/adapters/prisma.js.map +7 -0
  28. package/dist/{core → auth/core}/index.cjs +67 -2
  29. package/dist/auth/core/index.cjs.map +7 -0
  30. package/dist/auth/core/index.js +143 -0
  31. package/dist/auth/core/index.js.map +7 -0
  32. package/dist/{index.cjs → auth/index.cjs} +12 -4
  33. package/dist/auth/index.cjs.map +7 -0
  34. package/dist/{index.js → auth/index.js} +6 -1
  35. package/dist/auth/index.js.map +7 -0
  36. package/dist/auth/providers/index.cjs.map +7 -0
  37. package/dist/auth/providers/index.js.map +7 -0
  38. package/dist/{security → auth/security}/index.cjs +10 -9
  39. package/dist/auth/security/index.cjs.map +7 -0
  40. package/dist/auth/security/index.js +19 -0
  41. package/dist/auth/security/index.js.map +7 -0
  42. package/dist/auth/security/rate-limit.cjs +82 -0
  43. package/dist/auth/security/rate-limit.cjs.map +7 -0
  44. package/dist/auth/security/rate-limit.js +57 -0
  45. package/dist/auth/security/rate-limit.js.map +7 -0
  46. package/dist/cli/index.cjs +134 -0
  47. package/dist/cli/index.cjs.map +7 -0
  48. package/dist/cli/index.js +111 -0
  49. package/dist/cli/index.js.map +7 -0
  50. package/dist/cli/templates.cjs +147 -0
  51. package/dist/cli/templates.cjs.map +7 -0
  52. package/dist/cli/templates.js +111 -0
  53. package/dist/cli/templates.js.map +7 -0
  54. package/dist/core/index.d.ts +16 -1
  55. package/dist/core/index.d.ts.map +1 -1
  56. package/dist/index.d.ts +3 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/security/index.d.ts +1 -0
  59. package/dist/security/index.d.ts.map +1 -1
  60. package/dist/security/rate-limit.d.ts +39 -0
  61. package/dist/security/rate-limit.d.ts.map +1 -0
  62. package/package.json +8 -2
  63. package/dist/adapters/drizzle.cjs.map +0 -7
  64. package/dist/adapters/drizzle.js +0 -27
  65. package/dist/adapters/drizzle.js.map +0 -7
  66. package/dist/adapters/index.cjs.map +0 -7
  67. package/dist/adapters/memory.cjs.map +0 -7
  68. package/dist/adapters/memory.js +0 -31
  69. package/dist/adapters/memory.js.map +0 -7
  70. package/dist/adapters/mongoose.cjs +0 -55
  71. package/dist/adapters/mongoose.cjs.map +0 -7
  72. package/dist/adapters/mongoose.js +0 -31
  73. package/dist/adapters/mongoose.js.map +0 -7
  74. package/dist/adapters/prisma.cjs.map +0 -7
  75. package/dist/adapters/prisma.js +0 -34
  76. package/dist/adapters/prisma.js.map +0 -7
  77. package/dist/core/index.cjs.map +0 -7
  78. package/dist/core/index.js +0 -78
  79. package/dist/core/index.js.map +0 -7
  80. package/dist/index.cjs.map +0 -7
  81. package/dist/index.js.map +0 -7
  82. package/dist/providers/index.cjs.map +0 -7
  83. package/dist/providers/index.js.map +0 -7
  84. package/dist/security/index.cjs.map +0 -7
  85. package/dist/security/index.js +0 -20
  86. package/dist/security/index.js.map +0 -7
  87. /package/dist/{adapters → auth/adapters}/index.cjs +0 -0
  88. /package/dist/{adapters → auth/adapters}/index.js +0 -0
  89. /package/dist/{adapters → auth/adapters}/index.js.map +0 -0
  90. /package/dist/{providers → auth/providers}/index.cjs +0 -0
  91. /package/dist/{providers → auth/providers}/index.js +0 -0
package/README.md CHANGED
@@ -1,22 +1,39 @@
1
- # kroxt 🔐
1
+ # Kroxt 🖤🤍
2
2
 
3
3
  A framework-agnostic, modular authentication engine for modern TypeScript applications. Built for security, extensibility, and pure developer joy.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/kroxt.svg)](https://www.npmjs.com/package/kroxt)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- [![Security Policy](https://img.shields.io/badge/Security-Policy-brightgreen.svg)](./SECURITY.md)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-black.svg)](https://opensource.org/licenses/MIT)
8
7
 
9
8
  > [!IMPORTANT]
10
- > **What's New in v1.2.0**: Universal SQL support (Drizzle/Prisma), multi-framework examples for Express/Fastify/Hono, and a revamped mobile-first documentation site. [Read the full Changelog](./CHANGELOG.md).
9
+ > **What's New in v1.3.0**: The **Kroxt CLI** is here! Bootstrap your entire auth engine in seconds with `npx kroxt init`. Also featuring a premium **Monochrome rebranding** and advanced **IP-Blocking** defense.
10
+
11
+ ---
12
+
13
+ ## ⚡ Quick Start (The Recommended Way)
14
+
15
+ The fastest way to get started with Kroxt is using our interactive initializer:
16
+
17
+ ```bash
18
+ npx kroxt init
19
+ ```
20
+
21
+ This will guide you through:
22
+ - 🏗️ Choosing your database adapter (**Mongoose**, **Prisma**, **Drizzle**, or **Memory**).
23
+ - 🛡️ Configuring security layers (**Rate Limiting**, **IP Blocking**, **Peppering**).
24
+ - 🔑 Generating secure **JWT_SECRET** and **JWT_PEPPER** in your `.env`.
25
+ - ⚙️ Setting up a modern **tsconfig.json**.
26
+
27
+ ---
11
28
 
12
29
  ## 🚀 Why Kroxt?
13
30
 
14
- Authentication is often either too complex (Passport, Auth.js) or too restrictive. Kroxt is the **"Headless" Auth Engine** that gives you the best of both worlds:
31
+ Authentication is often either too complex or too restrictive. Kroxt is the **"Headless" Auth Engine** that gives you the best of both worlds:
15
32
 
16
- - 🏗️ **Database Agnostic**: Native adapters for **Prisma**, **Drizzle**, and **Mongoose**.
17
- - 🛠️ **Modular**: Use only what you need. No forced session managers or UI components.
18
- - 🔐 **Security First**: Argon2 hashing, dual-token rotation, and timing-attack protection built-in.
19
- - 🧩 **TypeScript Native**: Perfectly preserves your user schemas and metadata.
33
+ - **🏗️ Database Agnostic**: Native adapters for **Prisma**, **Drizzle**, and **Mongoose**.
34
+ - **🛠️ Modular**: Use only what you need. No forced session managers or UI components.
35
+ - **🔐 Security First**: Argon2 hashing, dual-token rotation, and **IP-based brute force protection** built-in.
36
+ - **🧩 TypeScript Native**: Perfectly preserves your user schemas and metadata.
20
37
 
21
38
  ---
22
39
 
@@ -26,7 +43,7 @@ Kroxt sits between your database and your controller logic. It handles the "heav
26
43
 
27
44
  ```mermaid
28
45
  graph LR
29
- A[Client] -- "Credentials" --> B[Express/Fastify]
46
+ A[Client] -- "Credentials" --> B[Express/Fastify/Next.js]
30
47
  B -- "auth.signup()" --> C[Kroxt Engine]
31
48
  C -- "Save User" --> D[(Database Adapter)]
32
49
  D -- "Success" --> C
@@ -43,62 +60,6 @@ graph LR
43
60
 
44
61
  ---
45
62
 
46
- ## 🏁 Quick Start (5 Minutes)
47
-
48
- ### 1. Installation
49
-
50
- ```bash
51
- npm install kroxt
52
- ```
53
-
54
- ### 2. Choose Your Adapter
55
-
56
- Kroxt provides official adapters for the most popular ORMs.
57
-
58
- #### **Option A: Drizzle (SQLite/PG/MySQL)**
59
- ```typescript
60
- import { createDrizzleAdapter } from "kroxt/adapters/drizzle";
61
- import { db } from "./db";
62
- import { users } from "./schema";
63
- import { eq } from "drizzle-orm";
64
-
65
- export const adapter = createDrizzleAdapter(db, users, eq);
66
- ```
67
-
68
- #### **Option B: Prisma**
69
- ```typescript
70
- import { createPrismaAdapter } from "kroxt/adapters/prisma";
71
- import { prisma } from "./db";
72
-
73
- export const adapter = createPrismaAdapter(prisma.user);
74
- ```
75
-
76
- #### **Option C: Mongoose**
77
- ```typescript
78
- import { createMongoAdapter } from "kroxt/adapters/mongoose";
79
- import { User } from "./models/user.model";
80
-
81
- export const adapter = createMongoAdapter(User);
82
- ```
83
-
84
- ### 3. Initialize the Engine
85
-
86
- ```typescript
87
- import { createAuth } from "kroxt/core";
88
- import { adapter } from "./auth-adapter";
89
-
90
- export const auth = createAuth({
91
- adapter,
92
- secret: process.env.JWT_SECRET,
93
- session: {
94
- expires: "15m",
95
- refreshExpires: "7d"
96
- }
97
- });
98
- ```
99
-
100
- ---
101
-
102
63
  ## 🛡️ Core Authentication Flows
103
64
 
104
65
  ### **Registration**
@@ -122,15 +83,6 @@ const { accessToken } = await auth.refresh(refreshToken);
122
83
 
123
84
  ---
124
85
 
125
- ## 🐣 Beginner Corner: What is "Headless"?
126
-
127
- If you're new to backend development, "Headless" means Kroxt **doesn't provide a UI** (no login buttons or pre-made forms). Instead, it provides the **engine** (the logic).
128
-
129
- **Why is this good?**
130
- It means you can build your own login screen in React, Vue, or even a Mobile App, and Kroxt will handle the security part on the server exactly the same way every time.
131
-
132
- ---
133
-
134
86
  ## 🛠️ Advanced: Custom JWT Payloads
135
87
 
136
88
  Want to share a user's `role` or `plan` with the frontend via the JWT? Use the `payload` hook:
@@ -143,10 +95,10 @@ export const auth = createAuth({
143
95
  if (type === "access") {
144
96
  return {
145
97
  role: user.role,
146
- tier: user.subscriptionTier
98
+ schoolId: user.schoolId
147
99
  };
148
100
  }
149
- return {}; // Keep refresh tokens small
101
+ return {};
150
102
  }
151
103
  }
152
104
  });
@@ -154,29 +106,10 @@ export const auth = createAuth({
154
106
 
155
107
  ---
156
108
 
157
- ## 🛑 Common v1.2.0 Troubleshooting
158
-
159
- ### "Cannot find module '.prisma/client/default.js'" (ESM on Windows)
160
- If you're using Prisma with ESM (`"type": "module"`) on Windows, you may need a robust import in your `src/db/index.ts`:
161
-
162
- ```typescript
163
- import { createRequire } from "module";
164
- const require = createRequire(import.meta.url);
165
- const { PrismaClient } = require("@prisma/client");
166
- ```
167
-
168
- ### Prisma "Unknown argument `name`"
169
- Prisma is strict about schemas. If you're sending extra fields in `auth.signup()`, ensure your `schema.prisma` includes them (marked as `?` optional if needed).
170
-
171
- ---
172
-
173
109
  ## 🔗 Reference Projects
174
110
 
175
111
  Complete working implementations for all frameworks:
176
112
  - [Kroxt Examples (All Frameworks)](https://github.com/adepoju-oluwatobi/kroxt-examples)
177
- - [Hono + Drizzle + SQLite](https://github.com/adepoju-oluwatobi/kroxt-examples/tree/main/hono/kroxt-hono-drizzle)
178
- - [Express + Prisma + DB](https://github.com/adepoju-oluwatobi/kroxt-examples/tree/main/express/kroxt-express-prisma)
179
- - [Fastify + Mongoose](https://github.com/adepoju-oluwatobi/kroxt-examples/tree/main/fastify/kroxt-fastify-mongo)
180
113
 
181
114
  ## 📄 License
182
115
 
@@ -8,7 +8,8 @@ import type { AuthAdapter, User } from "./index.js";
8
8
  * @param db - The Drizzle database instance.
9
9
  * @param table - The Drizzle table representing users.
10
10
  * @param eq - The Drizzle `eq` operator (imported from `drizzle-orm`).
11
+ * @param rateLimitTable - Optional Drizzle table for rate limiting tracking.
11
12
  * @returns An AuthAdapter compliant object.
12
13
  */
13
- export declare function createDrizzleAdapter<TUser extends User = User>(db: any, table: any, eq: any): AuthAdapter<TUser>;
14
+ export declare function createDrizzleAdapter<TUser extends User = User>(db: any, table: any, eq: any, rateLimitTable?: any): AuthAdapter<TUser>;
14
15
  //# sourceMappingURL=drizzle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/drizzle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAC5D,EAAE,EAAE,GAAG,EACP,KAAK,EAAE,GAAG,EACV,EAAE,EAAE,GAAG,GACN,WAAW,CAAC,KAAK,CAAC,CA2BpB"}
1
+ {"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/drizzle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAC5D,EAAE,EAAE,GAAG,EACP,KAAK,EAAE,GAAG,EACV,EAAE,EAAE,GAAG,EACP,cAAc,CAAC,EAAE,GAAG,GACnB,WAAW,CAAC,KAAK,CAAC,CAgEpB"}
@@ -9,6 +9,15 @@ export interface AuthAdapter<TUser = User> {
9
9
  createUser: (data: any) => Promise<TUser>;
10
10
  findUserByEmail: (email: string) => Promise<TUser | null>;
11
11
  findUserById: (id: string) => Promise<TUser | null>;
12
+ updateUser?: (id: string, data: Partial<TUser>) => Promise<TUser | null>;
12
13
  linkOAuthAccount: (userId: string, provider: string, providerId: string) => Promise<void>;
14
+ incrementRateLimit?: (key: string, windowMs: number) => Promise<{
15
+ count: number;
16
+ resetTime: number;
17
+ }>;
18
+ getRateLimit?: (key: string) => Promise<{
19
+ count: number;
20
+ resetTime: number;
21
+ } | null>;
13
22
  }
14
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,QAAQ,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,IAAI;IACvC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC1D,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACpD,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3F"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,QAAQ,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,IAAI;IACvC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC1D,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACzE,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtG,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACtF"}
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,KAAK,WAAW,CAAC,KAAK,CAAC,CAiCnF"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,KAAK,WAAW,CAAC,KAAK,CAAC,CAkEnF"}
@@ -1,9 +1,15 @@
1
1
  import type { AuthAdapter, User } from "./index.js";
2
+ /**
3
+ * Creates a pre-configured Mongoose model for rate limiting.
4
+ * @param mongoose The mongoose instance to use for schema creation.
5
+ */
6
+ export declare function createRateLimitModel(mongoose: any): any;
2
7
  /**
3
8
  * Creates a MongoDB adapter using a Mongoose model.
4
9
  *
5
10
  * @param model - A Mongoose model instance (e.g., User model).
11
+ * @param rateLimitModel - An optional Mongoose model for rate limiting tracking.
6
12
  * @returns An AuthAdapter compliant object.
7
13
  */
8
- export declare function createMongoAdapter<TUser extends User = User>(model: any): AuthAdapter<TUser>;
14
+ export declare function createMongoAdapter<TUser extends User = User>(model: any, rateLimitModel?: any): AuthAdapter<TUser>;
9
15
  //# sourceMappingURL=mongoose.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mongoose.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/mongoose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CA6B5F"}
1
+ {"version":3,"file":"mongoose.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/mongoose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,GAAG,OAQjD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAoElH"}
@@ -6,7 +6,8 @@ import type { AuthAdapter, User } from "./index.js";
6
6
  * Prisma delegate operations (findUnique, create, update).
7
7
  *
8
8
  * @param model - A Prisma delegate instance (e.g., prisma.user).
9
+ * @param rateLimitModel - An optional Prisma delegate for rate limit tracking.
9
10
  * @returns An AuthAdapter compliant object.
10
11
  */
11
- export declare function createPrismaAdapter<TUser extends User = User>(model: any): AuthAdapter<TUser>;
12
+ export declare function createPrismaAdapter<TUser extends User = User>(model: any, rateLimitModel?: any): AuthAdapter<TUser>;
12
13
  //# sourceMappingURL=prisma.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAgC7F"}
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/auth/adapters/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,cAAc,CAAC,EAAE,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAuEnH"}
@@ -21,8 +21,8 @@ __export(drizzle_exports, {
21
21
  createDrizzleAdapter: () => createDrizzleAdapter
22
22
  });
23
23
  module.exports = __toCommonJS(drizzle_exports);
24
- function createDrizzleAdapter(db, table, eq) {
25
- return {
24
+ function createDrizzleAdapter(db, table, eq, rateLimitTable) {
25
+ const adapter = {
26
26
  async createUser(data) {
27
27
  const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };
28
28
  const results = await db.insert(table).values(dataToSave).returning();
@@ -36,6 +36,10 @@ function createDrizzleAdapter(db, table, eq) {
36
36
  const results = await db.select().from(table).where(eq(table.id, id)).limit(1);
37
37
  return results[0] || null;
38
38
  },
39
+ async updateUser(id, data) {
40
+ const results = await db.update(table).set(data).where(eq(table.id, id)).returning();
41
+ return results[0] || null;
42
+ },
39
43
  async linkOAuthAccount(userId, provider, providerId) {
40
44
  await db.update(table).set({
41
45
  oauthProvider: provider,
@@ -43,6 +47,33 @@ function createDrizzleAdapter(db, table, eq) {
43
47
  }).where(eq(table.id, userId));
44
48
  }
45
49
  };
50
+ if (rateLimitTable) {
51
+ adapter.incrementRateLimit = async (key, windowMs) => {
52
+ const now = Date.now();
53
+ const resetTime = now + windowMs;
54
+ let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);
55
+ let record = records[0];
56
+ if (!record || now > record.resetTime) {
57
+ if (record) {
58
+ await db.update(rateLimitTable).set({ count: 1, resetTime }).where(eq(rateLimitTable.key, key));
59
+ } else {
60
+ await db.insert(rateLimitTable).values({ key, count: 1, resetTime });
61
+ }
62
+ return { count: 1, resetTime };
63
+ } else {
64
+ await db.update(rateLimitTable).set({ count: record.count + 1 }).where(eq(rateLimitTable.key, key));
65
+ return { count: record.count + 1, resetTime: record.resetTime };
66
+ }
67
+ };
68
+ adapter.getRateLimit = async (key) => {
69
+ const now = Date.now();
70
+ let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);
71
+ let record = records[0];
72
+ if (!record || now > record.resetTime) return null;
73
+ return { count: record.count, resetTime: record.resetTime };
74
+ };
75
+ }
76
+ return adapter;
46
77
  }
47
78
  // Annotate the CommonJS export names for ESM import in node:
48
79
  0 && (module.exports = {
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/auth/adapters/drizzle.ts"],
4
+ "sourcesContent": ["import type { AuthAdapter, User } from \"./index.js\";\r\n\r\n/**\r\n * Creates a Drizzle ORM adapter.\r\n * \r\n * Works with any Drizzle-supported database (PostgreSQL, MySQL, SQLite)\r\n * by using the standard drizzle-orm `db` instance and table definition.\r\n * \r\n * @param db - The Drizzle database instance.\r\n * @param table - The Drizzle table representing users.\r\n * @param eq - The Drizzle `eq` operator (imported from `drizzle-orm`).\r\n * @param rateLimitTable - Optional Drizzle table for rate limiting tracking.\r\n * @returns An AuthAdapter compliant object.\r\n */\r\nexport function createDrizzleAdapter<TUser extends User = User>(\r\n db: any,\r\n table: any,\r\n eq: any,\r\n rateLimitTable?: any\r\n): AuthAdapter<TUser> {\r\n const adapter: AuthAdapter<TUser> = {\r\n async createUser(data: any) {\r\n const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };\r\n const results = await db.insert(table).values(dataToSave).returning();\r\n return results[0] as TUser;\r\n },\r\n\r\n async findUserByEmail(email: string) {\r\n const results = await db.select().from(table).where(eq(table.email, email)).limit(1);\r\n return (results[0] || null) as TUser | null;\r\n },\r\n\r\n async findUserById(id: string) {\r\n const results = await db.select().from(table).where(eq(table.id, id)).limit(1);\r\n return (results[0] || null) as TUser | null;\r\n },\r\n\r\n async updateUser(id: string, data: Partial<TUser>) {\r\n const results = await db.update(table).set(data).where(eq(table.id, id)).returning();\r\n return (results[0] || null) as TUser | null;\r\n },\r\n\r\n async linkOAuthAccount(userId: string, provider: string, providerId: string) {\r\n await db.update(table)\r\n .set({\r\n oauthProvider: provider,\r\n oauthId: providerId,\r\n })\r\n .where(eq(table.id, userId));\r\n },\r\n };\r\n\r\n if (rateLimitTable) {\r\n adapter.incrementRateLimit = async (key: string, windowMs: number) => {\r\n const now = Date.now();\r\n const resetTime = now + windowMs;\r\n \r\n let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);\r\n let record = records[0];\r\n \r\n if (!record || now > record.resetTime) {\r\n if (record) {\r\n await db.update(rateLimitTable).set({ count: 1, resetTime }).where(eq(rateLimitTable.key, key));\r\n } else {\r\n await db.insert(rateLimitTable).values({ key, count: 1, resetTime });\r\n }\r\n return { count: 1, resetTime };\r\n } else {\r\n await db.update(rateLimitTable).set({ count: record.count + 1 }).where(eq(rateLimitTable.key, key));\r\n return { count: record.count + 1, resetTime: record.resetTime };\r\n }\r\n };\r\n\r\n adapter.getRateLimit = async (key: string) => {\r\n const now = Date.now();\r\n let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);\r\n let record = records[0];\r\n if (!record || now > record.resetTime) return null;\r\n return { count: record.count, resetTime: record.resetTime };\r\n };\r\n }\r\n\r\n return adapter;\r\n}\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAcO,SAAS,qBACd,IACA,OACA,IACA,gBACoB;AACpB,QAAM,UAA8B;AAAA,IAClC,MAAM,WAAW,MAAW;AAC1B,YAAM,aAAa,EAAE,IAAI,KAAK,MAAM,WAAW,OAAO,WAAW,GAAG,GAAG,KAAK;AAC5E,YAAM,UAAU,MAAM,GAAG,OAAO,KAAK,EAAE,OAAO,UAAU,EAAE,UAAU;AACpE,aAAO,QAAQ,CAAC;AAAA,IAClB;AAAA,IAEA,MAAM,gBAAgB,OAAe;AACnC,YAAM,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,GAAG,MAAM,OAAO,KAAK,CAAC,EAAE,MAAM,CAAC;AACnF,aAAQ,QAAQ,CAAC,KAAK;AAAA,IACxB;AAAA,IAEA,MAAM,aAAa,IAAY;AAC7B,YAAM,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC;AAC7E,aAAQ,QAAQ,CAAC,KAAK;AAAA,IACxB;AAAA,IAEA,MAAM,WAAW,IAAY,MAAsB;AACjD,YAAM,UAAU,MAAM,GAAG,OAAO,KAAK,EAAE,IAAI,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC,EAAE,UAAU;AACnF,aAAQ,QAAQ,CAAC,KAAK;AAAA,IACxB;AAAA,IAEA,MAAM,iBAAiB,QAAgB,UAAkB,YAAoB;AAC3E,YAAM,GAAG,OAAO,KAAK,EAClB,IAAI;AAAA,QACH,eAAe;AAAA,QACf,SAAS;AAAA,MACX,CAAC,EACA,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,YAAQ,qBAAqB,OAAO,KAAa,aAAqB;AACpE,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,YAAY,MAAM;AAExB,UAAI,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC;AAC/F,UAAI,SAAS,QAAQ,CAAC;AAEtB,UAAI,CAAC,UAAU,MAAM,OAAO,WAAW;AACnC,YAAI,QAAQ;AACR,gBAAM,GAAG,OAAO,cAAc,EAAE,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC;AAAA,QAClG,OAAO;AACH,gBAAM,GAAG,OAAO,cAAc,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,UAAU,CAAC;AAAA,QACvE;AACA,eAAO,EAAE,OAAO,GAAG,UAAU;AAAA,MACjC,OAAO;AACH,cAAM,GAAG,OAAO,cAAc,EAAE,IAAI,EAAE,OAAO,OAAO,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC;AAClG,eAAO,EAAE,OAAO,OAAO,QAAQ,GAAG,WAAW,OAAO,UAAU;AAAA,MAClE;AAAA,IACF;AAEA,YAAQ,eAAe,OAAO,QAAgB;AAC5C,YAAM,MAAM,KAAK,IAAI;AACrB,UAAI,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC;AAC/F,UAAI,SAAS,QAAQ,CAAC;AACtB,UAAI,CAAC,UAAU,MAAM,OAAO,UAAW,QAAO;AAC9C,aAAO,EAAE,OAAO,OAAO,OAAO,WAAW,OAAO,UAAU;AAAA,IAC5D;AAAA,EACF;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,58 @@
1
+ function createDrizzleAdapter(db, table, eq, rateLimitTable) {
2
+ const adapter = {
3
+ async createUser(data) {
4
+ const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };
5
+ const results = await db.insert(table).values(dataToSave).returning();
6
+ return results[0];
7
+ },
8
+ async findUserByEmail(email) {
9
+ const results = await db.select().from(table).where(eq(table.email, email)).limit(1);
10
+ return results[0] || null;
11
+ },
12
+ async findUserById(id) {
13
+ const results = await db.select().from(table).where(eq(table.id, id)).limit(1);
14
+ return results[0] || null;
15
+ },
16
+ async updateUser(id, data) {
17
+ const results = await db.update(table).set(data).where(eq(table.id, id)).returning();
18
+ return results[0] || null;
19
+ },
20
+ async linkOAuthAccount(userId, provider, providerId) {
21
+ await db.update(table).set({
22
+ oauthProvider: provider,
23
+ oauthId: providerId
24
+ }).where(eq(table.id, userId));
25
+ }
26
+ };
27
+ if (rateLimitTable) {
28
+ adapter.incrementRateLimit = async (key, windowMs) => {
29
+ const now = Date.now();
30
+ const resetTime = now + windowMs;
31
+ let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);
32
+ let record = records[0];
33
+ if (!record || now > record.resetTime) {
34
+ if (record) {
35
+ await db.update(rateLimitTable).set({ count: 1, resetTime }).where(eq(rateLimitTable.key, key));
36
+ } else {
37
+ await db.insert(rateLimitTable).values({ key, count: 1, resetTime });
38
+ }
39
+ return { count: 1, resetTime };
40
+ } else {
41
+ await db.update(rateLimitTable).set({ count: record.count + 1 }).where(eq(rateLimitTable.key, key));
42
+ return { count: record.count + 1, resetTime: record.resetTime };
43
+ }
44
+ };
45
+ adapter.getRateLimit = async (key) => {
46
+ const now = Date.now();
47
+ let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);
48
+ let record = records[0];
49
+ if (!record || now > record.resetTime) return null;
50
+ return { count: record.count, resetTime: record.resetTime };
51
+ };
52
+ }
53
+ return adapter;
54
+ }
55
+ export {
56
+ createDrizzleAdapter
57
+ };
58
+ //# sourceMappingURL=drizzle.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/auth/adapters/drizzle.ts"],
4
+ "sourcesContent": ["import type { AuthAdapter, User } from \"./index.js\";\r\n\r\n/**\r\n * Creates a Drizzle ORM adapter.\r\n * \r\n * Works with any Drizzle-supported database (PostgreSQL, MySQL, SQLite)\r\n * by using the standard drizzle-orm `db` instance and table definition.\r\n * \r\n * @param db - The Drizzle database instance.\r\n * @param table - The Drizzle table representing users.\r\n * @param eq - The Drizzle `eq` operator (imported from `drizzle-orm`).\r\n * @param rateLimitTable - Optional Drizzle table for rate limiting tracking.\r\n * @returns An AuthAdapter compliant object.\r\n */\r\nexport function createDrizzleAdapter<TUser extends User = User>(\r\n db: any,\r\n table: any,\r\n eq: any,\r\n rateLimitTable?: any\r\n): AuthAdapter<TUser> {\r\n const adapter: AuthAdapter<TUser> = {\r\n async createUser(data: any) {\r\n const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };\r\n const results = await db.insert(table).values(dataToSave).returning();\r\n return results[0] as TUser;\r\n },\r\n\r\n async findUserByEmail(email: string) {\r\n const results = await db.select().from(table).where(eq(table.email, email)).limit(1);\r\n return (results[0] || null) as TUser | null;\r\n },\r\n\r\n async findUserById(id: string) {\r\n const results = await db.select().from(table).where(eq(table.id, id)).limit(1);\r\n return (results[0] || null) as TUser | null;\r\n },\r\n\r\n async updateUser(id: string, data: Partial<TUser>) {\r\n const results = await db.update(table).set(data).where(eq(table.id, id)).returning();\r\n return (results[0] || null) as TUser | null;\r\n },\r\n\r\n async linkOAuthAccount(userId: string, provider: string, providerId: string) {\r\n await db.update(table)\r\n .set({\r\n oauthProvider: provider,\r\n oauthId: providerId,\r\n })\r\n .where(eq(table.id, userId));\r\n },\r\n };\r\n\r\n if (rateLimitTable) {\r\n adapter.incrementRateLimit = async (key: string, windowMs: number) => {\r\n const now = Date.now();\r\n const resetTime = now + windowMs;\r\n \r\n let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);\r\n let record = records[0];\r\n \r\n if (!record || now > record.resetTime) {\r\n if (record) {\r\n await db.update(rateLimitTable).set({ count: 1, resetTime }).where(eq(rateLimitTable.key, key));\r\n } else {\r\n await db.insert(rateLimitTable).values({ key, count: 1, resetTime });\r\n }\r\n return { count: 1, resetTime };\r\n } else {\r\n await db.update(rateLimitTable).set({ count: record.count + 1 }).where(eq(rateLimitTable.key, key));\r\n return { count: record.count + 1, resetTime: record.resetTime };\r\n }\r\n };\r\n\r\n adapter.getRateLimit = async (key: string) => {\r\n const now = Date.now();\r\n let records = await db.select().from(rateLimitTable).where(eq(rateLimitTable.key, key)).limit(1);\r\n let record = records[0];\r\n if (!record || now > record.resetTime) return null;\r\n return { count: record.count, resetTime: record.resetTime };\r\n };\r\n }\r\n\r\n return adapter;\r\n}\r\n"],
5
+ "mappings": "AAcO,SAAS,qBACd,IACA,OACA,IACA,gBACoB;AACpB,QAAM,UAA8B;AAAA,IAClC,MAAM,WAAW,MAAW;AAC1B,YAAM,aAAa,EAAE,IAAI,KAAK,MAAM,WAAW,OAAO,WAAW,GAAG,GAAG,KAAK;AAC5E,YAAM,UAAU,MAAM,GAAG,OAAO,KAAK,EAAE,OAAO,UAAU,EAAE,UAAU;AACpE,aAAO,QAAQ,CAAC;AAAA,IAClB;AAAA,IAEA,MAAM,gBAAgB,OAAe;AACnC,YAAM,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,GAAG,MAAM,OAAO,KAAK,CAAC,EAAE,MAAM,CAAC;AACnF,aAAQ,QAAQ,CAAC,KAAK;AAAA,IACxB;AAAA,IAEA,MAAM,aAAa,IAAY;AAC7B,YAAM,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC;AAC7E,aAAQ,QAAQ,CAAC,KAAK;AAAA,IACxB;AAAA,IAEA,MAAM,WAAW,IAAY,MAAsB;AACjD,YAAM,UAAU,MAAM,GAAG,OAAO,KAAK,EAAE,IAAI,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC,EAAE,UAAU;AACnF,aAAQ,QAAQ,CAAC,KAAK;AAAA,IACxB;AAAA,IAEA,MAAM,iBAAiB,QAAgB,UAAkB,YAAoB;AAC3E,YAAM,GAAG,OAAO,KAAK,EAClB,IAAI;AAAA,QACH,eAAe;AAAA,QACf,SAAS;AAAA,MACX,CAAC,EACA,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,gBAAgB;AAClB,YAAQ,qBAAqB,OAAO,KAAa,aAAqB;AACpE,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,YAAY,MAAM;AAExB,UAAI,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC;AAC/F,UAAI,SAAS,QAAQ,CAAC;AAEtB,UAAI,CAAC,UAAU,MAAM,OAAO,WAAW;AACnC,YAAI,QAAQ;AACR,gBAAM,GAAG,OAAO,cAAc,EAAE,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC;AAAA,QAClG,OAAO;AACH,gBAAM,GAAG,OAAO,cAAc,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,UAAU,CAAC;AAAA,QACvE;AACA,eAAO,EAAE,OAAO,GAAG,UAAU;AAAA,MACjC,OAAO;AACH,cAAM,GAAG,OAAO,cAAc,EAAE,IAAI,EAAE,OAAO,OAAO,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC;AAClG,eAAO,EAAE,OAAO,OAAO,QAAQ,GAAG,WAAW,OAAO,UAAU;AAAA,MAClE;AAAA,IACF;AAEA,YAAQ,eAAe,OAAO,QAAgB;AAC5C,YAAM,MAAM,KAAK,IAAI;AACrB,UAAI,UAAU,MAAM,GAAG,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,GAAG,eAAe,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC;AAC/F,UAAI,SAAS,QAAQ,CAAC;AACtB,UAAI,CAAC,UAAU,MAAM,OAAO,UAAW,QAAO;AAC9C,aAAO,EAAE,OAAO,OAAO,OAAO,WAAW,OAAO,UAAU;AAAA,IAC5D;AAAA,EACF;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/auth/adapters/index.ts"],
4
+ "sourcesContent": ["export interface BaseUser {\r\n id: string;\r\n email: string;\r\n passwordHash?: string;\r\n role?: string;\r\n}\r\n\r\n// Allows any extended fields natively (like nin, bvn, maritalStatus, etc.)\r\nexport type User<TExtended = Record<string, any>> = BaseUser & TExtended;\r\n\r\nexport interface AuthAdapter<TUser = User> {\r\n createUser: (data: any) => Promise<TUser>;\r\n findUserByEmail: (email: string) => Promise<TUser | null>;\r\n findUserById: (id: string) => Promise<TUser | null>;\r\n updateUser?: (id: string, data: Partial<TUser>) => Promise<TUser | null>;\r\n linkOAuthAccount: (userId: string, provider: string, providerId: string) => Promise<void>;\r\n incrementRateLimit?: (key: string, windowMs: number) => Promise<{ count: number; resetTime: number }>;\r\n getRateLimit?: (key: string) => Promise<{ count: number; resetTime: number } | null>;\r\n}\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
+ "names": []
7
+ }
@@ -24,6 +24,7 @@ module.exports = __toCommonJS(memory_exports);
24
24
  function createMemoryAdapter() {
25
25
  const users = /* @__PURE__ */ new Map();
26
26
  const accounts = /* @__PURE__ */ new Map();
27
+ const rateLimits = /* @__PURE__ */ new Map();
27
28
  return {
28
29
  createUser: async (data) => {
29
30
  const id = data.id || Date.now().toString();
@@ -42,9 +43,36 @@ function createMemoryAdapter() {
42
43
  }
43
44
  return null;
44
45
  },
46
+ updateUser: async (id, data) => {
47
+ for (const [email, user] of users.entries()) {
48
+ if (user.id === id) {
49
+ const updatedUser = { ...user, ...data };
50
+ users.set(email, updatedUser);
51
+ return updatedUser;
52
+ }
53
+ }
54
+ return null;
55
+ },
45
56
  linkOAuthAccount: async (userId, provider, providerId) => {
46
57
  const accountId = `${provider}_${providerId}`;
47
58
  accounts.set(accountId, { userId, provider, providerId });
59
+ },
60
+ incrementRateLimit: async (key, windowMs) => {
61
+ const now = Date.now();
62
+ const record = rateLimits.get(key);
63
+ if (!record || now > record.resetTime) {
64
+ const newRecord = { count: 1, resetTime: now + windowMs };
65
+ rateLimits.set(key, newRecord);
66
+ return newRecord;
67
+ }
68
+ record.count += 1;
69
+ return record;
70
+ },
71
+ getRateLimit: async (key) => {
72
+ const now = Date.now();
73
+ const record = rateLimits.get(key);
74
+ if (!record || now > record.resetTime) return null;
75
+ return record;
48
76
  }
49
77
  };
50
78
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/auth/adapters/memory.ts"],
4
+ "sourcesContent": ["import type { AuthAdapter, User } from \"./index.js\";\r\n\r\n/**\r\n * Creates an in-memory database adapter for the auth engine.\r\n * This is useful for testing, prototyping, or when you don't need persistent storage.\r\n * All data is kept in memory and is lost when the server restarts.\r\n */\r\nexport function createMemoryAdapter<TUser extends User = User>(): AuthAdapter<TUser> {\r\n const users = new Map<string, TUser>();\r\n const accounts = new Map<string, { userId: string; provider: string; providerId: string }>();\r\n const rateLimits = new Map<string, { count: number; resetTime: number }>();\r\n\r\n return {\r\n createUser: async (data: any) => {\r\n // Auto-generate ID if not provided\r\n const id = data.id || Date.now().toString();\r\n const newUser = { ...data, id } as TUser;\r\n\r\n // Store using email as the primary lookup key\r\n users.set(newUser.email, newUser);\r\n return newUser;\r\n },\r\n\r\n findUserByEmail: async (email: string) => {\r\n return users.get(email) || null;\r\n },\r\n\r\n findUserById: async (id: string) => {\r\n for (const user of users.values()) {\r\n if (user.id === id) {\r\n return user;\r\n }\r\n }\r\n return null;\r\n },\r\n\r\n updateUser: async (id: string, data: Partial<TUser>) => {\r\n for (const [email, user] of users.entries()) {\r\n if (user.id === id) {\r\n const updatedUser = { ...user, ...data } as TUser;\r\n users.set(email, updatedUser);\r\n return updatedUser;\r\n }\r\n }\r\n return null;\r\n },\r\n\r\n linkOAuthAccount: async (userId: string, provider: string, providerId: string) => {\r\n const accountId = `${provider}_${providerId}`;\r\n accounts.set(accountId, { userId, provider, providerId });\r\n },\r\n\r\n incrementRateLimit: async (key: string, windowMs: number) => {\r\n const now = Date.now();\r\n const record = rateLimits.get(key);\r\n\r\n if (!record || now > record.resetTime) {\r\n const newRecord = { count: 1, resetTime: now + windowMs };\r\n rateLimits.set(key, newRecord);\r\n return newRecord;\r\n }\r\n\r\n record.count += 1;\r\n return record;\r\n },\r\n\r\n getRateLimit: async (key: string) => {\r\n const now = Date.now();\r\n const record = rateLimits.get(key);\r\n if (!record || now > record.resetTime) return null;\r\n return record;\r\n }\r\n };\r\n}\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,SAAS,sBAAqE;AACjF,QAAM,QAAQ,oBAAI,IAAmB;AACrC,QAAM,WAAW,oBAAI,IAAsE;AAC3F,QAAM,aAAa,oBAAI,IAAkD;AAEzE,SAAO;AAAA,IACH,YAAY,OAAO,SAAc;AAE7B,YAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE,SAAS;AAC1C,YAAM,UAAU,EAAE,GAAG,MAAM,GAAG;AAG9B,YAAM,IAAI,QAAQ,OAAO,OAAO;AAChC,aAAO;AAAA,IACX;AAAA,IAEA,iBAAiB,OAAO,UAAkB;AACtC,aAAO,MAAM,IAAI,KAAK,KAAK;AAAA,IAC/B;AAAA,IAEA,cAAc,OAAO,OAAe;AAChC,iBAAW,QAAQ,MAAM,OAAO,GAAG;AAC/B,YAAI,KAAK,OAAO,IAAI;AAChB,iBAAO;AAAA,QACX;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAAA,IAEA,YAAY,OAAO,IAAY,SAAyB;AACpD,iBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AACzC,YAAI,KAAK,OAAO,IAAI;AAChB,gBAAM,cAAc,EAAE,GAAG,MAAM,GAAG,KAAK;AACvC,gBAAM,IAAI,OAAO,WAAW;AAC5B,iBAAO;AAAA,QACX;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAAA,IAEA,kBAAkB,OAAO,QAAgB,UAAkB,eAAuB;AAC9E,YAAM,YAAY,GAAG,QAAQ,IAAI,UAAU;AAC3C,eAAS,IAAI,WAAW,EAAE,QAAQ,UAAU,WAAW,CAAC;AAAA,IAC5D;AAAA,IAEA,oBAAoB,OAAO,KAAa,aAAqB;AACzD,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,SAAS,WAAW,IAAI,GAAG;AAEjC,UAAI,CAAC,UAAU,MAAM,OAAO,WAAW;AACnC,cAAM,YAAY,EAAE,OAAO,GAAG,WAAW,MAAM,SAAS;AACxD,mBAAW,IAAI,KAAK,SAAS;AAC7B,eAAO;AAAA,MACX;AAEA,aAAO,SAAS;AAChB,aAAO;AAAA,IACX;AAAA,IAEA,cAAc,OAAO,QAAgB;AACjC,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,SAAS,WAAW,IAAI,GAAG;AACjC,UAAI,CAAC,UAAU,MAAM,OAAO,UAAW,QAAO;AAC9C,aAAO;AAAA,IACX;AAAA,EACJ;AACJ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,59 @@
1
+ function createMemoryAdapter() {
2
+ const users = /* @__PURE__ */ new Map();
3
+ const accounts = /* @__PURE__ */ new Map();
4
+ const rateLimits = /* @__PURE__ */ new Map();
5
+ return {
6
+ createUser: async (data) => {
7
+ const id = data.id || Date.now().toString();
8
+ const newUser = { ...data, id };
9
+ users.set(newUser.email, newUser);
10
+ return newUser;
11
+ },
12
+ findUserByEmail: async (email) => {
13
+ return users.get(email) || null;
14
+ },
15
+ findUserById: async (id) => {
16
+ for (const user of users.values()) {
17
+ if (user.id === id) {
18
+ return user;
19
+ }
20
+ }
21
+ return null;
22
+ },
23
+ updateUser: async (id, data) => {
24
+ for (const [email, user] of users.entries()) {
25
+ if (user.id === id) {
26
+ const updatedUser = { ...user, ...data };
27
+ users.set(email, updatedUser);
28
+ return updatedUser;
29
+ }
30
+ }
31
+ return null;
32
+ },
33
+ linkOAuthAccount: async (userId, provider, providerId) => {
34
+ const accountId = `${provider}_${providerId}`;
35
+ accounts.set(accountId, { userId, provider, providerId });
36
+ },
37
+ incrementRateLimit: async (key, windowMs) => {
38
+ const now = Date.now();
39
+ const record = rateLimits.get(key);
40
+ if (!record || now > record.resetTime) {
41
+ const newRecord = { count: 1, resetTime: now + windowMs };
42
+ rateLimits.set(key, newRecord);
43
+ return newRecord;
44
+ }
45
+ record.count += 1;
46
+ return record;
47
+ },
48
+ getRateLimit: async (key) => {
49
+ const now = Date.now();
50
+ const record = rateLimits.get(key);
51
+ if (!record || now > record.resetTime) return null;
52
+ return record;
53
+ }
54
+ };
55
+ }
56
+ export {
57
+ createMemoryAdapter
58
+ };
59
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/auth/adapters/memory.ts"],
4
+ "sourcesContent": ["import type { AuthAdapter, User } from \"./index.js\";\r\n\r\n/**\r\n * Creates an in-memory database adapter for the auth engine.\r\n * This is useful for testing, prototyping, or when you don't need persistent storage.\r\n * All data is kept in memory and is lost when the server restarts.\r\n */\r\nexport function createMemoryAdapter<TUser extends User = User>(): AuthAdapter<TUser> {\r\n const users = new Map<string, TUser>();\r\n const accounts = new Map<string, { userId: string; provider: string; providerId: string }>();\r\n const rateLimits = new Map<string, { count: number; resetTime: number }>();\r\n\r\n return {\r\n createUser: async (data: any) => {\r\n // Auto-generate ID if not provided\r\n const id = data.id || Date.now().toString();\r\n const newUser = { ...data, id } as TUser;\r\n\r\n // Store using email as the primary lookup key\r\n users.set(newUser.email, newUser);\r\n return newUser;\r\n },\r\n\r\n findUserByEmail: async (email: string) => {\r\n return users.get(email) || null;\r\n },\r\n\r\n findUserById: async (id: string) => {\r\n for (const user of users.values()) {\r\n if (user.id === id) {\r\n return user;\r\n }\r\n }\r\n return null;\r\n },\r\n\r\n updateUser: async (id: string, data: Partial<TUser>) => {\r\n for (const [email, user] of users.entries()) {\r\n if (user.id === id) {\r\n const updatedUser = { ...user, ...data } as TUser;\r\n users.set(email, updatedUser);\r\n return updatedUser;\r\n }\r\n }\r\n return null;\r\n },\r\n\r\n linkOAuthAccount: async (userId: string, provider: string, providerId: string) => {\r\n const accountId = `${provider}_${providerId}`;\r\n accounts.set(accountId, { userId, provider, providerId });\r\n },\r\n\r\n incrementRateLimit: async (key: string, windowMs: number) => {\r\n const now = Date.now();\r\n const record = rateLimits.get(key);\r\n\r\n if (!record || now > record.resetTime) {\r\n const newRecord = { count: 1, resetTime: now + windowMs };\r\n rateLimits.set(key, newRecord);\r\n return newRecord;\r\n }\r\n\r\n record.count += 1;\r\n return record;\r\n },\r\n\r\n getRateLimit: async (key: string) => {\r\n const now = Date.now();\r\n const record = rateLimits.get(key);\r\n if (!record || now > record.resetTime) return null;\r\n return record;\r\n }\r\n };\r\n}\r\n"],
5
+ "mappings": "AAOO,SAAS,sBAAqE;AACjF,QAAM,QAAQ,oBAAI,IAAmB;AACrC,QAAM,WAAW,oBAAI,IAAsE;AAC3F,QAAM,aAAa,oBAAI,IAAkD;AAEzE,SAAO;AAAA,IACH,YAAY,OAAO,SAAc;AAE7B,YAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE,SAAS;AAC1C,YAAM,UAAU,EAAE,GAAG,MAAM,GAAG;AAG9B,YAAM,IAAI,QAAQ,OAAO,OAAO;AAChC,aAAO;AAAA,IACX;AAAA,IAEA,iBAAiB,OAAO,UAAkB;AACtC,aAAO,MAAM,IAAI,KAAK,KAAK;AAAA,IAC/B;AAAA,IAEA,cAAc,OAAO,OAAe;AAChC,iBAAW,QAAQ,MAAM,OAAO,GAAG;AAC/B,YAAI,KAAK,OAAO,IAAI;AAChB,iBAAO;AAAA,QACX;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAAA,IAEA,YAAY,OAAO,IAAY,SAAyB;AACpD,iBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AACzC,YAAI,KAAK,OAAO,IAAI;AAChB,gBAAM,cAAc,EAAE,GAAG,MAAM,GAAG,KAAK;AACvC,gBAAM,IAAI,OAAO,WAAW;AAC5B,iBAAO;AAAA,QACX;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAAA,IAEA,kBAAkB,OAAO,QAAgB,UAAkB,eAAuB;AAC9E,YAAM,YAAY,GAAG,QAAQ,IAAI,UAAU;AAC3C,eAAS,IAAI,WAAW,EAAE,QAAQ,UAAU,WAAW,CAAC;AAAA,IAC5D;AAAA,IAEA,oBAAoB,OAAO,KAAa,aAAqB;AACzD,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,SAAS,WAAW,IAAI,GAAG;AAEjC,UAAI,CAAC,UAAU,MAAM,OAAO,WAAW;AACnC,cAAM,YAAY,EAAE,OAAO,GAAG,WAAW,MAAM,SAAS;AACxD,mBAAW,IAAI,KAAK,SAAS;AAC7B,eAAO;AAAA,MACX;AAEA,aAAO,SAAS;AAChB,aAAO;AAAA,IACX;AAAA,IAEA,cAAc,OAAO,QAAgB;AACjC,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,SAAS,WAAW,IAAI,GAAG;AACjC,UAAI,CAAC,UAAU,MAAM,OAAO,UAAW,QAAO;AAC9C,aAAO;AAAA,IACX;AAAA,EACJ;AACJ;",
6
+ "names": []
7
+ }