next-lite-auth 0.1.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/LICENSE +21 -0
- package/README.md +219 -0
- package/dist/client.d.mts +30 -0
- package/dist/client.d.ts +30 -0
- package/dist/client.js +63 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +36 -0
- package/dist/client.mjs.map +1 -0
- package/dist/index.d.mts +30 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +158 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +131 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 aminuddin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# next-lite-auth
|
|
2
|
+
|
|
3
|
+
Lightweight JWT auth for Next.js using static JSON users — no database required.
|
|
4
|
+
|
|
5
|
+
> **Not for production.** Designed for demos, OSS projects, internal tools, and quick Vercel deployments.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- Node.js >= 20
|
|
12
|
+
- Next.js >= 13
|
|
13
|
+
- React >= 18
|
|
14
|
+
- TypeScript
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add next-lite-auth jose
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
### 1. Create your auth instance
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// lib/auth.ts
|
|
32
|
+
import { createLiteAuth } from "next-lite-auth";
|
|
33
|
+
|
|
34
|
+
export const auth = createLiteAuth({
|
|
35
|
+
users: [
|
|
36
|
+
{ email: "admin@example.com", password: "secret", role: "admin", name: "Admin" },
|
|
37
|
+
{ email: "user@example.com", password: "pass123", role: "user", name: "User" },
|
|
38
|
+
],
|
|
39
|
+
jwtSecret: process.env.JWT_SECRET!,
|
|
40
|
+
cookieName: "lite-auth-token", // optional, this is the default
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Add route handlers
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// app/api/auth/login/route.ts
|
|
48
|
+
import { auth } from "@/lib/auth";
|
|
49
|
+
export const POST = auth.handlers.login;
|
|
50
|
+
|
|
51
|
+
// app/api/auth/logout/route.ts
|
|
52
|
+
import { auth } from "@/lib/auth";
|
|
53
|
+
export const POST = auth.handlers.logout;
|
|
54
|
+
|
|
55
|
+
// app/api/auth/me/route.ts
|
|
56
|
+
import { auth } from "@/lib/auth";
|
|
57
|
+
export const GET = auth.handlers.me;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Add middleware
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// middleware.ts
|
|
64
|
+
import { auth } from "@/lib/auth";
|
|
65
|
+
|
|
66
|
+
export default auth.middleware({
|
|
67
|
+
protect: ["/dashboard", "/settings"],
|
|
68
|
+
redirectTo: "/login", // optional, default is "/login"
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const config = {
|
|
72
|
+
matcher: ["/((?!_next|api/auth).*)"],
|
|
73
|
+
};
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 4. Use on the client
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
"use client";
|
|
80
|
+
|
|
81
|
+
import { useLiteAuth } from "next-lite-auth/client";
|
|
82
|
+
|
|
83
|
+
export default function LoginPage() {
|
|
84
|
+
const { user, loading, login, logout } = useLiteAuth();
|
|
85
|
+
|
|
86
|
+
if (loading) return <p>Loading...</p>;
|
|
87
|
+
|
|
88
|
+
if (user) {
|
|
89
|
+
return (
|
|
90
|
+
<div>
|
|
91
|
+
<p>Hello, {user.name ?? user.email}</p>
|
|
92
|
+
<button onClick={logout}>Logout</button>
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<form
|
|
99
|
+
onSubmit={async (e) => {
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
const form = e.currentTarget;
|
|
102
|
+
const result = await login({
|
|
103
|
+
email: form.email.value,
|
|
104
|
+
password: form.password.value,
|
|
105
|
+
});
|
|
106
|
+
if (result.error) alert(result.error);
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
<input name="email" type="email" placeholder="Email" />
|
|
110
|
+
<input name="password" type="password" placeholder="Password" />
|
|
111
|
+
<button type="submit">Login</button>
|
|
112
|
+
</form>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 5. Read user on the server
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
// app/dashboard/page.tsx
|
|
121
|
+
import { cookies } from "next/headers";
|
|
122
|
+
import { auth } from "@/lib/auth";
|
|
123
|
+
|
|
124
|
+
export default async function DashboardPage() {
|
|
125
|
+
const user = await auth.getUserFromCookies(cookies());
|
|
126
|
+
return <p>Welcome, {user?.name}</p>;
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## API Reference
|
|
133
|
+
|
|
134
|
+
### `createLiteAuth(config)`
|
|
135
|
+
|
|
136
|
+
| Option | Type | Required | Description |
|
|
137
|
+
|---|---|---|---|
|
|
138
|
+
| `users` | `User[]` | Yes | Hardcoded list of users |
|
|
139
|
+
| `jwtSecret` | `string` | Yes | Secret used to sign JWTs |
|
|
140
|
+
| `cookieName` | `string` | No | Cookie name (default: `"lite-auth-token"`) |
|
|
141
|
+
|
|
142
|
+
Returns `{ handlers, middleware, getUserFromCookies }`.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### `User` type
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
type User = {
|
|
150
|
+
email: string;
|
|
151
|
+
password: string;
|
|
152
|
+
role?: string;
|
|
153
|
+
name?: string;
|
|
154
|
+
};
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### `auth.handlers`
|
|
160
|
+
|
|
161
|
+
| Handler | Method | Route |
|
|
162
|
+
|---|---|---|
|
|
163
|
+
| `login` | POST | `/api/auth/login` |
|
|
164
|
+
| `logout` | POST | `/api/auth/logout` |
|
|
165
|
+
| `me` | GET | `/api/auth/me` |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### `auth.middleware(options)`
|
|
170
|
+
|
|
171
|
+
| Option | Type | Default | Description |
|
|
172
|
+
|---|---|---|---|
|
|
173
|
+
| `protect` | `string[]` | — | Route prefixes to protect |
|
|
174
|
+
| `redirectTo` | `string` | `"/login"` | Where to redirect unauthenticated users |
|
|
175
|
+
|
|
176
|
+
Appends `?from=<pathname>` to the redirect URL.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### `auth.getUserFromCookies(cookies)`
|
|
181
|
+
|
|
182
|
+
Server-side helper. Accepts Next.js `cookies()` and returns the current `PublicUser` or `null`.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### `useLiteAuth(options?)`
|
|
187
|
+
|
|
188
|
+
Client hook. Fetches `/api/auth/me` on mount.
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
const { user, loading, login, logout } = useLiteAuth({
|
|
192
|
+
loginPath: "/api/auth/login", // optional
|
|
193
|
+
logoutPath: "/api/auth/logout", // optional
|
|
194
|
+
mePath: "/api/auth/me", // optional
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
| Return | Type | Description |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| `user` | `PublicUser \| null` | Current authenticated user |
|
|
201
|
+
| `loading` | `boolean` | True while fetching session |
|
|
202
|
+
| `login(creds)` | `Promise<{ error?: string }>` | Logs in and sets user state |
|
|
203
|
+
| `logout()` | `Promise<void>` | Clears cookie and user state |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Non-Goals
|
|
208
|
+
|
|
209
|
+
- OAuth / social login
|
|
210
|
+
- Signup / registration
|
|
211
|
+
- Password reset
|
|
212
|
+
- Role-based access control
|
|
213
|
+
- Production-grade security
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type User = {
|
|
2
|
+
email: string;
|
|
3
|
+
password: string;
|
|
4
|
+
role?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
};
|
|
7
|
+
type PublicUser = Omit<User, "password">;
|
|
8
|
+
|
|
9
|
+
type LiteAuthState = {
|
|
10
|
+
user: PublicUser | null;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
};
|
|
13
|
+
type LoginCredentials = {
|
|
14
|
+
email: string;
|
|
15
|
+
password: string;
|
|
16
|
+
};
|
|
17
|
+
type UseLiteAuthReturn = LiteAuthState & {
|
|
18
|
+
login: (credentials: LoginCredentials) => Promise<{
|
|
19
|
+
error?: string;
|
|
20
|
+
}>;
|
|
21
|
+
logout: () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
type UseLiteAuthOptions = {
|
|
24
|
+
loginPath?: string;
|
|
25
|
+
logoutPath?: string;
|
|
26
|
+
mePath?: string;
|
|
27
|
+
};
|
|
28
|
+
declare function useLiteAuth(options?: UseLiteAuthOptions): UseLiteAuthReturn;
|
|
29
|
+
|
|
30
|
+
export { useLiteAuth };
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type User = {
|
|
2
|
+
email: string;
|
|
3
|
+
password: string;
|
|
4
|
+
role?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
};
|
|
7
|
+
type PublicUser = Omit<User, "password">;
|
|
8
|
+
|
|
9
|
+
type LiteAuthState = {
|
|
10
|
+
user: PublicUser | null;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
};
|
|
13
|
+
type LoginCredentials = {
|
|
14
|
+
email: string;
|
|
15
|
+
password: string;
|
|
16
|
+
};
|
|
17
|
+
type UseLiteAuthReturn = LiteAuthState & {
|
|
18
|
+
login: (credentials: LoginCredentials) => Promise<{
|
|
19
|
+
error?: string;
|
|
20
|
+
}>;
|
|
21
|
+
logout: () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
type UseLiteAuthOptions = {
|
|
24
|
+
loginPath?: string;
|
|
25
|
+
logoutPath?: string;
|
|
26
|
+
mePath?: string;
|
|
27
|
+
};
|
|
28
|
+
declare function useLiteAuth(options?: UseLiteAuthOptions): UseLiteAuthReturn;
|
|
29
|
+
|
|
30
|
+
export { useLiteAuth };
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
|
|
20
|
+
// src/client/index.ts
|
|
21
|
+
var client_exports = {};
|
|
22
|
+
__export(client_exports, {
|
|
23
|
+
useLiteAuth: () => useLiteAuth
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(client_exports);
|
|
26
|
+
|
|
27
|
+
// src/client/useLiteAuth.ts
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
function useLiteAuth(options = {}) {
|
|
30
|
+
const {
|
|
31
|
+
loginPath = "/api/auth/login",
|
|
32
|
+
logoutPath = "/api/auth/logout",
|
|
33
|
+
mePath = "/api/auth/me"
|
|
34
|
+
} = options;
|
|
35
|
+
const [state, setState] = (0, import_react.useState)({ user: null, loading: true });
|
|
36
|
+
(0, import_react.useEffect)(() => {
|
|
37
|
+
fetch(mePath).then((r) => r.json()).then(({ user }) => setState({ user: user ?? null, loading: false })).catch(() => setState({ user: null, loading: false }));
|
|
38
|
+
}, [mePath]);
|
|
39
|
+
const login = (0, import_react.useCallback)(
|
|
40
|
+
async ({ email, password }) => {
|
|
41
|
+
const res = await fetch(loginPath, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: { "Content-Type": "application/json" },
|
|
44
|
+
body: JSON.stringify({ email, password })
|
|
45
|
+
});
|
|
46
|
+
const data = await res.json();
|
|
47
|
+
if (!res.ok) return { error: data.error ?? "Login failed" };
|
|
48
|
+
setState({ user: data.user, loading: false });
|
|
49
|
+
return {};
|
|
50
|
+
},
|
|
51
|
+
[loginPath]
|
|
52
|
+
);
|
|
53
|
+
const logout = (0, import_react.useCallback)(async () => {
|
|
54
|
+
await fetch(logoutPath, { method: "POST" });
|
|
55
|
+
setState({ user: null, loading: false });
|
|
56
|
+
}, [logoutPath]);
|
|
57
|
+
return { ...state, login, logout };
|
|
58
|
+
}
|
|
59
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
60
|
+
0 && (module.exports = {
|
|
61
|
+
useLiteAuth
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/index.ts","../src/client/useLiteAuth.ts"],"sourcesContent":["export { useLiteAuth } from \"./useLiteAuth\";\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { PublicUser } from \"../core/types\";\n\ntype LiteAuthState = {\n user: PublicUser | null;\n loading: boolean;\n};\n\ntype LoginCredentials = {\n email: string;\n password: string;\n};\n\ntype UseLiteAuthReturn = LiteAuthState & {\n login: (credentials: LoginCredentials) => Promise<{ error?: string }>;\n logout: () => Promise<void>;\n};\n\ntype UseLiteAuthOptions = {\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function useLiteAuth(options: UseLiteAuthOptions = {}): UseLiteAuthReturn {\n const {\n loginPath = \"/api/auth/login\",\n logoutPath = \"/api/auth/logout\",\n mePath = \"/api/auth/me\",\n } = options;\n\n const [state, setState] = useState<LiteAuthState>({ user: null, loading: true });\n\n useEffect(() => {\n fetch(mePath)\n .then((r) => r.json())\n .then(({ user }) => setState({ user: user ?? null, loading: false }))\n .catch(() => setState({ user: null, loading: false }));\n }, [mePath]);\n\n const login = useCallback(\n async ({ email, password }: LoginCredentials) => {\n const res = await fetch(loginPath, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email, password }),\n });\n const data = await res.json();\n if (!res.ok) return { error: data.error ?? \"Login failed\" };\n setState({ user: data.user, loading: false });\n return {};\n },\n [loginPath]\n );\n\n const logout = useCallback(async () => {\n await fetch(logoutPath, { method: \"POST\" });\n setState({ user: null, loading: false });\n }, [logoutPath]);\n\n return { ...state, login, logout };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,mBAAiD;AAwB1C,SAAS,YAAY,UAA8B,CAAC,GAAsB;AAC/E,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,SAAS;AAAA,EACX,IAAI;AAEJ,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAwB,EAAE,MAAM,MAAM,SAAS,KAAK,CAAC;AAE/E,8BAAU,MAAM;AACd,UAAM,MAAM,EACT,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EACpB,KAAK,CAAC,EAAE,KAAK,MAAM,SAAS,EAAE,MAAM,QAAQ,MAAM,SAAS,MAAM,CAAC,CAAC,EACnE,MAAM,MAAM,SAAS,EAAE,MAAM,MAAM,SAAS,MAAM,CAAC,CAAC;AAAA,EACzD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,YAAQ;AAAA,IACZ,OAAO,EAAE,OAAO,SAAS,MAAwB;AAC/C,YAAM,MAAM,MAAM,MAAM,WAAW;AAAA,QACjC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,MAC1C,CAAC;AACD,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI,CAAC,IAAI,GAAI,QAAO,EAAE,OAAO,KAAK,SAAS,eAAe;AAC1D,eAAS,EAAE,MAAM,KAAK,MAAM,SAAS,MAAM,CAAC;AAC5C,aAAO,CAAC;AAAA,IACV;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,aAAS,0BAAY,YAAY;AACrC,UAAM,MAAM,YAAY,EAAE,QAAQ,OAAO,CAAC;AAC1C,aAAS,EAAE,MAAM,MAAM,SAAS,MAAM,CAAC;AAAA,EACzC,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO,EAAE,GAAG,OAAO,OAAO,OAAO;AACnC;","names":[]}
|
package/dist/client.mjs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// src/client/useLiteAuth.ts
|
|
2
|
+
import { useState, useEffect, useCallback } from "react";
|
|
3
|
+
function useLiteAuth(options = {}) {
|
|
4
|
+
const {
|
|
5
|
+
loginPath = "/api/auth/login",
|
|
6
|
+
logoutPath = "/api/auth/logout",
|
|
7
|
+
mePath = "/api/auth/me"
|
|
8
|
+
} = options;
|
|
9
|
+
const [state, setState] = useState({ user: null, loading: true });
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
fetch(mePath).then((r) => r.json()).then(({ user }) => setState({ user: user ?? null, loading: false })).catch(() => setState({ user: null, loading: false }));
|
|
12
|
+
}, [mePath]);
|
|
13
|
+
const login = useCallback(
|
|
14
|
+
async ({ email, password }) => {
|
|
15
|
+
const res = await fetch(loginPath, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: { "Content-Type": "application/json" },
|
|
18
|
+
body: JSON.stringify({ email, password })
|
|
19
|
+
});
|
|
20
|
+
const data = await res.json();
|
|
21
|
+
if (!res.ok) return { error: data.error ?? "Login failed" };
|
|
22
|
+
setState({ user: data.user, loading: false });
|
|
23
|
+
return {};
|
|
24
|
+
},
|
|
25
|
+
[loginPath]
|
|
26
|
+
);
|
|
27
|
+
const logout = useCallback(async () => {
|
|
28
|
+
await fetch(logoutPath, { method: "POST" });
|
|
29
|
+
setState({ user: null, loading: false });
|
|
30
|
+
}, [logoutPath]);
|
|
31
|
+
return { ...state, login, logout };
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
useLiteAuth
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/useLiteAuth.ts"],"sourcesContent":["\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { PublicUser } from \"../core/types\";\n\ntype LiteAuthState = {\n user: PublicUser | null;\n loading: boolean;\n};\n\ntype LoginCredentials = {\n email: string;\n password: string;\n};\n\ntype UseLiteAuthReturn = LiteAuthState & {\n login: (credentials: LoginCredentials) => Promise<{ error?: string }>;\n logout: () => Promise<void>;\n};\n\ntype UseLiteAuthOptions = {\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function useLiteAuth(options: UseLiteAuthOptions = {}): UseLiteAuthReturn {\n const {\n loginPath = \"/api/auth/login\",\n logoutPath = \"/api/auth/logout\",\n mePath = \"/api/auth/me\",\n } = options;\n\n const [state, setState] = useState<LiteAuthState>({ user: null, loading: true });\n\n useEffect(() => {\n fetch(mePath)\n .then((r) => r.json())\n .then(({ user }) => setState({ user: user ?? null, loading: false }))\n .catch(() => setState({ user: null, loading: false }));\n }, [mePath]);\n\n const login = useCallback(\n async ({ email, password }: LoginCredentials) => {\n const res = await fetch(loginPath, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email, password }),\n });\n const data = await res.json();\n if (!res.ok) return { error: data.error ?? \"Login failed\" };\n setState({ user: data.user, loading: false });\n return {};\n },\n [loginPath]\n );\n\n const logout = useCallback(async () => {\n await fetch(logoutPath, { method: \"POST\" });\n setState({ user: null, loading: false });\n }, [logoutPath]);\n\n return { ...state, login, logout };\n}\n"],"mappings":";AAEA,SAAS,UAAU,WAAW,mBAAmB;AAwB1C,SAAS,YAAY,UAA8B,CAAC,GAAsB;AAC/E,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,SAAS;AAAA,EACX,IAAI;AAEJ,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,EAAE,MAAM,MAAM,SAAS,KAAK,CAAC;AAE/E,YAAU,MAAM;AACd,UAAM,MAAM,EACT,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EACpB,KAAK,CAAC,EAAE,KAAK,MAAM,SAAS,EAAE,MAAM,QAAQ,MAAM,SAAS,MAAM,CAAC,CAAC,EACnE,MAAM,MAAM,SAAS,EAAE,MAAM,MAAM,SAAS,MAAM,CAAC,CAAC;AAAA,EACzD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,QAAQ;AAAA,IACZ,OAAO,EAAE,OAAO,SAAS,MAAwB;AAC/C,YAAM,MAAM,MAAM,MAAM,WAAW;AAAA,QACjC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,MAC1C,CAAC;AACD,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI,CAAC,IAAI,GAAI,QAAO,EAAE,OAAO,KAAK,SAAS,eAAe;AAC1D,eAAS,EAAE,MAAM,KAAK,MAAM,SAAS,MAAM,CAAC;AAC5C,aAAO,CAAC;AAAA,IACV;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,SAAS,YAAY,YAAY;AACrC,UAAM,MAAM,YAAY,EAAE,QAAQ,OAAO,CAAC;AAC1C,aAAS,EAAE,MAAM,MAAM,SAAS,MAAM,CAAC;AAAA,EACzC,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO,EAAE,GAAG,OAAO,OAAO,OAAO;AACnC;","names":[]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as next_dist_server_web_spec_extension_adapters_request_cookies from 'next/dist/server/web/spec-extension/adapters/request-cookies';
|
|
2
|
+
import * as next_server from 'next/server';
|
|
3
|
+
|
|
4
|
+
type User = {
|
|
5
|
+
email: string;
|
|
6
|
+
password: string;
|
|
7
|
+
role?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
};
|
|
10
|
+
type PublicUser = Omit<User, "password">;
|
|
11
|
+
type LiteAuthConfig = {
|
|
12
|
+
users: User[];
|
|
13
|
+
jwtSecret: string;
|
|
14
|
+
cookieName?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare function createLiteAuth(config: LiteAuthConfig): {
|
|
18
|
+
handlers: {
|
|
19
|
+
login: (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
20
|
+
logout: (_req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
21
|
+
me: (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
22
|
+
};
|
|
23
|
+
middleware: (options: {
|
|
24
|
+
protect: string[];
|
|
25
|
+
redirectTo?: string;
|
|
26
|
+
}) => (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
27
|
+
getUserFromCookies: (cookies: next_dist_server_web_spec_extension_adapters_request_cookies.ReadonlyRequestCookies) => Promise<PublicUser | null>;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { type LiteAuthConfig, type PublicUser, type User, createLiteAuth };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as next_dist_server_web_spec_extension_adapters_request_cookies from 'next/dist/server/web/spec-extension/adapters/request-cookies';
|
|
2
|
+
import * as next_server from 'next/server';
|
|
3
|
+
|
|
4
|
+
type User = {
|
|
5
|
+
email: string;
|
|
6
|
+
password: string;
|
|
7
|
+
role?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
};
|
|
10
|
+
type PublicUser = Omit<User, "password">;
|
|
11
|
+
type LiteAuthConfig = {
|
|
12
|
+
users: User[];
|
|
13
|
+
jwtSecret: string;
|
|
14
|
+
cookieName?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare function createLiteAuth(config: LiteAuthConfig): {
|
|
18
|
+
handlers: {
|
|
19
|
+
login: (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
20
|
+
logout: (_req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
21
|
+
me: (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
22
|
+
};
|
|
23
|
+
middleware: (options: {
|
|
24
|
+
protect: string[];
|
|
25
|
+
redirectTo?: string;
|
|
26
|
+
}) => (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
|
|
27
|
+
getUserFromCookies: (cookies: next_dist_server_web_spec_extension_adapters_request_cookies.ReadonlyRequestCookies) => Promise<PublicUser | null>;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { type LiteAuthConfig, type PublicUser, type User, createLiteAuth };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
createLiteAuth: () => createLiteAuth
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
|
|
27
|
+
// src/server/handlers.ts
|
|
28
|
+
var import_server = require("next/server");
|
|
29
|
+
|
|
30
|
+
// src/server/jwt.ts
|
|
31
|
+
var import_jose = require("jose");
|
|
32
|
+
function getSecret(secret) {
|
|
33
|
+
return new TextEncoder().encode(secret);
|
|
34
|
+
}
|
|
35
|
+
async function signToken(user, secret) {
|
|
36
|
+
return new import_jose.SignJWT({ ...user }).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime("7d").sign(getSecret(secret));
|
|
37
|
+
}
|
|
38
|
+
async function verifyToken(token, secret) {
|
|
39
|
+
try {
|
|
40
|
+
const { payload } = await (0, import_jose.jwtVerify)(token, getSecret(secret));
|
|
41
|
+
return payload;
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/server/handlers.ts
|
|
48
|
+
function makeLoginHandler(ctx) {
|
|
49
|
+
return async function loginHandler(req) {
|
|
50
|
+
let body;
|
|
51
|
+
try {
|
|
52
|
+
body = await req.json();
|
|
53
|
+
} catch {
|
|
54
|
+
return import_server.NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
|
55
|
+
}
|
|
56
|
+
const { email, password } = body;
|
|
57
|
+
if (!email || !password) {
|
|
58
|
+
return import_server.NextResponse.json({ error: "Email and password are required" }, { status: 400 });
|
|
59
|
+
}
|
|
60
|
+
const user = ctx.users.find((u) => u.email === email && u.password === password);
|
|
61
|
+
if (!user) {
|
|
62
|
+
return import_server.NextResponse.json({ error: "Invalid credentials" }, { status: 401 });
|
|
63
|
+
}
|
|
64
|
+
const { password: _, ...publicUser } = user;
|
|
65
|
+
const token = await signToken(publicUser, ctx.jwtSecret);
|
|
66
|
+
const res = import_server.NextResponse.json({ user: publicUser });
|
|
67
|
+
res.cookies.set(ctx.cookieName, token, {
|
|
68
|
+
httpOnly: true,
|
|
69
|
+
path: "/",
|
|
70
|
+
sameSite: "lax",
|
|
71
|
+
secure: process.env.NODE_ENV === "production",
|
|
72
|
+
maxAge: 60 * 60 * 24 * 7
|
|
73
|
+
// 7 days
|
|
74
|
+
});
|
|
75
|
+
return res;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function makeLogoutHandler(ctx) {
|
|
79
|
+
return async function logoutHandler(_req) {
|
|
80
|
+
const res = import_server.NextResponse.json({ ok: true });
|
|
81
|
+
res.cookies.set(ctx.cookieName, "", {
|
|
82
|
+
httpOnly: true,
|
|
83
|
+
path: "/",
|
|
84
|
+
maxAge: 0
|
|
85
|
+
});
|
|
86
|
+
return res;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function makeMeHandler(ctx) {
|
|
90
|
+
return async function meHandler(req) {
|
|
91
|
+
const token = req.cookies.get(ctx.cookieName)?.value;
|
|
92
|
+
if (!token) {
|
|
93
|
+
return import_server.NextResponse.json({ user: null }, { status: 401 });
|
|
94
|
+
}
|
|
95
|
+
const user = await verifyToken(token, ctx.jwtSecret);
|
|
96
|
+
if (!user) {
|
|
97
|
+
return import_server.NextResponse.json({ user: null }, { status: 401 });
|
|
98
|
+
}
|
|
99
|
+
return import_server.NextResponse.json({ user });
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/server/getUserFromCookies.ts
|
|
104
|
+
function getUserFromCookies(ctx) {
|
|
105
|
+
return async function(cookies) {
|
|
106
|
+
const token = cookies.get(ctx.cookieName)?.value;
|
|
107
|
+
if (!token) return null;
|
|
108
|
+
return verifyToken(token, ctx.jwtSecret);
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/middleware/index.ts
|
|
113
|
+
var import_server2 = require("next/server");
|
|
114
|
+
function makeMiddleware(ctx) {
|
|
115
|
+
return function middleware(options) {
|
|
116
|
+
return async function(req) {
|
|
117
|
+
const { protect, redirectTo = "/login" } = options;
|
|
118
|
+
const { pathname } = req.nextUrl;
|
|
119
|
+
const isProtected = protect.some(
|
|
120
|
+
(pattern) => pathname === pattern || pathname.startsWith(pattern + "/")
|
|
121
|
+
);
|
|
122
|
+
if (!isProtected) {
|
|
123
|
+
return import_server2.NextResponse.next();
|
|
124
|
+
}
|
|
125
|
+
const token = req.cookies.get(ctx.cookieName)?.value;
|
|
126
|
+
if (token) {
|
|
127
|
+
const user = await verifyToken(token, ctx.jwtSecret);
|
|
128
|
+
if (user) return import_server2.NextResponse.next();
|
|
129
|
+
}
|
|
130
|
+
const loginUrl = new URL(redirectTo, req.url);
|
|
131
|
+
loginUrl.searchParams.set("from", pathname);
|
|
132
|
+
return import_server2.NextResponse.redirect(loginUrl);
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/core/createLiteAuth.ts
|
|
138
|
+
function createLiteAuth(config) {
|
|
139
|
+
const ctx = {
|
|
140
|
+
users: config.users,
|
|
141
|
+
jwtSecret: config.jwtSecret,
|
|
142
|
+
cookieName: config.cookieName ?? "lite-auth-token"
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
handlers: {
|
|
146
|
+
login: makeLoginHandler(ctx),
|
|
147
|
+
logout: makeLogoutHandler(ctx),
|
|
148
|
+
me: makeMeHandler(ctx)
|
|
149
|
+
},
|
|
150
|
+
middleware: makeMiddleware(ctx),
|
|
151
|
+
getUserFromCookies: getUserFromCookies(ctx)
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
155
|
+
0 && (module.exports = {
|
|
156
|
+
createLiteAuth
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/server/handlers.ts","../src/server/jwt.ts","../src/server/getUserFromCookies.ts","../src/middleware/index.ts","../src/core/createLiteAuth.ts"],"sourcesContent":["export { createLiteAuth } from \"./core/createLiteAuth\";\nexport type { User, PublicUser, LiteAuthConfig } from \"./core/types\";\n","import { NextRequest, NextResponse } from \"next/server\";\nimport { LiteAuthContext } from \"../core/types\";\nimport { signToken, verifyToken } from \"./jwt\";\n\nexport function makeLoginHandler(ctx: LiteAuthContext) {\n return async function loginHandler(req: NextRequest): Promise<NextResponse> {\n let body: { email?: string; password?: string };\n try {\n body = await req.json();\n } catch {\n return NextResponse.json({ error: \"Invalid JSON\" }, { status: 400 });\n }\n\n const { email, password } = body;\n if (!email || !password) {\n return NextResponse.json({ error: \"Email and password are required\" }, { status: 400 });\n }\n\n const user = ctx.users.find((u) => u.email === email && u.password === password);\n if (!user) {\n return NextResponse.json({ error: \"Invalid credentials\" }, { status: 401 });\n }\n\n const { password: _, ...publicUser } = user;\n const token = await signToken(publicUser, ctx.jwtSecret);\n\n const res = NextResponse.json({ user: publicUser });\n res.cookies.set(ctx.cookieName, token, {\n httpOnly: true,\n path: \"/\",\n sameSite: \"lax\",\n secure: process.env.NODE_ENV === \"production\",\n maxAge: 60 * 60 * 24 * 7, // 7 days\n });\n return res;\n };\n}\n\nexport function makeLogoutHandler(ctx: LiteAuthContext) {\n return async function logoutHandler(_req: NextRequest): Promise<NextResponse> {\n const res = NextResponse.json({ ok: true });\n res.cookies.set(ctx.cookieName, \"\", {\n httpOnly: true,\n path: \"/\",\n maxAge: 0,\n });\n return res;\n };\n}\n\nexport function makeMeHandler(ctx: LiteAuthContext) {\n return async function meHandler(req: NextRequest): Promise<NextResponse> {\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (!token) {\n return NextResponse.json({ user: null }, { status: 401 });\n }\n\n const user = await verifyToken(token, ctx.jwtSecret);\n if (!user) {\n return NextResponse.json({ user: null }, { status: 401 });\n }\n\n return NextResponse.json({ user });\n };\n}\n","import { SignJWT, jwtVerify } from \"jose\";\nimport { PublicUser } from \"../core/types\";\n\nfunction getSecret(secret: string) {\n return new TextEncoder().encode(secret);\n}\n\nexport async function signToken(user: PublicUser, secret: string): Promise<string> {\n return new SignJWT({ ...user })\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuedAt()\n .setExpirationTime(\"7d\")\n .sign(getSecret(secret));\n}\n\nexport async function verifyToken(token: string, secret: string): Promise<PublicUser | null> {\n try {\n const { payload } = await jwtVerify(token, getSecret(secret));\n return payload as unknown as PublicUser;\n } catch {\n return null;\n }\n}\n","import { ReadonlyRequestCookies } from \"next/dist/server/web/spec-extension/adapters/request-cookies\";\nimport { LiteAuthContext, PublicUser } from \"../core/types\";\nimport { verifyToken } from \"./jwt\";\n\nexport function getUserFromCookies(ctx: LiteAuthContext) {\n return async function (cookies: ReadonlyRequestCookies): Promise<PublicUser | null> {\n const token = cookies.get(ctx.cookieName)?.value;\n if (!token) return null;\n return verifyToken(token, ctx.jwtSecret);\n };\n}\n","import { NextRequest, NextResponse } from \"next/server\";\nimport { LiteAuthContext } from \"../core/types\";\nimport { verifyToken } from \"../server/jwt\";\n\ntype MiddlewareOptions = {\n protect: string[];\n redirectTo?: string;\n};\n\nexport function makeMiddleware(ctx: LiteAuthContext) {\n return function middleware(options: MiddlewareOptions) {\n return async function (req: NextRequest): Promise<NextResponse> {\n const { protect, redirectTo = \"/login\" } = options;\n const { pathname } = req.nextUrl;\n\n const isProtected = protect.some(\n (pattern) => pathname === pattern || pathname.startsWith(pattern + \"/\")\n );\n\n if (!isProtected) {\n return NextResponse.next();\n }\n\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (token) {\n const user = await verifyToken(token, ctx.jwtSecret);\n if (user) return NextResponse.next();\n }\n\n const loginUrl = new URL(redirectTo, req.url);\n loginUrl.searchParams.set(\"from\", pathname);\n return NextResponse.redirect(loginUrl);\n };\n };\n}\n","import { LiteAuthConfig, LiteAuthContext } from \"./types\";\nimport { makeLoginHandler, makeLogoutHandler, makeMeHandler, getUserFromCookies } from \"../server\";\nimport { makeMiddleware } from \"../middleware\";\n\nexport function createLiteAuth(config: LiteAuthConfig) {\n const ctx: LiteAuthContext = {\n users: config.users,\n jwtSecret: config.jwtSecret,\n cookieName: config.cookieName ?? \"lite-auth-token\",\n };\n\n return {\n handlers: {\n login: makeLoginHandler(ctx),\n logout: makeLogoutHandler(ctx),\n me: makeMeHandler(ctx),\n },\n middleware: makeMiddleware(ctx),\n getUserFromCookies: getUserFromCookies(ctx),\n };\n}\n"],"mappings":"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","names":["import_server"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// src/server/handlers.ts
|
|
2
|
+
import { NextResponse } from "next/server";
|
|
3
|
+
|
|
4
|
+
// src/server/jwt.ts
|
|
5
|
+
import { SignJWT, jwtVerify } from "jose";
|
|
6
|
+
function getSecret(secret) {
|
|
7
|
+
return new TextEncoder().encode(secret);
|
|
8
|
+
}
|
|
9
|
+
async function signToken(user, secret) {
|
|
10
|
+
return new SignJWT({ ...user }).setProtectedHeader({ alg: "HS256" }).setIssuedAt().setExpirationTime("7d").sign(getSecret(secret));
|
|
11
|
+
}
|
|
12
|
+
async function verifyToken(token, secret) {
|
|
13
|
+
try {
|
|
14
|
+
const { payload } = await jwtVerify(token, getSecret(secret));
|
|
15
|
+
return payload;
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/server/handlers.ts
|
|
22
|
+
function makeLoginHandler(ctx) {
|
|
23
|
+
return async function loginHandler(req) {
|
|
24
|
+
let body;
|
|
25
|
+
try {
|
|
26
|
+
body = await req.json();
|
|
27
|
+
} catch {
|
|
28
|
+
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
|
29
|
+
}
|
|
30
|
+
const { email, password } = body;
|
|
31
|
+
if (!email || !password) {
|
|
32
|
+
return NextResponse.json({ error: "Email and password are required" }, { status: 400 });
|
|
33
|
+
}
|
|
34
|
+
const user = ctx.users.find((u) => u.email === email && u.password === password);
|
|
35
|
+
if (!user) {
|
|
36
|
+
return NextResponse.json({ error: "Invalid credentials" }, { status: 401 });
|
|
37
|
+
}
|
|
38
|
+
const { password: _, ...publicUser } = user;
|
|
39
|
+
const token = await signToken(publicUser, ctx.jwtSecret);
|
|
40
|
+
const res = NextResponse.json({ user: publicUser });
|
|
41
|
+
res.cookies.set(ctx.cookieName, token, {
|
|
42
|
+
httpOnly: true,
|
|
43
|
+
path: "/",
|
|
44
|
+
sameSite: "lax",
|
|
45
|
+
secure: process.env.NODE_ENV === "production",
|
|
46
|
+
maxAge: 60 * 60 * 24 * 7
|
|
47
|
+
// 7 days
|
|
48
|
+
});
|
|
49
|
+
return res;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function makeLogoutHandler(ctx) {
|
|
53
|
+
return async function logoutHandler(_req) {
|
|
54
|
+
const res = NextResponse.json({ ok: true });
|
|
55
|
+
res.cookies.set(ctx.cookieName, "", {
|
|
56
|
+
httpOnly: true,
|
|
57
|
+
path: "/",
|
|
58
|
+
maxAge: 0
|
|
59
|
+
});
|
|
60
|
+
return res;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function makeMeHandler(ctx) {
|
|
64
|
+
return async function meHandler(req) {
|
|
65
|
+
const token = req.cookies.get(ctx.cookieName)?.value;
|
|
66
|
+
if (!token) {
|
|
67
|
+
return NextResponse.json({ user: null }, { status: 401 });
|
|
68
|
+
}
|
|
69
|
+
const user = await verifyToken(token, ctx.jwtSecret);
|
|
70
|
+
if (!user) {
|
|
71
|
+
return NextResponse.json({ user: null }, { status: 401 });
|
|
72
|
+
}
|
|
73
|
+
return NextResponse.json({ user });
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/server/getUserFromCookies.ts
|
|
78
|
+
function getUserFromCookies(ctx) {
|
|
79
|
+
return async function(cookies) {
|
|
80
|
+
const token = cookies.get(ctx.cookieName)?.value;
|
|
81
|
+
if (!token) return null;
|
|
82
|
+
return verifyToken(token, ctx.jwtSecret);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/middleware/index.ts
|
|
87
|
+
import { NextResponse as NextResponse2 } from "next/server";
|
|
88
|
+
function makeMiddleware(ctx) {
|
|
89
|
+
return function middleware(options) {
|
|
90
|
+
return async function(req) {
|
|
91
|
+
const { protect, redirectTo = "/login" } = options;
|
|
92
|
+
const { pathname } = req.nextUrl;
|
|
93
|
+
const isProtected = protect.some(
|
|
94
|
+
(pattern) => pathname === pattern || pathname.startsWith(pattern + "/")
|
|
95
|
+
);
|
|
96
|
+
if (!isProtected) {
|
|
97
|
+
return NextResponse2.next();
|
|
98
|
+
}
|
|
99
|
+
const token = req.cookies.get(ctx.cookieName)?.value;
|
|
100
|
+
if (token) {
|
|
101
|
+
const user = await verifyToken(token, ctx.jwtSecret);
|
|
102
|
+
if (user) return NextResponse2.next();
|
|
103
|
+
}
|
|
104
|
+
const loginUrl = new URL(redirectTo, req.url);
|
|
105
|
+
loginUrl.searchParams.set("from", pathname);
|
|
106
|
+
return NextResponse2.redirect(loginUrl);
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/core/createLiteAuth.ts
|
|
112
|
+
function createLiteAuth(config) {
|
|
113
|
+
const ctx = {
|
|
114
|
+
users: config.users,
|
|
115
|
+
jwtSecret: config.jwtSecret,
|
|
116
|
+
cookieName: config.cookieName ?? "lite-auth-token"
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
handlers: {
|
|
120
|
+
login: makeLoginHandler(ctx),
|
|
121
|
+
logout: makeLogoutHandler(ctx),
|
|
122
|
+
me: makeMeHandler(ctx)
|
|
123
|
+
},
|
|
124
|
+
middleware: makeMiddleware(ctx),
|
|
125
|
+
getUserFromCookies: getUserFromCookies(ctx)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export {
|
|
129
|
+
createLiteAuth
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/handlers.ts","../src/server/jwt.ts","../src/server/getUserFromCookies.ts","../src/middleware/index.ts","../src/core/createLiteAuth.ts"],"sourcesContent":["import { NextRequest, NextResponse } from \"next/server\";\nimport { LiteAuthContext } from \"../core/types\";\nimport { signToken, verifyToken } from \"./jwt\";\n\nexport function makeLoginHandler(ctx: LiteAuthContext) {\n return async function loginHandler(req: NextRequest): Promise<NextResponse> {\n let body: { email?: string; password?: string };\n try {\n body = await req.json();\n } catch {\n return NextResponse.json({ error: \"Invalid JSON\" }, { status: 400 });\n }\n\n const { email, password } = body;\n if (!email || !password) {\n return NextResponse.json({ error: \"Email and password are required\" }, { status: 400 });\n }\n\n const user = ctx.users.find((u) => u.email === email && u.password === password);\n if (!user) {\n return NextResponse.json({ error: \"Invalid credentials\" }, { status: 401 });\n }\n\n const { password: _, ...publicUser } = user;\n const token = await signToken(publicUser, ctx.jwtSecret);\n\n const res = NextResponse.json({ user: publicUser });\n res.cookies.set(ctx.cookieName, token, {\n httpOnly: true,\n path: \"/\",\n sameSite: \"lax\",\n secure: process.env.NODE_ENV === \"production\",\n maxAge: 60 * 60 * 24 * 7, // 7 days\n });\n return res;\n };\n}\n\nexport function makeLogoutHandler(ctx: LiteAuthContext) {\n return async function logoutHandler(_req: NextRequest): Promise<NextResponse> {\n const res = NextResponse.json({ ok: true });\n res.cookies.set(ctx.cookieName, \"\", {\n httpOnly: true,\n path: \"/\",\n maxAge: 0,\n });\n return res;\n };\n}\n\nexport function makeMeHandler(ctx: LiteAuthContext) {\n return async function meHandler(req: NextRequest): Promise<NextResponse> {\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (!token) {\n return NextResponse.json({ user: null }, { status: 401 });\n }\n\n const user = await verifyToken(token, ctx.jwtSecret);\n if (!user) {\n return NextResponse.json({ user: null }, { status: 401 });\n }\n\n return NextResponse.json({ user });\n };\n}\n","import { SignJWT, jwtVerify } from \"jose\";\nimport { PublicUser } from \"../core/types\";\n\nfunction getSecret(secret: string) {\n return new TextEncoder().encode(secret);\n}\n\nexport async function signToken(user: PublicUser, secret: string): Promise<string> {\n return new SignJWT({ ...user })\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuedAt()\n .setExpirationTime(\"7d\")\n .sign(getSecret(secret));\n}\n\nexport async function verifyToken(token: string, secret: string): Promise<PublicUser | null> {\n try {\n const { payload } = await jwtVerify(token, getSecret(secret));\n return payload as unknown as PublicUser;\n } catch {\n return null;\n }\n}\n","import { ReadonlyRequestCookies } from \"next/dist/server/web/spec-extension/adapters/request-cookies\";\nimport { LiteAuthContext, PublicUser } from \"../core/types\";\nimport { verifyToken } from \"./jwt\";\n\nexport function getUserFromCookies(ctx: LiteAuthContext) {\n return async function (cookies: ReadonlyRequestCookies): Promise<PublicUser | null> {\n const token = cookies.get(ctx.cookieName)?.value;\n if (!token) return null;\n return verifyToken(token, ctx.jwtSecret);\n };\n}\n","import { NextRequest, NextResponse } from \"next/server\";\nimport { LiteAuthContext } from \"../core/types\";\nimport { verifyToken } from \"../server/jwt\";\n\ntype MiddlewareOptions = {\n protect: string[];\n redirectTo?: string;\n};\n\nexport function makeMiddleware(ctx: LiteAuthContext) {\n return function middleware(options: MiddlewareOptions) {\n return async function (req: NextRequest): Promise<NextResponse> {\n const { protect, redirectTo = \"/login\" } = options;\n const { pathname } = req.nextUrl;\n\n const isProtected = protect.some(\n (pattern) => pathname === pattern || pathname.startsWith(pattern + \"/\")\n );\n\n if (!isProtected) {\n return NextResponse.next();\n }\n\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (token) {\n const user = await verifyToken(token, ctx.jwtSecret);\n if (user) return NextResponse.next();\n }\n\n const loginUrl = new URL(redirectTo, req.url);\n loginUrl.searchParams.set(\"from\", pathname);\n return NextResponse.redirect(loginUrl);\n };\n };\n}\n","import { LiteAuthConfig, LiteAuthContext } from \"./types\";\nimport { makeLoginHandler, makeLogoutHandler, makeMeHandler, getUserFromCookies } from \"../server\";\nimport { makeMiddleware } from \"../middleware\";\n\nexport function createLiteAuth(config: LiteAuthConfig) {\n const ctx: LiteAuthContext = {\n users: config.users,\n jwtSecret: config.jwtSecret,\n cookieName: config.cookieName ?? \"lite-auth-token\",\n };\n\n return {\n handlers: {\n login: makeLoginHandler(ctx),\n logout: makeLogoutHandler(ctx),\n me: makeMeHandler(ctx),\n },\n middleware: makeMiddleware(ctx),\n getUserFromCookies: getUserFromCookies(ctx),\n };\n}\n"],"mappings":"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","names":["NextResponse","NextResponse"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "next-lite-auth",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight JWT auth for Next.js using static JSON users (no database)",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./client": {
|
|
15
|
+
"types": "./dist/client.d.ts",
|
|
16
|
+
"import": "./dist/client.mjs",
|
|
17
|
+
"require": "./dist/client.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": ["dist"],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"prepublishOnly": "pnpm build",
|
|
26
|
+
"docs:dev": "vitepress dev docs",
|
|
27
|
+
"docs:build": "vitepress build docs",
|
|
28
|
+
"docs:preview": "vitepress preview docs"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"next": ">=13.0.0",
|
|
32
|
+
"react": ">=18.0.0"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"jose": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/react": "^18.0.0",
|
|
39
|
+
"next": "^14.0.0",
|
|
40
|
+
"react": "^18.0.0",
|
|
41
|
+
"tsup": "^8.0.0",
|
|
42
|
+
"typescript": "^5.0.0",
|
|
43
|
+
"vitepress": "^1.0.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0",
|
|
47
|
+
"pnpm": ">=9.0.0"
|
|
48
|
+
},
|
|
49
|
+
"packageManager": "pnpm@9.0.0",
|
|
50
|
+
"author": "amide-init",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/amide-init/next-lite-auth.git"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/amide-init/next-lite-auth#readme",
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/amide-init/next-lite-auth/issues"
|
|
58
|
+
},
|
|
59
|
+
"keywords": ["nextjs", "auth", "jwt", "lightweight"],
|
|
60
|
+
"license": "MIT"
|
|
61
|
+
}
|