kroxt 1.1.5 → 1.2.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.
- package/README.md +177 -221
- package/dist/adapters/drizzle.cjs +51 -0
- package/dist/adapters/drizzle.cjs.map +7 -0
- package/dist/adapters/drizzle.d.ts +14 -0
- package/dist/adapters/drizzle.d.ts.map +1 -0
- package/dist/adapters/drizzle.js +27 -0
- package/dist/adapters/drizzle.js.map +7 -0
- package/dist/adapters/prisma.cjs +58 -0
- package/dist/adapters/prisma.cjs.map +7 -0
- package/dist/adapters/prisma.d.ts +12 -0
- package/dist/adapters/prisma.d.ts.map +1 -0
- package/dist/adapters/prisma.js +34 -0
- package/dist/adapters/prisma.js.map +7 -0
- package/package.json +12 -1
package/README.md
CHANGED
|
@@ -1,221 +1,177 @@
|
|
|
1
|
-
# kroxt
|
|
2
|
-
|
|
3
|
-
A framework-agnostic, modular authentication engine for modern TypeScript applications. Built for security, extensibility, and
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
import {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
linkOAuthAccount: async (id, provider, providerId) => {
|
|
179
|
-
await db.users.update({
|
|
180
|
-
where: { id },
|
|
181
|
-
data: { oauthProvider: provider, oauthId: providerId }
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Using this pattern, you can connect Kroxt to **Supabase**, **Firestore**, **PostgreSQL**, or even a 3rd-party API.
|
|
188
|
-
|
|
189
|
-
## Security Best Practices
|
|
190
|
-
|
|
191
|
-
### 1. Password Peppering
|
|
192
|
-
Always use a `pepper` in production. It's a server-side secret added to passwords before hashing. If your database is leaked, the hashes cannot be cracked without this pepper.
|
|
193
|
-
|
|
194
|
-
### 2. CSRF Protection
|
|
195
|
-
Kroxt provides helpers for the double-submit cookie pattern. Use these if you are storing tokens in cookies.
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
import { generateCsrfToken, verifyCsrf } from "kroxt/security";
|
|
199
|
-
|
|
200
|
-
const token = generateCsrfToken();
|
|
201
|
-
const isValid = verifyCsrf(tokenInRequest, tokenInCookie);
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### 3. Secure Cookies
|
|
205
|
-
If using cookies, always set these flags:
|
|
206
|
-
- `httpOnly: true` (Prevents XSS)
|
|
207
|
-
- `secure: true` (Requires HTTPS)
|
|
208
|
-
- `sameSite: 'strict'` (Prevents CSRF)
|
|
209
|
-
|
|
210
|
-
### 4. Rate Limiting
|
|
211
|
-
Implement rate limiting (e.g., `express-rate-limit`) on `/login` and `/register` to block brute-force attempts.
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## Reference Project
|
|
216
|
-
|
|
217
|
-
Check out the `kroxt-example` folder or the [GitHub repository](https://github.com/adepoju-oluwatobi/kroxt-example) for a complete **Express + MongoDB** implementation using this library.
|
|
218
|
-
|
|
219
|
-
## License
|
|
220
|
-
|
|
221
|
-
MIT
|
|
1
|
+
# kroxt 🔐
|
|
2
|
+
|
|
3
|
+
A framework-agnostic, modular authentication engine for modern TypeScript applications. Built for security, extensibility, and pure developer joy.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/kroxt)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## 🚀 Why Kroxt?
|
|
9
|
+
|
|
10
|
+
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:
|
|
11
|
+
|
|
12
|
+
- 🏗️ **Database Agnostic**: Native adapters for **Prisma**, **Drizzle**, and **Mongoose**.
|
|
13
|
+
- 🛠️ **Modular**: Use only what you need. No forced session managers or UI components.
|
|
14
|
+
- 🔐 **Security First**: Argon2 hashing, dual-token rotation, and timing-attack protection built-in.
|
|
15
|
+
- 🧩 **TypeScript Native**: Perfectly preserves your user schemas and metadata.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🗺️ How it Works
|
|
20
|
+
|
|
21
|
+
Kroxt sits between your database and your controller logic. It handles the "heavy lifting" (hashing, JWT signing, token rotation) while you maintain full control over your API.
|
|
22
|
+
|
|
23
|
+
```mermaid
|
|
24
|
+
graph LR
|
|
25
|
+
A[Client] -- "Credentials" --> B[Express/Fastify]
|
|
26
|
+
B -- "auth.signup()" --> C[Kroxt Engine]
|
|
27
|
+
C -- "Save User" --> D[(Database Adapter)]
|
|
28
|
+
D -- "Success" --> C
|
|
29
|
+
C -- "Tokens + User" --> B
|
|
30
|
+
B -- "Set Cookies/JSON" --> A
|
|
31
|
+
|
|
32
|
+
subgraph Adapters
|
|
33
|
+
D
|
|
34
|
+
E[Mongoose]
|
|
35
|
+
F[Drizzle]
|
|
36
|
+
G[Prisma]
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🏁 Quick Start (5 Minutes)
|
|
43
|
+
|
|
44
|
+
### 1. Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install kroxt
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Choose Your Adapter
|
|
51
|
+
|
|
52
|
+
Kroxt provides official adapters for the most popular ORMs.
|
|
53
|
+
|
|
54
|
+
#### **Option A: Drizzle (SQLite/PG/MySQL)**
|
|
55
|
+
```typescript
|
|
56
|
+
import { createDrizzleAdapter } from "kroxt/adapters/drizzle";
|
|
57
|
+
import { db } from "./db";
|
|
58
|
+
import { users } from "./schema";
|
|
59
|
+
import { eq } from "drizzle-orm";
|
|
60
|
+
|
|
61
|
+
export const adapter = createDrizzleAdapter(db, users, eq);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### **Option B: Prisma**
|
|
65
|
+
```typescript
|
|
66
|
+
import { createPrismaAdapter } from "kroxt/adapters/prisma";
|
|
67
|
+
import { prisma } from "./db";
|
|
68
|
+
|
|
69
|
+
export const adapter = createPrismaAdapter(prisma.user);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### **Option C: Mongoose**
|
|
73
|
+
```typescript
|
|
74
|
+
import { createMongoAdapter } from "kroxt/adapters/mongoose";
|
|
75
|
+
import { User } from "./models/user.model";
|
|
76
|
+
|
|
77
|
+
export const adapter = createMongoAdapter(User);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 3. Initialize the Engine
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { createAuth } from "kroxt/core";
|
|
84
|
+
import { adapter } from "./auth-adapter";
|
|
85
|
+
|
|
86
|
+
export const auth = createAuth({
|
|
87
|
+
adapter,
|
|
88
|
+
secret: process.env.JWT_SECRET,
|
|
89
|
+
session: {
|
|
90
|
+
expires: "15m",
|
|
91
|
+
refreshExpires: "7d"
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 🛡️ Core Authentication Flows
|
|
99
|
+
|
|
100
|
+
### **Registration**
|
|
101
|
+
```typescript
|
|
102
|
+
const { user, accessToken, refreshToken } = await auth.signup({
|
|
103
|
+
email,
|
|
104
|
+
name,
|
|
105
|
+
role: 'user'
|
|
106
|
+
}, password);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### **Login**
|
|
110
|
+
```typescript
|
|
111
|
+
const { user, accessToken, refreshToken } = await auth.loginWithPassword(email, password);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### **Token Refresh**
|
|
115
|
+
```typescript
|
|
116
|
+
const { accessToken } = await auth.refresh(refreshToken);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🐣 Beginner Corner: What is "Headless"?
|
|
122
|
+
|
|
123
|
+
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).
|
|
124
|
+
|
|
125
|
+
**Why is this good?**
|
|
126
|
+
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.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🛠️ Advanced: Custom JWT Payloads
|
|
131
|
+
|
|
132
|
+
Want to share a user's `role` or `plan` with the frontend via the JWT? Use the `payload` hook:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
export const auth = createAuth({
|
|
136
|
+
adapter,
|
|
137
|
+
jwt: {
|
|
138
|
+
payload: (user, type) => {
|
|
139
|
+
if (type === "access") {
|
|
140
|
+
return {
|
|
141
|
+
role: user.role,
|
|
142
|
+
tier: user.subscriptionTier
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return {}; // Keep refresh tokens small
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 🛑 Common v1.2.0 Troubleshooting
|
|
154
|
+
|
|
155
|
+
### "Cannot find module '.prisma/client/default.js'" (ESM on Windows)
|
|
156
|
+
If you're using Prisma with ESM (`"type": "module"`) on Windows, you may need a robust import in your `src/db/index.ts`:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { createRequire } from "module";
|
|
160
|
+
const require = createRequire(import.meta.url);
|
|
161
|
+
const { PrismaClient } = require("@prisma/client");
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Prisma "Unknown argument `name`"
|
|
165
|
+
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).
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 🔗 Reference Project
|
|
170
|
+
|
|
171
|
+
Complete working implementations:
|
|
172
|
+
- [Express + Drizzle + SQLite](https://github.com/adepoju-oluwatobi/kroxt-example)
|
|
173
|
+
- [Express + Mongoose](https://github.com/adepoju-oluwatobi/kroxt-example-cjs)
|
|
174
|
+
|
|
175
|
+
## 📄 License
|
|
176
|
+
|
|
177
|
+
MIT © [Adepoju Oluwatobi](https://github.com/adepoju-oluwatobi)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var drizzle_exports = {};
|
|
20
|
+
__export(drizzle_exports, {
|
|
21
|
+
createDrizzleAdapter: () => createDrizzleAdapter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(drizzle_exports);
|
|
24
|
+
function createDrizzleAdapter(db, table, eq) {
|
|
25
|
+
return {
|
|
26
|
+
async createUser(data) {
|
|
27
|
+
const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };
|
|
28
|
+
const results = await db.insert(table).values(dataToSave).returning();
|
|
29
|
+
return results[0];
|
|
30
|
+
},
|
|
31
|
+
async findUserByEmail(email) {
|
|
32
|
+
const results = await db.select().from(table).where(eq(table.email, email)).limit(1);
|
|
33
|
+
return results[0] || null;
|
|
34
|
+
},
|
|
35
|
+
async findUserById(id) {
|
|
36
|
+
const results = await db.select().from(table).where(eq(table.id, id)).limit(1);
|
|
37
|
+
return results[0] || null;
|
|
38
|
+
},
|
|
39
|
+
async linkOAuthAccount(userId, provider, providerId) {
|
|
40
|
+
await db.update(table).set({
|
|
41
|
+
oauthProvider: provider,
|
|
42
|
+
oauthId: providerId
|
|
43
|
+
}).where(eq(table.id, userId));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
+
0 && (module.exports = {
|
|
49
|
+
createDrizzleAdapter
|
|
50
|
+
});
|
|
51
|
+
//# sourceMappingURL=drizzle.cjs.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\";\n\n/**\n * Creates a Drizzle ORM adapter.\n * \n * Works with any Drizzle-supported database (PostgreSQL, MySQL, SQLite)\n * by using the standard drizzle-orm `db` instance and table definition.\n * \n * @param db - The Drizzle database instance.\n * @param table - The Drizzle table representing users.\n * @param eq - The Drizzle `eq` operator (imported from `drizzle-orm`).\n * @returns An AuthAdapter compliant object.\n */\nexport function createDrizzleAdapter<TUser extends User = User>(\n db: any,\n table: any,\n eq: any\n): AuthAdapter<TUser> {\n return {\n async createUser(data: any) {\n const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };\n const results = await db.insert(table).values(dataToSave).returning();\n return results[0] as TUser;\n },\n\n async findUserByEmail(email: string) {\n const results = await db.select().from(table).where(eq(table.email, email)).limit(1);\n return (results[0] || null) as TUser | null;\n },\n\n async findUserById(id: string) {\n const results = await db.select().from(table).where(eq(table.id, id)).limit(1);\n return (results[0] || null) as TUser | null;\n },\n\n async linkOAuthAccount(userId: string, provider: string, providerId: string) {\n await db.update(table)\n .set({\n oauthProvider: provider,\n oauthId: providerId,\n })\n .where(eq(table.id, userId));\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaO,SAAS,qBACd,IACA,OACA,IACoB;AACpB,SAAO;AAAA,IACL,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,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;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AuthAdapter, User } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a Drizzle ORM adapter.
|
|
4
|
+
*
|
|
5
|
+
* Works with any Drizzle-supported database (PostgreSQL, MySQL, SQLite)
|
|
6
|
+
* by using the standard drizzle-orm `db` instance and table definition.
|
|
7
|
+
*
|
|
8
|
+
* @param db - The Drizzle database instance.
|
|
9
|
+
* @param table - The Drizzle table representing users.
|
|
10
|
+
* @param eq - The Drizzle `eq` operator (imported from `drizzle-orm`).
|
|
11
|
+
* @returns An AuthAdapter compliant object.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createDrizzleAdapter<TUser extends User = User>(db: any, table: any, eq: any): AuthAdapter<TUser>;
|
|
14
|
+
//# sourceMappingURL=drizzle.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function createDrizzleAdapter(db, table, eq) {
|
|
2
|
+
return {
|
|
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 linkOAuthAccount(userId, provider, providerId) {
|
|
17
|
+
await db.update(table).set({
|
|
18
|
+
oauthProvider: provider,
|
|
19
|
+
oauthId: providerId
|
|
20
|
+
}).where(eq(table.id, userId));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
createDrizzleAdapter
|
|
26
|
+
};
|
|
27
|
+
//# 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\";\n\n/**\n * Creates a Drizzle ORM adapter.\n * \n * Works with any Drizzle-supported database (PostgreSQL, MySQL, SQLite)\n * by using the standard drizzle-orm `db` instance and table definition.\n * \n * @param db - The Drizzle database instance.\n * @param table - The Drizzle table representing users.\n * @param eq - The Drizzle `eq` operator (imported from `drizzle-orm`).\n * @returns An AuthAdapter compliant object.\n */\nexport function createDrizzleAdapter<TUser extends User = User>(\n db: any,\n table: any,\n eq: any\n): AuthAdapter<TUser> {\n return {\n async createUser(data: any) {\n const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };\n const results = await db.insert(table).values(dataToSave).returning();\n return results[0] as TUser;\n },\n\n async findUserByEmail(email: string) {\n const results = await db.select().from(table).where(eq(table.email, email)).limit(1);\n return (results[0] || null) as TUser | null;\n },\n\n async findUserById(id: string) {\n const results = await db.select().from(table).where(eq(table.id, id)).limit(1);\n return (results[0] || null) as TUser | null;\n },\n\n async linkOAuthAccount(userId: string, provider: string, providerId: string) {\n await db.update(table)\n .set({\n oauthProvider: provider,\n oauthId: providerId,\n })\n .where(eq(table.id, userId));\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAaO,SAAS,qBACd,IACA,OACA,IACoB;AACpB,SAAO;AAAA,IACL,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,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;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var prisma_exports = {};
|
|
20
|
+
__export(prisma_exports, {
|
|
21
|
+
createPrismaAdapter: () => createPrismaAdapter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(prisma_exports);
|
|
24
|
+
function createPrismaAdapter(model) {
|
|
25
|
+
return {
|
|
26
|
+
async createUser(data) {
|
|
27
|
+
const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };
|
|
28
|
+
const user = await model.create({ data: dataToSave });
|
|
29
|
+
return user;
|
|
30
|
+
},
|
|
31
|
+
async findUserByEmail(email) {
|
|
32
|
+
const user = await model.findUnique({
|
|
33
|
+
where: { email }
|
|
34
|
+
});
|
|
35
|
+
return user;
|
|
36
|
+
},
|
|
37
|
+
async findUserById(id) {
|
|
38
|
+
const user = await model.findUnique({
|
|
39
|
+
where: { id }
|
|
40
|
+
});
|
|
41
|
+
return user;
|
|
42
|
+
},
|
|
43
|
+
async linkOAuthAccount(userId, provider, providerId) {
|
|
44
|
+
await model.update({
|
|
45
|
+
where: { id: userId },
|
|
46
|
+
data: {
|
|
47
|
+
oauthProvider: provider,
|
|
48
|
+
oauthId: providerId
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
55
|
+
0 && (module.exports = {
|
|
56
|
+
createPrismaAdapter
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=prisma.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/auth/adapters/prisma.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AuthAdapter, User } from \"./index.js\";\n\n/**\n * Creates a Prisma adapter using a Prisma delegate (e.g., prisma.user).\n * \n * Works with any Prisma-supported database by using the standard\n * Prisma delegate operations (findUnique, create, update).\n * \n * @param model - A Prisma delegate instance (e.g., prisma.user).\n * @returns An AuthAdapter compliant object.\n */\nexport function createPrismaAdapter<TUser extends User = User>(model: any): AuthAdapter<TUser> {\n return {\n async createUser(data: any) {\n const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };\n const user = await model.create({ data: dataToSave });\n return user as TUser;\n },\n\n async findUserByEmail(email: string) {\n const user = await model.findUnique({\n where: { email },\n });\n return user as TUser | null;\n },\n\n async findUserById(id: string) {\n const user = await model.findUnique({\n where: { id },\n });\n return user as TUser | null;\n },\n\n async linkOAuthAccount(userId: string, provider: string, providerId: string) {\n await model.update({\n where: { id: userId },\n data: {\n oauthProvider: provider,\n oauthId: providerId,\n },\n });\n },\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,SAAS,oBAA+C,OAAgC;AAC7F,SAAO;AAAA,IACL,MAAM,WAAW,MAAW;AAC1B,YAAM,aAAa,EAAE,IAAI,KAAK,MAAM,WAAW,OAAO,WAAW,GAAG,GAAG,KAAK;AAC5E,YAAM,OAAO,MAAM,MAAM,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,gBAAgB,OAAe;AACnC,YAAM,OAAO,MAAM,MAAM,WAAW;AAAA,QAClC,OAAO,EAAE,MAAM;AAAA,MACjB,CAAC;AACD,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,aAAa,IAAY;AAC7B,YAAM,OAAO,MAAM,MAAM,WAAW;AAAA,QAClC,OAAO,EAAE,GAAG;AAAA,MACd,CAAC;AACD,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,iBAAiB,QAAgB,UAAkB,YAAoB;AAC3E,YAAM,MAAM,OAAO;AAAA,QACjB,OAAO,EAAE,IAAI,OAAO;AAAA,QACpB,MAAM;AAAA,UACJ,eAAe;AAAA,UACf,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AuthAdapter, User } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a Prisma adapter using a Prisma delegate (e.g., prisma.user).
|
|
4
|
+
*
|
|
5
|
+
* Works with any Prisma-supported database by using the standard
|
|
6
|
+
* Prisma delegate operations (findUnique, create, update).
|
|
7
|
+
*
|
|
8
|
+
* @param model - A Prisma delegate instance (e.g., prisma.user).
|
|
9
|
+
* @returns An AuthAdapter compliant object.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createPrismaAdapter<TUser extends User = User>(model: any): AuthAdapter<TUser>;
|
|
12
|
+
//# sourceMappingURL=prisma.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function createPrismaAdapter(model) {
|
|
2
|
+
return {
|
|
3
|
+
async createUser(data) {
|
|
4
|
+
const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };
|
|
5
|
+
const user = await model.create({ data: dataToSave });
|
|
6
|
+
return user;
|
|
7
|
+
},
|
|
8
|
+
async findUserByEmail(email) {
|
|
9
|
+
const user = await model.findUnique({
|
|
10
|
+
where: { email }
|
|
11
|
+
});
|
|
12
|
+
return user;
|
|
13
|
+
},
|
|
14
|
+
async findUserById(id) {
|
|
15
|
+
const user = await model.findUnique({
|
|
16
|
+
where: { id }
|
|
17
|
+
});
|
|
18
|
+
return user;
|
|
19
|
+
},
|
|
20
|
+
async linkOAuthAccount(userId, provider, providerId) {
|
|
21
|
+
await model.update({
|
|
22
|
+
where: { id: userId },
|
|
23
|
+
data: {
|
|
24
|
+
oauthProvider: provider,
|
|
25
|
+
oauthId: providerId
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
createPrismaAdapter
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=prisma.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/auth/adapters/prisma.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AuthAdapter, User } from \"./index.js\";\n\n/**\n * Creates a Prisma adapter using a Prisma delegate (e.g., prisma.user).\n * \n * Works with any Prisma-supported database by using the standard\n * Prisma delegate operations (findUnique, create, update).\n * \n * @param model - A Prisma delegate instance (e.g., prisma.user).\n * @returns An AuthAdapter compliant object.\n */\nexport function createPrismaAdapter<TUser extends User = User>(model: any): AuthAdapter<TUser> {\n return {\n async createUser(data: any) {\n const dataToSave = { id: data.id || globalThis.crypto.randomUUID(), ...data };\n const user = await model.create({ data: dataToSave });\n return user as TUser;\n },\n\n async findUserByEmail(email: string) {\n const user = await model.findUnique({\n where: { email },\n });\n return user as TUser | null;\n },\n\n async findUserById(id: string) {\n const user = await model.findUnique({\n where: { id },\n });\n return user as TUser | null;\n },\n\n async linkOAuthAccount(userId: string, provider: string, providerId: string) {\n await model.update({\n where: { id: userId },\n data: {\n oauthProvider: provider,\n oauthId: providerId,\n },\n });\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAWO,SAAS,oBAA+C,OAAgC;AAC7F,SAAO;AAAA,IACL,MAAM,WAAW,MAAW;AAC1B,YAAM,aAAa,EAAE,IAAI,KAAK,MAAM,WAAW,OAAO,WAAW,GAAG,GAAG,KAAK;AAC5E,YAAM,OAAO,MAAM,MAAM,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,gBAAgB,OAAe;AACnC,YAAM,OAAO,MAAM,MAAM,WAAW;AAAA,QAClC,OAAO,EAAE,MAAM;AAAA,MACjB,CAAC;AACD,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,aAAa,IAAY;AAC7B,YAAM,OAAO,MAAM,MAAM,WAAW;AAAA,QAClC,OAAO,EAAE,GAAG;AAAA,MACd,CAAC;AACD,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,iBAAiB,QAAgB,UAAkB,YAAoB;AAC3E,YAAM,MAAM,OAAO;AAAA,QACjB,OAAO,EAAE,IAAI,OAAO;AAAA,QACpB,MAAM;AAAA,UACJ,eAAe;AAAA,UACf,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kroxt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"auth",
|
|
6
6
|
"authentication",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"hono",
|
|
17
17
|
"express",
|
|
18
18
|
"prisma-adapter",
|
|
19
|
+
"drizzle-adapter",
|
|
19
20
|
"mongoose-adapter"
|
|
20
21
|
],
|
|
21
22
|
"license": "MIT",
|
|
@@ -55,6 +56,16 @@
|
|
|
55
56
|
"import": "./dist/adapters/mongoose.js",
|
|
56
57
|
"require": "./dist/adapters/mongoose.cjs"
|
|
57
58
|
},
|
|
59
|
+
"./adapters/drizzle": {
|
|
60
|
+
"types": "./dist/adapters/drizzle.d.ts",
|
|
61
|
+
"import": "./dist/adapters/drizzle.js",
|
|
62
|
+
"require": "./dist/adapters/drizzle.cjs"
|
|
63
|
+
},
|
|
64
|
+
"./adapters/prisma": {
|
|
65
|
+
"types": "./dist/adapters/prisma.d.ts",
|
|
66
|
+
"import": "./dist/adapters/prisma.js",
|
|
67
|
+
"require": "./dist/adapters/prisma.cjs"
|
|
68
|
+
},
|
|
58
69
|
"./security": {
|
|
59
70
|
"types": "./dist/security/index.d.ts",
|
|
60
71
|
"import": "./dist/security/index.js",
|