next-lite-auth 0.2.2 → 0.2.4
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 +28 -7
- package/dist/client.js +58 -18
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +58 -18
- package/dist/client.mjs.map +1 -1
- package/package.json +14 -12
package/README.md
CHANGED
|
@@ -58,24 +58,38 @@ export const { GET, POST } = handlers;
|
|
|
58
58
|
|
|
59
59
|
### 3. Wrap root layout
|
|
60
60
|
|
|
61
|
+
`layout.tsx` is a Server Component — wrap `LiteAuthProvider` in a client component first:
|
|
62
|
+
|
|
61
63
|
```tsx
|
|
62
|
-
//
|
|
64
|
+
// components/auth-provider.tsx
|
|
65
|
+
"use client";
|
|
63
66
|
import { LiteAuthProvider } from "next-lite-auth/client";
|
|
64
67
|
|
|
68
|
+
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
69
|
+
return (
|
|
70
|
+
<LiteAuthProvider protect={["/dashboard", "/settings"]} appName="My App">
|
|
71
|
+
{children}
|
|
72
|
+
</LiteAuthProvider>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
// app/layout.tsx
|
|
79
|
+
import { AuthProvider } from "@/components/auth-provider";
|
|
80
|
+
|
|
65
81
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
66
82
|
return (
|
|
67
83
|
<html>
|
|
68
84
|
<body>
|
|
69
|
-
<
|
|
70
|
-
{children}
|
|
71
|
-
</LiteAuthProvider>
|
|
85
|
+
<AuthProvider>{children}</AuthProvider>
|
|
72
86
|
</body>
|
|
73
87
|
</html>
|
|
74
88
|
);
|
|
75
89
|
}
|
|
76
90
|
```
|
|
77
91
|
|
|
78
|
-
**Done.** Visiting a protected route while logged out automatically shows the built-in login UI. After login, the original page renders instantly — no redirects, no separate login page needed.
|
|
92
|
+
**Done.** Visiting a protected route while logged out automatically shows the built-in login UI with your app name. After login, the original page renders instantly — no redirects, no separate login page needed.
|
|
79
93
|
|
|
80
94
|
---
|
|
81
95
|
|
|
@@ -97,10 +111,17 @@ LITE_AUTH_SECRET=your-secret
|
|
|
97
111
|
|
|
98
112
|
## Optional: server-side middleware
|
|
99
113
|
|
|
114
|
+
Strings protect exact and prefix routes. Use `"/"` to protect everything, or `RegExp` for dynamic routes:
|
|
115
|
+
|
|
100
116
|
```ts
|
|
101
117
|
// middleware.ts
|
|
102
118
|
import { middleware } from "@/auth";
|
|
103
|
-
|
|
119
|
+
|
|
120
|
+
export default middleware({
|
|
121
|
+
protect: ["/dashboard", "/settings"], // string prefixes
|
|
122
|
+
// protect: ["/"], // protect all routes
|
|
123
|
+
// protect: [/^\/[^/]+\/name$/], // dynamic route /:id/name
|
|
124
|
+
});
|
|
104
125
|
|
|
105
126
|
export const config = {
|
|
106
127
|
matcher: ["/((?!_next|api/auth).*)"],
|
|
@@ -146,7 +167,7 @@ const user = await getUserFromCookies(cookies());
|
|
|
146
167
|
| `handlers.GET / POST` | Catch-all route handlers |
|
|
147
168
|
| `middleware(options)` | Edge middleware for server-side route protection |
|
|
148
169
|
| `getUserFromCookies(cookies)` | Server-side session helper |
|
|
149
|
-
| `LiteAuthProvider` | Root provider — manages session
|
|
170
|
+
| `LiteAuthProvider` | Root provider — manages session, auto-shows login UI (`appName`, `protect` props) |
|
|
150
171
|
| `useLiteAuth()` | Hook — `user`, `loading`, `login`, `logout` |
|
|
151
172
|
|
|
152
173
|
---
|
package/dist/client.js
CHANGED
|
@@ -118,6 +118,22 @@ var styles = {
|
|
|
118
118
|
border: "1px solid #6366f1",
|
|
119
119
|
boxShadow: "0 0 0 3px rgba(99,102,241,0.15)"
|
|
120
120
|
},
|
|
121
|
+
passwordWrapper: {
|
|
122
|
+
position: "relative",
|
|
123
|
+
display: "flex",
|
|
124
|
+
alignItems: "center"
|
|
125
|
+
},
|
|
126
|
+
passwordToggle: {
|
|
127
|
+
position: "absolute",
|
|
128
|
+
right: "10px",
|
|
129
|
+
background: "none",
|
|
130
|
+
border: "none",
|
|
131
|
+
cursor: "pointer",
|
|
132
|
+
padding: "0",
|
|
133
|
+
display: "flex",
|
|
134
|
+
alignItems: "center",
|
|
135
|
+
color: "#9ca3af"
|
|
136
|
+
},
|
|
121
137
|
button: {
|
|
122
138
|
height: "36px",
|
|
123
139
|
width: "100%",
|
|
@@ -178,6 +194,7 @@ var darkModeCSS = `
|
|
|
178
194
|
}
|
|
179
195
|
.lite-auth-footer { color: #52525b !important; }
|
|
180
196
|
.lite-auth-link { color: #71717a !important; }
|
|
197
|
+
.lite-auth-pw-toggle { color: #52525b !important; }
|
|
181
198
|
}
|
|
182
199
|
`;
|
|
183
200
|
function LiteLoginPage({
|
|
@@ -189,6 +206,7 @@ function LiteLoginPage({
|
|
|
189
206
|
const [error, setError] = (0, import_react.useState)("");
|
|
190
207
|
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
191
208
|
const [focusedField, setFocusedField] = (0, import_react.useState)(null);
|
|
209
|
+
const [showPassword, setShowPassword] = (0, import_react.useState)(false);
|
|
192
210
|
async function handleSubmit(e) {
|
|
193
211
|
e.preventDefault();
|
|
194
212
|
setError("");
|
|
@@ -237,24 +255,46 @@ function LiteLoginPage({
|
|
|
237
255
|
] }),
|
|
238
256
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.field, children: [
|
|
239
257
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "password", className: "lite-auth-label", style: styles.label, children: "Password" }),
|
|
240
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.passwordWrapper, children: [
|
|
259
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
260
|
+
"input",
|
|
261
|
+
{
|
|
262
|
+
id: "password",
|
|
263
|
+
name: "password",
|
|
264
|
+
type: showPassword ? "text" : "password",
|
|
265
|
+
required: true,
|
|
266
|
+
autoComplete: "current-password",
|
|
267
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
268
|
+
className: "lite-auth-input",
|
|
269
|
+
style: {
|
|
270
|
+
...styles.input,
|
|
271
|
+
paddingRight: "36px",
|
|
272
|
+
...focusedField === "password" ? styles.inputFocus : {}
|
|
273
|
+
},
|
|
274
|
+
onFocus: () => setFocusedField("password"),
|
|
275
|
+
onBlur: () => setFocusedField(null)
|
|
276
|
+
}
|
|
277
|
+
),
|
|
278
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
279
|
+
"button",
|
|
280
|
+
{
|
|
281
|
+
type: "button",
|
|
282
|
+
onClick: () => setShowPassword((v) => !v),
|
|
283
|
+
className: "lite-auth-pw-toggle",
|
|
284
|
+
style: styles.passwordToggle,
|
|
285
|
+
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
286
|
+
tabIndex: -1,
|
|
287
|
+
children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
288
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94" }),
|
|
289
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19" }),
|
|
290
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "1", y1: "1", x2: "23", y2: "23" })
|
|
291
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
292
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
|
|
293
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "3" })
|
|
294
|
+
] })
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
] })
|
|
258
298
|
] }),
|
|
259
299
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
260
300
|
"button",
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/index.ts","../src/client/LiteAuthProvider.tsx","../src/client/LiteLoginPage.tsx","../src/core/matchesProtect.ts"],"sourcesContent":["export { LiteAuthProvider, useLiteAuth } from \"./LiteAuthProvider\";\nexport { LiteLoginPage } from \"./LiteLoginPage\";\n","\"use client\";\n\nimport { createContext, useContext, useState, useEffect, useCallback, ReactNode } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { PublicUser } from \"../core/types\";\nimport { LiteLoginPage } from \"./LiteLoginPage\";\nimport { matchesProtect } from \"../core/matchesProtect\";\n\ntype LiteAuthContextValue = {\n user: PublicUser | null;\n loading: boolean;\n login: (creds: { email: string; password: string }) => Promise<{ error?: string }>;\n logout: () => Promise<void>;\n};\n\nconst LiteAuthContext = createContext<LiteAuthContextValue | null>(null);\n\ntype LiteAuthProviderProps = {\n children: ReactNode;\n protect?: (string | RegExp)[];\n appName?: string;\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function LiteAuthProvider({\n children,\n protect = [],\n appName,\n loginPath = \"/api/auth/login\",\n logoutPath = \"/api/auth/logout\",\n mePath = \"/api/auth/me\",\n}: LiteAuthProviderProps) {\n const [user, setUser] = useState<PublicUser | null>(null);\n const [loading, setLoading] = useState(true);\n const pathname = usePathname();\n\n useEffect(() => {\n fetch(mePath)\n .then((r) => r.json())\n .then(({ user }) => setUser(user ?? null))\n .catch(() => setUser(null))\n .finally(() => setLoading(false));\n }, [mePath]);\n\n const login = useCallback(\n async ({ email, password }: { email: string; password: string }) => {\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 setUser(data.user);\n return {};\n },\n [loginPath]\n );\n\n const logout = useCallback(async () => {\n await fetch(logoutPath, { method: \"POST\" });\n setUser(null);\n }, [logoutPath]);\n\n const value = { user, loading, login, logout };\n\n const isProtected = matchesProtect(protect, pathname);\n\n if (loading) {\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n }\n\n if (!user && isProtected) {\n return (\n <LiteAuthContext.Provider value={value}>\n <LiteLoginPage appName={appName} />\n </LiteAuthContext.Provider>\n );\n }\n\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n}\n\nexport function useLiteAuth(): LiteAuthContextValue {\n const ctx = useContext(LiteAuthContext);\n if (!ctx) throw new Error(\"useLiteAuth must be used inside <LiteAuthProvider>\");\n return ctx;\n}\n","\"use client\";\n\nimport { CSSProperties, FormEvent, useState } from \"react\";\nimport { useLiteAuth } from \"./LiteAuthProvider\";\n\ntype LiteLoginPageProps = {\n appName?: string;\n title?: string;\n description?: string;\n};\n\nconst styles: Record<string, CSSProperties> = {\n page: {\n minHeight: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f9fafb\",\n padding: \"0 16px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n container: {\n width: \"100%\",\n maxWidth: \"360px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"24px\",\n },\n header: {\n textAlign: \"center\",\n },\n appName: {\n margin: \"0 0 8px\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"#6366f1\",\n textTransform: \"uppercase\" as const,\n letterSpacing: \"0.08em\",\n },\n title: {\n margin: \"0 0 4px\",\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#111827\",\n letterSpacing: \"-0.01em\",\n },\n description: {\n margin: 0,\n fontSize: \"14px\",\n color: \"#6b7280\",\n },\n card: {\n backgroundColor: \"#ffffff\",\n border: \"1px solid #e5e7eb\",\n borderRadius: \"12px\",\n padding: \"24px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"16px\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.07)\",\n },\n error: {\n backgroundColor: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: \"6px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"#dc2626\",\n },\n field: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"6px\",\n },\n label: {\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"#374151\",\n },\n input: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"1px solid #d1d5db\",\n padding: \"0 12px\",\n fontSize: \"14px\",\n color: \"#111827\",\n backgroundColor: \"#fff\",\n outline: \"none\",\n boxSizing: \"border-box\",\n transition: \"border-color 0.15s\",\n },\n inputFocus: {\n border: \"1px solid #6366f1\",\n boxShadow: \"0 0 0 3px rgba(99,102,241,0.15)\",\n },\n button: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"none\",\n backgroundColor: \"#111827\",\n color: \"#ffffff\",\n fontSize: \"14px\",\n fontWeight: 500,\n cursor: \"pointer\",\n transition: \"opacity 0.15s\",\n },\n buttonDisabled: {\n opacity: 0.5,\n pointerEvents: \"none\",\n },\n footer: {\n textAlign: \"center\",\n fontSize: \"12px\",\n color: \"#9ca3af\",\n },\n link: {\n color: \"#6b7280\",\n textDecoration: \"underline\",\n textUnderlineOffset: \"3px\",\n },\n};\n\nconst darkModeCSS = `\n @media (prefers-color-scheme: dark) {\n .lite-auth-page { background-color: #09090b !important; }\n .lite-auth-appname { color: #818cf8 !important; }\n .lite-auth-title { color: #fafafa !important; }\n .lite-auth-desc { color: #a1a1aa !important; }\n .lite-auth-card {\n background-color: #18181b !important;\n border-color: #27272a !important;\n box-shadow: none !important;\n }\n .lite-auth-error {\n background-color: rgba(239,68,68,0.1) !important;\n border-color: rgba(239,68,68,0.3) !important;\n color: #f87171 !important;\n }\n .lite-auth-label { color: #e4e4e7 !important; }\n .lite-auth-input {\n background-color: transparent !important;\n border-color: #3f3f46 !important;\n color: #fafafa !important;\n }\n .lite-auth-input::placeholder { color: #52525b !important; }\n .lite-auth-input:focus {\n border-color: #6366f1 !important;\n box-shadow: 0 0 0 3px rgba(99,102,241,0.2) !important;\n }\n .lite-auth-btn {\n background-color: #fafafa !important;\n color: #09090b !important;\n }\n .lite-auth-footer { color: #52525b !important; }\n .lite-auth-link { color: #71717a !important; }\n }\n`;\n\nexport function LiteLoginPage({\n appName,\n title = \"Sign in\",\n description = \"Enter your credentials to continue\",\n}: LiteLoginPageProps) {\n const { login } = useLiteAuth();\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [focusedField, setFocusedField] = useState<string | null>(null);\n\n async function handleSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setError(\"\");\n setLoading(true);\n\n const form = e.currentTarget;\n const result = await login({\n email: (form.elements.namedItem(\"email\") as HTMLInputElement).value,\n password: (form.elements.namedItem(\"password\") as HTMLInputElement).value,\n });\n\n setLoading(false);\n\n if (result.error) {\n setError(result.error);\n }\n }\n\n return (\n <>\n <style>{darkModeCSS}</style>\n <div className=\"lite-auth-page\" style={styles.page}>\n <div style={styles.container}>\n <div style={styles.header}>\n {appName && <p className=\"lite-auth-appname\" style={styles.appName}>{appName}</p>}\n <h1 className=\"lite-auth-title\" style={styles.title}>{title}</h1>\n <p className=\"lite-auth-desc\" style={styles.description}>{description}</p>\n </div>\n\n <div className=\"lite-auth-card\" style={styles.card}>\n {error && (\n <div className=\"lite-auth-error\" style={styles.error}>{error}</div>\n )}\n\n <form onSubmit={handleSubmit} style={{ display: \"flex\", flexDirection: \"column\", gap: \"16px\" }}>\n <div style={styles.field}>\n <label htmlFor=\"email\" className=\"lite-auth-label\" style={styles.label}>Email</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n autoComplete=\"email\"\n placeholder=\"you@example.com\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n ...(focusedField === \"email\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"email\")}\n onBlur={() => setFocusedField(null)}\n />\n </div>\n\n <div style={styles.field}>\n <label htmlFor=\"password\" className=\"lite-auth-label\" style={styles.label}>Password</label>\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n required\n autoComplete=\"current-password\"\n placeholder=\"••••••••\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n ...(focusedField === \"password\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"password\")}\n onBlur={() => setFocusedField(null)}\n />\n </div>\n\n <button\n type=\"submit\"\n disabled={loading}\n className=\"lite-auth-btn\"\n style={{\n ...styles.button,\n ...(loading ? styles.buttonDisabled : {}),\n }}\n >\n {loading ? \"Signing in…\" : \"Sign in\"}\n </button>\n </form>\n </div>\n\n <p className=\"lite-auth-footer\" style={styles.footer}>\n Powered by{\" \"}\n <a\n href=\"https://github.com/amide-init/next-lite-auth\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"lite-auth-link\"\n style={styles.link}\n >\n next-lite-auth\n </a>\n </p>\n </div>\n </div>\n </>\n );\n}\n","export function matchesProtect(patterns: (string | RegExp)[], pathname: string): boolean {\n return patterns.some((p) =>\n p instanceof RegExp\n ? p.test(pathname)\n : p === \"/\" || pathname === p || pathname.startsWith(p + \"/\")\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","user"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/index.ts","../src/client/LiteAuthProvider.tsx","../src/client/LiteLoginPage.tsx","../src/core/matchesProtect.ts"],"sourcesContent":["export { LiteAuthProvider, useLiteAuth } from \"./LiteAuthProvider\";\nexport { LiteLoginPage } from \"./LiteLoginPage\";\n","\"use client\";\n\nimport { createContext, useContext, useState, useEffect, useCallback, ReactNode } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { PublicUser } from \"../core/types\";\nimport { LiteLoginPage } from \"./LiteLoginPage\";\nimport { matchesProtect } from \"../core/matchesProtect\";\n\ntype LiteAuthContextValue = {\n user: PublicUser | null;\n loading: boolean;\n login: (creds: { email: string; password: string }) => Promise<{ error?: string }>;\n logout: () => Promise<void>;\n};\n\nconst LiteAuthContext = createContext<LiteAuthContextValue | null>(null);\n\ntype LiteAuthProviderProps = {\n children: ReactNode;\n protect?: (string | RegExp)[];\n appName?: string;\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function LiteAuthProvider({\n children,\n protect = [],\n appName,\n loginPath = \"/api/auth/login\",\n logoutPath = \"/api/auth/logout\",\n mePath = \"/api/auth/me\",\n}: LiteAuthProviderProps) {\n const [user, setUser] = useState<PublicUser | null>(null);\n const [loading, setLoading] = useState(true);\n const pathname = usePathname();\n\n useEffect(() => {\n fetch(mePath)\n .then((r) => r.json())\n .then(({ user }) => setUser(user ?? null))\n .catch(() => setUser(null))\n .finally(() => setLoading(false));\n }, [mePath]);\n\n const login = useCallback(\n async ({ email, password }: { email: string; password: string }) => {\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 setUser(data.user);\n return {};\n },\n [loginPath]\n );\n\n const logout = useCallback(async () => {\n await fetch(logoutPath, { method: \"POST\" });\n setUser(null);\n }, [logoutPath]);\n\n const value = { user, loading, login, logout };\n\n const isProtected = matchesProtect(protect, pathname);\n\n if (loading) {\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n }\n\n if (!user && isProtected) {\n return (\n <LiteAuthContext.Provider value={value}>\n <LiteLoginPage appName={appName} />\n </LiteAuthContext.Provider>\n );\n }\n\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n}\n\nexport function useLiteAuth(): LiteAuthContextValue {\n const ctx = useContext(LiteAuthContext);\n if (!ctx) throw new Error(\"useLiteAuth must be used inside <LiteAuthProvider>\");\n return ctx;\n}\n","\"use client\";\n\nimport { CSSProperties, FormEvent, useState } from \"react\";\nimport { useLiteAuth } from \"./LiteAuthProvider\";\n\ntype LiteLoginPageProps = {\n appName?: string;\n title?: string;\n description?: string;\n};\n\nconst styles: Record<string, CSSProperties> = {\n page: {\n minHeight: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f9fafb\",\n padding: \"0 16px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n container: {\n width: \"100%\",\n maxWidth: \"360px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"24px\",\n },\n header: {\n textAlign: \"center\",\n },\n appName: {\n margin: \"0 0 8px\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"#6366f1\",\n textTransform: \"uppercase\" as const,\n letterSpacing: \"0.08em\",\n },\n title: {\n margin: \"0 0 4px\",\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#111827\",\n letterSpacing: \"-0.01em\",\n },\n description: {\n margin: 0,\n fontSize: \"14px\",\n color: \"#6b7280\",\n },\n card: {\n backgroundColor: \"#ffffff\",\n border: \"1px solid #e5e7eb\",\n borderRadius: \"12px\",\n padding: \"24px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"16px\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.07)\",\n },\n error: {\n backgroundColor: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: \"6px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"#dc2626\",\n },\n field: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"6px\",\n },\n label: {\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"#374151\",\n },\n input: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"1px solid #d1d5db\",\n padding: \"0 12px\",\n fontSize: \"14px\",\n color: \"#111827\",\n backgroundColor: \"#fff\",\n outline: \"none\",\n boxSizing: \"border-box\",\n transition: \"border-color 0.15s\",\n },\n inputFocus: {\n border: \"1px solid #6366f1\",\n boxShadow: \"0 0 0 3px rgba(99,102,241,0.15)\",\n },\n passwordWrapper: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n },\n passwordToggle: {\n position: \"absolute\",\n right: \"10px\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"0\",\n display: \"flex\",\n alignItems: \"center\",\n color: \"#9ca3af\",\n },\n button: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"none\",\n backgroundColor: \"#111827\",\n color: \"#ffffff\",\n fontSize: \"14px\",\n fontWeight: 500,\n cursor: \"pointer\",\n transition: \"opacity 0.15s\",\n },\n buttonDisabled: {\n opacity: 0.5,\n pointerEvents: \"none\",\n },\n footer: {\n textAlign: \"center\",\n fontSize: \"12px\",\n color: \"#9ca3af\",\n },\n link: {\n color: \"#6b7280\",\n textDecoration: \"underline\",\n textUnderlineOffset: \"3px\",\n },\n};\n\nconst darkModeCSS = `\n @media (prefers-color-scheme: dark) {\n .lite-auth-page { background-color: #09090b !important; }\n .lite-auth-appname { color: #818cf8 !important; }\n .lite-auth-title { color: #fafafa !important; }\n .lite-auth-desc { color: #a1a1aa !important; }\n .lite-auth-card {\n background-color: #18181b !important;\n border-color: #27272a !important;\n box-shadow: none !important;\n }\n .lite-auth-error {\n background-color: rgba(239,68,68,0.1) !important;\n border-color: rgba(239,68,68,0.3) !important;\n color: #f87171 !important;\n }\n .lite-auth-label { color: #e4e4e7 !important; }\n .lite-auth-input {\n background-color: transparent !important;\n border-color: #3f3f46 !important;\n color: #fafafa !important;\n }\n .lite-auth-input::placeholder { color: #52525b !important; }\n .lite-auth-input:focus {\n border-color: #6366f1 !important;\n box-shadow: 0 0 0 3px rgba(99,102,241,0.2) !important;\n }\n .lite-auth-btn {\n background-color: #fafafa !important;\n color: #09090b !important;\n }\n .lite-auth-footer { color: #52525b !important; }\n .lite-auth-link { color: #71717a !important; }\n .lite-auth-pw-toggle { color: #52525b !important; }\n }\n`;\n\nexport function LiteLoginPage({\n appName,\n title = \"Sign in\",\n description = \"Enter your credentials to continue\",\n}: LiteLoginPageProps) {\n const { login } = useLiteAuth();\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [focusedField, setFocusedField] = useState<string | null>(null);\n const [showPassword, setShowPassword] = useState(false);\n\n async function handleSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setError(\"\");\n setLoading(true);\n\n const form = e.currentTarget;\n const result = await login({\n email: (form.elements.namedItem(\"email\") as HTMLInputElement).value,\n password: (form.elements.namedItem(\"password\") as HTMLInputElement).value,\n });\n\n setLoading(false);\n\n if (result.error) {\n setError(result.error);\n }\n }\n\n return (\n <>\n <style>{darkModeCSS}</style>\n <div className=\"lite-auth-page\" style={styles.page}>\n <div style={styles.container}>\n <div style={styles.header}>\n {appName && <p className=\"lite-auth-appname\" style={styles.appName}>{appName}</p>}\n <h1 className=\"lite-auth-title\" style={styles.title}>{title}</h1>\n <p className=\"lite-auth-desc\" style={styles.description}>{description}</p>\n </div>\n\n <div className=\"lite-auth-card\" style={styles.card}>\n {error && (\n <div className=\"lite-auth-error\" style={styles.error}>{error}</div>\n )}\n\n <form onSubmit={handleSubmit} style={{ display: \"flex\", flexDirection: \"column\", gap: \"16px\" }}>\n <div style={styles.field}>\n <label htmlFor=\"email\" className=\"lite-auth-label\" style={styles.label}>Email</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n autoComplete=\"email\"\n placeholder=\"you@example.com\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n ...(focusedField === \"email\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"email\")}\n onBlur={() => setFocusedField(null)}\n />\n </div>\n\n <div style={styles.field}>\n <label htmlFor=\"password\" className=\"lite-auth-label\" style={styles.label}>Password</label>\n <div style={styles.passwordWrapper}>\n <input\n id=\"password\"\n name=\"password\"\n type={showPassword ? \"text\" : \"password\"}\n required\n autoComplete=\"current-password\"\n placeholder=\"••••••••\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n paddingRight: \"36px\",\n ...(focusedField === \"password\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"password\")}\n onBlur={() => setFocusedField(null)}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword((v) => !v)}\n className=\"lite-auth-pw-toggle\"\n style={styles.passwordToggle}\n aria-label={showPassword ? \"Hide password\" : \"Show password\"}\n tabIndex={-1}\n >\n {showPassword ? (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"/>\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"/>\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"/>\n </svg>\n ) : (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n </svg>\n )}\n </button>\n </div>\n </div>\n\n <button\n type=\"submit\"\n disabled={loading}\n className=\"lite-auth-btn\"\n style={{\n ...styles.button,\n ...(loading ? styles.buttonDisabled : {}),\n }}\n >\n {loading ? \"Signing in…\" : \"Sign in\"}\n </button>\n </form>\n </div>\n\n <p className=\"lite-auth-footer\" style={styles.footer}>\n Powered by{\" \"}\n <a\n href=\"https://github.com/amide-init/next-lite-auth\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"lite-auth-link\"\n style={styles.link}\n >\n next-lite-auth\n </a>\n </p>\n </div>\n </div>\n </>\n );\n}\n","export function matchesProtect(patterns: (string | RegExp)[], pathname: string): boolean {\n return patterns.some((p) =>\n p instanceof RegExp\n ? p.test(pathname)\n : p === \"/\" || pathname === p || pathname.startsWith(p + \"/\")\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","user"]}
|
package/dist/client.mjs
CHANGED
|
@@ -90,6 +90,22 @@ var styles = {
|
|
|
90
90
|
border: "1px solid #6366f1",
|
|
91
91
|
boxShadow: "0 0 0 3px rgba(99,102,241,0.15)"
|
|
92
92
|
},
|
|
93
|
+
passwordWrapper: {
|
|
94
|
+
position: "relative",
|
|
95
|
+
display: "flex",
|
|
96
|
+
alignItems: "center"
|
|
97
|
+
},
|
|
98
|
+
passwordToggle: {
|
|
99
|
+
position: "absolute",
|
|
100
|
+
right: "10px",
|
|
101
|
+
background: "none",
|
|
102
|
+
border: "none",
|
|
103
|
+
cursor: "pointer",
|
|
104
|
+
padding: "0",
|
|
105
|
+
display: "flex",
|
|
106
|
+
alignItems: "center",
|
|
107
|
+
color: "#9ca3af"
|
|
108
|
+
},
|
|
93
109
|
button: {
|
|
94
110
|
height: "36px",
|
|
95
111
|
width: "100%",
|
|
@@ -150,6 +166,7 @@ var darkModeCSS = `
|
|
|
150
166
|
}
|
|
151
167
|
.lite-auth-footer { color: #52525b !important; }
|
|
152
168
|
.lite-auth-link { color: #71717a !important; }
|
|
169
|
+
.lite-auth-pw-toggle { color: #52525b !important; }
|
|
153
170
|
}
|
|
154
171
|
`;
|
|
155
172
|
function LiteLoginPage({
|
|
@@ -161,6 +178,7 @@ function LiteLoginPage({
|
|
|
161
178
|
const [error, setError] = useState("");
|
|
162
179
|
const [loading, setLoading] = useState(false);
|
|
163
180
|
const [focusedField, setFocusedField] = useState(null);
|
|
181
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
164
182
|
async function handleSubmit(e) {
|
|
165
183
|
e.preventDefault();
|
|
166
184
|
setError("");
|
|
@@ -209,24 +227,46 @@ function LiteLoginPage({
|
|
|
209
227
|
] }),
|
|
210
228
|
/* @__PURE__ */ jsxs("div", { style: styles.field, children: [
|
|
211
229
|
/* @__PURE__ */ jsx("label", { htmlFor: "password", className: "lite-auth-label", style: styles.label, children: "Password" }),
|
|
212
|
-
/* @__PURE__ */
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
+
/* @__PURE__ */ jsxs("div", { style: styles.passwordWrapper, children: [
|
|
231
|
+
/* @__PURE__ */ jsx(
|
|
232
|
+
"input",
|
|
233
|
+
{
|
|
234
|
+
id: "password",
|
|
235
|
+
name: "password",
|
|
236
|
+
type: showPassword ? "text" : "password",
|
|
237
|
+
required: true,
|
|
238
|
+
autoComplete: "current-password",
|
|
239
|
+
placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
|
|
240
|
+
className: "lite-auth-input",
|
|
241
|
+
style: {
|
|
242
|
+
...styles.input,
|
|
243
|
+
paddingRight: "36px",
|
|
244
|
+
...focusedField === "password" ? styles.inputFocus : {}
|
|
245
|
+
},
|
|
246
|
+
onFocus: () => setFocusedField("password"),
|
|
247
|
+
onBlur: () => setFocusedField(null)
|
|
248
|
+
}
|
|
249
|
+
),
|
|
250
|
+
/* @__PURE__ */ jsx(
|
|
251
|
+
"button",
|
|
252
|
+
{
|
|
253
|
+
type: "button",
|
|
254
|
+
onClick: () => setShowPassword((v) => !v),
|
|
255
|
+
className: "lite-auth-pw-toggle",
|
|
256
|
+
style: styles.passwordToggle,
|
|
257
|
+
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
258
|
+
tabIndex: -1,
|
|
259
|
+
children: showPassword ? /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
260
|
+
/* @__PURE__ */ jsx("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94" }),
|
|
261
|
+
/* @__PURE__ */ jsx("path", { d: "M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19" }),
|
|
262
|
+
/* @__PURE__ */ jsx("line", { x1: "1", y1: "1", x2: "23", y2: "23" })
|
|
263
|
+
] }) : /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
264
|
+
/* @__PURE__ */ jsx("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
|
|
265
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" })
|
|
266
|
+
] })
|
|
267
|
+
}
|
|
268
|
+
)
|
|
269
|
+
] })
|
|
230
270
|
] }),
|
|
231
271
|
/* @__PURE__ */ jsx(
|
|
232
272
|
"button",
|
package/dist/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/LiteAuthProvider.tsx","../src/client/LiteLoginPage.tsx","../src/core/matchesProtect.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, useState, useEffect, useCallback, ReactNode } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { PublicUser } from \"../core/types\";\nimport { LiteLoginPage } from \"./LiteLoginPage\";\nimport { matchesProtect } from \"../core/matchesProtect\";\n\ntype LiteAuthContextValue = {\n user: PublicUser | null;\n loading: boolean;\n login: (creds: { email: string; password: string }) => Promise<{ error?: string }>;\n logout: () => Promise<void>;\n};\n\nconst LiteAuthContext = createContext<LiteAuthContextValue | null>(null);\n\ntype LiteAuthProviderProps = {\n children: ReactNode;\n protect?: (string | RegExp)[];\n appName?: string;\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function LiteAuthProvider({\n children,\n protect = [],\n appName,\n loginPath = \"/api/auth/login\",\n logoutPath = \"/api/auth/logout\",\n mePath = \"/api/auth/me\",\n}: LiteAuthProviderProps) {\n const [user, setUser] = useState<PublicUser | null>(null);\n const [loading, setLoading] = useState(true);\n const pathname = usePathname();\n\n useEffect(() => {\n fetch(mePath)\n .then((r) => r.json())\n .then(({ user }) => setUser(user ?? null))\n .catch(() => setUser(null))\n .finally(() => setLoading(false));\n }, [mePath]);\n\n const login = useCallback(\n async ({ email, password }: { email: string; password: string }) => {\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 setUser(data.user);\n return {};\n },\n [loginPath]\n );\n\n const logout = useCallback(async () => {\n await fetch(logoutPath, { method: \"POST\" });\n setUser(null);\n }, [logoutPath]);\n\n const value = { user, loading, login, logout };\n\n const isProtected = matchesProtect(protect, pathname);\n\n if (loading) {\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n }\n\n if (!user && isProtected) {\n return (\n <LiteAuthContext.Provider value={value}>\n <LiteLoginPage appName={appName} />\n </LiteAuthContext.Provider>\n );\n }\n\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n}\n\nexport function useLiteAuth(): LiteAuthContextValue {\n const ctx = useContext(LiteAuthContext);\n if (!ctx) throw new Error(\"useLiteAuth must be used inside <LiteAuthProvider>\");\n return ctx;\n}\n","\"use client\";\n\nimport { CSSProperties, FormEvent, useState } from \"react\";\nimport { useLiteAuth } from \"./LiteAuthProvider\";\n\ntype LiteLoginPageProps = {\n appName?: string;\n title?: string;\n description?: string;\n};\n\nconst styles: Record<string, CSSProperties> = {\n page: {\n minHeight: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f9fafb\",\n padding: \"0 16px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n container: {\n width: \"100%\",\n maxWidth: \"360px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"24px\",\n },\n header: {\n textAlign: \"center\",\n },\n appName: {\n margin: \"0 0 8px\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"#6366f1\",\n textTransform: \"uppercase\" as const,\n letterSpacing: \"0.08em\",\n },\n title: {\n margin: \"0 0 4px\",\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#111827\",\n letterSpacing: \"-0.01em\",\n },\n description: {\n margin: 0,\n fontSize: \"14px\",\n color: \"#6b7280\",\n },\n card: {\n backgroundColor: \"#ffffff\",\n border: \"1px solid #e5e7eb\",\n borderRadius: \"12px\",\n padding: \"24px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"16px\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.07)\",\n },\n error: {\n backgroundColor: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: \"6px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"#dc2626\",\n },\n field: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"6px\",\n },\n label: {\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"#374151\",\n },\n input: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"1px solid #d1d5db\",\n padding: \"0 12px\",\n fontSize: \"14px\",\n color: \"#111827\",\n backgroundColor: \"#fff\",\n outline: \"none\",\n boxSizing: \"border-box\",\n transition: \"border-color 0.15s\",\n },\n inputFocus: {\n border: \"1px solid #6366f1\",\n boxShadow: \"0 0 0 3px rgba(99,102,241,0.15)\",\n },\n button: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"none\",\n backgroundColor: \"#111827\",\n color: \"#ffffff\",\n fontSize: \"14px\",\n fontWeight: 500,\n cursor: \"pointer\",\n transition: \"opacity 0.15s\",\n },\n buttonDisabled: {\n opacity: 0.5,\n pointerEvents: \"none\",\n },\n footer: {\n textAlign: \"center\",\n fontSize: \"12px\",\n color: \"#9ca3af\",\n },\n link: {\n color: \"#6b7280\",\n textDecoration: \"underline\",\n textUnderlineOffset: \"3px\",\n },\n};\n\nconst darkModeCSS = `\n @media (prefers-color-scheme: dark) {\n .lite-auth-page { background-color: #09090b !important; }\n .lite-auth-appname { color: #818cf8 !important; }\n .lite-auth-title { color: #fafafa !important; }\n .lite-auth-desc { color: #a1a1aa !important; }\n .lite-auth-card {\n background-color: #18181b !important;\n border-color: #27272a !important;\n box-shadow: none !important;\n }\n .lite-auth-error {\n background-color: rgba(239,68,68,0.1) !important;\n border-color: rgba(239,68,68,0.3) !important;\n color: #f87171 !important;\n }\n .lite-auth-label { color: #e4e4e7 !important; }\n .lite-auth-input {\n background-color: transparent !important;\n border-color: #3f3f46 !important;\n color: #fafafa !important;\n }\n .lite-auth-input::placeholder { color: #52525b !important; }\n .lite-auth-input:focus {\n border-color: #6366f1 !important;\n box-shadow: 0 0 0 3px rgba(99,102,241,0.2) !important;\n }\n .lite-auth-btn {\n background-color: #fafafa !important;\n color: #09090b !important;\n }\n .lite-auth-footer { color: #52525b !important; }\n .lite-auth-link { color: #71717a !important; }\n }\n`;\n\nexport function LiteLoginPage({\n appName,\n title = \"Sign in\",\n description = \"Enter your credentials to continue\",\n}: LiteLoginPageProps) {\n const { login } = useLiteAuth();\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [focusedField, setFocusedField] = useState<string | null>(null);\n\n async function handleSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setError(\"\");\n setLoading(true);\n\n const form = e.currentTarget;\n const result = await login({\n email: (form.elements.namedItem(\"email\") as HTMLInputElement).value,\n password: (form.elements.namedItem(\"password\") as HTMLInputElement).value,\n });\n\n setLoading(false);\n\n if (result.error) {\n setError(result.error);\n }\n }\n\n return (\n <>\n <style>{darkModeCSS}</style>\n <div className=\"lite-auth-page\" style={styles.page}>\n <div style={styles.container}>\n <div style={styles.header}>\n {appName && <p className=\"lite-auth-appname\" style={styles.appName}>{appName}</p>}\n <h1 className=\"lite-auth-title\" style={styles.title}>{title}</h1>\n <p className=\"lite-auth-desc\" style={styles.description}>{description}</p>\n </div>\n\n <div className=\"lite-auth-card\" style={styles.card}>\n {error && (\n <div className=\"lite-auth-error\" style={styles.error}>{error}</div>\n )}\n\n <form onSubmit={handleSubmit} style={{ display: \"flex\", flexDirection: \"column\", gap: \"16px\" }}>\n <div style={styles.field}>\n <label htmlFor=\"email\" className=\"lite-auth-label\" style={styles.label}>Email</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n autoComplete=\"email\"\n placeholder=\"you@example.com\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n ...(focusedField === \"email\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"email\")}\n onBlur={() => setFocusedField(null)}\n />\n </div>\n\n <div style={styles.field}>\n <label htmlFor=\"password\" className=\"lite-auth-label\" style={styles.label}>Password</label>\n <input\n id=\"password\"\n name=\"password\"\n type=\"password\"\n required\n autoComplete=\"current-password\"\n placeholder=\"••••••••\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n ...(focusedField === \"password\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"password\")}\n onBlur={() => setFocusedField(null)}\n />\n </div>\n\n <button\n type=\"submit\"\n disabled={loading}\n className=\"lite-auth-btn\"\n style={{\n ...styles.button,\n ...(loading ? styles.buttonDisabled : {}),\n }}\n >\n {loading ? \"Signing in…\" : \"Sign in\"}\n </button>\n </form>\n </div>\n\n <p className=\"lite-auth-footer\" style={styles.footer}>\n Powered by{\" \"}\n <a\n href=\"https://github.com/amide-init/next-lite-auth\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"lite-auth-link\"\n style={styles.link}\n >\n next-lite-auth\n </a>\n </p>\n </div>\n </div>\n </>\n );\n}\n","export function matchesProtect(patterns: (string | RegExp)[], pathname: string): boolean {\n return patterns.some((p) =>\n p instanceof RegExp\n ? p.test(pathname)\n : p === \"/\" || pathname === p || pathname.startsWith(p + \"/\")\n );\n}\n"],"mappings":"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","names":["useState","jsx","useState","user"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/LiteAuthProvider.tsx","../src/client/LiteLoginPage.tsx","../src/core/matchesProtect.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, useState, useEffect, useCallback, ReactNode } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { PublicUser } from \"../core/types\";\nimport { LiteLoginPage } from \"./LiteLoginPage\";\nimport { matchesProtect } from \"../core/matchesProtect\";\n\ntype LiteAuthContextValue = {\n user: PublicUser | null;\n loading: boolean;\n login: (creds: { email: string; password: string }) => Promise<{ error?: string }>;\n logout: () => Promise<void>;\n};\n\nconst LiteAuthContext = createContext<LiteAuthContextValue | null>(null);\n\ntype LiteAuthProviderProps = {\n children: ReactNode;\n protect?: (string | RegExp)[];\n appName?: string;\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function LiteAuthProvider({\n children,\n protect = [],\n appName,\n loginPath = \"/api/auth/login\",\n logoutPath = \"/api/auth/logout\",\n mePath = \"/api/auth/me\",\n}: LiteAuthProviderProps) {\n const [user, setUser] = useState<PublicUser | null>(null);\n const [loading, setLoading] = useState(true);\n const pathname = usePathname();\n\n useEffect(() => {\n fetch(mePath)\n .then((r) => r.json())\n .then(({ user }) => setUser(user ?? null))\n .catch(() => setUser(null))\n .finally(() => setLoading(false));\n }, [mePath]);\n\n const login = useCallback(\n async ({ email, password }: { email: string; password: string }) => {\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 setUser(data.user);\n return {};\n },\n [loginPath]\n );\n\n const logout = useCallback(async () => {\n await fetch(logoutPath, { method: \"POST\" });\n setUser(null);\n }, [logoutPath]);\n\n const value = { user, loading, login, logout };\n\n const isProtected = matchesProtect(protect, pathname);\n\n if (loading) {\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n }\n\n if (!user && isProtected) {\n return (\n <LiteAuthContext.Provider value={value}>\n <LiteLoginPage appName={appName} />\n </LiteAuthContext.Provider>\n );\n }\n\n return (\n <LiteAuthContext.Provider value={value}>\n {children}\n </LiteAuthContext.Provider>\n );\n}\n\nexport function useLiteAuth(): LiteAuthContextValue {\n const ctx = useContext(LiteAuthContext);\n if (!ctx) throw new Error(\"useLiteAuth must be used inside <LiteAuthProvider>\");\n return ctx;\n}\n","\"use client\";\n\nimport { CSSProperties, FormEvent, useState } from \"react\";\nimport { useLiteAuth } from \"./LiteAuthProvider\";\n\ntype LiteLoginPageProps = {\n appName?: string;\n title?: string;\n description?: string;\n};\n\nconst styles: Record<string, CSSProperties> = {\n page: {\n minHeight: \"100vh\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"#f9fafb\",\n padding: \"0 16px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n container: {\n width: \"100%\",\n maxWidth: \"360px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"24px\",\n },\n header: {\n textAlign: \"center\",\n },\n appName: {\n margin: \"0 0 8px\",\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"#6366f1\",\n textTransform: \"uppercase\" as const,\n letterSpacing: \"0.08em\",\n },\n title: {\n margin: \"0 0 4px\",\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#111827\",\n letterSpacing: \"-0.01em\",\n },\n description: {\n margin: 0,\n fontSize: \"14px\",\n color: \"#6b7280\",\n },\n card: {\n backgroundColor: \"#ffffff\",\n border: \"1px solid #e5e7eb\",\n borderRadius: \"12px\",\n padding: \"24px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"16px\",\n boxShadow: \"0 1px 3px rgba(0,0,0,0.07)\",\n },\n error: {\n backgroundColor: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: \"6px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n color: \"#dc2626\",\n },\n field: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"6px\",\n },\n label: {\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"#374151\",\n },\n input: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"1px solid #d1d5db\",\n padding: \"0 12px\",\n fontSize: \"14px\",\n color: \"#111827\",\n backgroundColor: \"#fff\",\n outline: \"none\",\n boxSizing: \"border-box\",\n transition: \"border-color 0.15s\",\n },\n inputFocus: {\n border: \"1px solid #6366f1\",\n boxShadow: \"0 0 0 3px rgba(99,102,241,0.15)\",\n },\n passwordWrapper: {\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n },\n passwordToggle: {\n position: \"absolute\",\n right: \"10px\",\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n padding: \"0\",\n display: \"flex\",\n alignItems: \"center\",\n color: \"#9ca3af\",\n },\n button: {\n height: \"36px\",\n width: \"100%\",\n borderRadius: \"6px\",\n border: \"none\",\n backgroundColor: \"#111827\",\n color: \"#ffffff\",\n fontSize: \"14px\",\n fontWeight: 500,\n cursor: \"pointer\",\n transition: \"opacity 0.15s\",\n },\n buttonDisabled: {\n opacity: 0.5,\n pointerEvents: \"none\",\n },\n footer: {\n textAlign: \"center\",\n fontSize: \"12px\",\n color: \"#9ca3af\",\n },\n link: {\n color: \"#6b7280\",\n textDecoration: \"underline\",\n textUnderlineOffset: \"3px\",\n },\n};\n\nconst darkModeCSS = `\n @media (prefers-color-scheme: dark) {\n .lite-auth-page { background-color: #09090b !important; }\n .lite-auth-appname { color: #818cf8 !important; }\n .lite-auth-title { color: #fafafa !important; }\n .lite-auth-desc { color: #a1a1aa !important; }\n .lite-auth-card {\n background-color: #18181b !important;\n border-color: #27272a !important;\n box-shadow: none !important;\n }\n .lite-auth-error {\n background-color: rgba(239,68,68,0.1) !important;\n border-color: rgba(239,68,68,0.3) !important;\n color: #f87171 !important;\n }\n .lite-auth-label { color: #e4e4e7 !important; }\n .lite-auth-input {\n background-color: transparent !important;\n border-color: #3f3f46 !important;\n color: #fafafa !important;\n }\n .lite-auth-input::placeholder { color: #52525b !important; }\n .lite-auth-input:focus {\n border-color: #6366f1 !important;\n box-shadow: 0 0 0 3px rgba(99,102,241,0.2) !important;\n }\n .lite-auth-btn {\n background-color: #fafafa !important;\n color: #09090b !important;\n }\n .lite-auth-footer { color: #52525b !important; }\n .lite-auth-link { color: #71717a !important; }\n .lite-auth-pw-toggle { color: #52525b !important; }\n }\n`;\n\nexport function LiteLoginPage({\n appName,\n title = \"Sign in\",\n description = \"Enter your credentials to continue\",\n}: LiteLoginPageProps) {\n const { login } = useLiteAuth();\n const [error, setError] = useState(\"\");\n const [loading, setLoading] = useState(false);\n const [focusedField, setFocusedField] = useState<string | null>(null);\n const [showPassword, setShowPassword] = useState(false);\n\n async function handleSubmit(e: FormEvent<HTMLFormElement>) {\n e.preventDefault();\n setError(\"\");\n setLoading(true);\n\n const form = e.currentTarget;\n const result = await login({\n email: (form.elements.namedItem(\"email\") as HTMLInputElement).value,\n password: (form.elements.namedItem(\"password\") as HTMLInputElement).value,\n });\n\n setLoading(false);\n\n if (result.error) {\n setError(result.error);\n }\n }\n\n return (\n <>\n <style>{darkModeCSS}</style>\n <div className=\"lite-auth-page\" style={styles.page}>\n <div style={styles.container}>\n <div style={styles.header}>\n {appName && <p className=\"lite-auth-appname\" style={styles.appName}>{appName}</p>}\n <h1 className=\"lite-auth-title\" style={styles.title}>{title}</h1>\n <p className=\"lite-auth-desc\" style={styles.description}>{description}</p>\n </div>\n\n <div className=\"lite-auth-card\" style={styles.card}>\n {error && (\n <div className=\"lite-auth-error\" style={styles.error}>{error}</div>\n )}\n\n <form onSubmit={handleSubmit} style={{ display: \"flex\", flexDirection: \"column\", gap: \"16px\" }}>\n <div style={styles.field}>\n <label htmlFor=\"email\" className=\"lite-auth-label\" style={styles.label}>Email</label>\n <input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n required\n autoComplete=\"email\"\n placeholder=\"you@example.com\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n ...(focusedField === \"email\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"email\")}\n onBlur={() => setFocusedField(null)}\n />\n </div>\n\n <div style={styles.field}>\n <label htmlFor=\"password\" className=\"lite-auth-label\" style={styles.label}>Password</label>\n <div style={styles.passwordWrapper}>\n <input\n id=\"password\"\n name=\"password\"\n type={showPassword ? \"text\" : \"password\"}\n required\n autoComplete=\"current-password\"\n placeholder=\"••••••••\"\n className=\"lite-auth-input\"\n style={{\n ...styles.input,\n paddingRight: \"36px\",\n ...(focusedField === \"password\" ? styles.inputFocus : {}),\n }}\n onFocus={() => setFocusedField(\"password\")}\n onBlur={() => setFocusedField(null)}\n />\n <button\n type=\"button\"\n onClick={() => setShowPassword((v) => !v)}\n className=\"lite-auth-pw-toggle\"\n style={styles.passwordToggle}\n aria-label={showPassword ? \"Hide password\" : \"Show password\"}\n tabIndex={-1}\n >\n {showPassword ? (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"/>\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"/>\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"/>\n </svg>\n ) : (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>\n <circle cx=\"12\" cy=\"12\" r=\"3\"/>\n </svg>\n )}\n </button>\n </div>\n </div>\n\n <button\n type=\"submit\"\n disabled={loading}\n className=\"lite-auth-btn\"\n style={{\n ...styles.button,\n ...(loading ? styles.buttonDisabled : {}),\n }}\n >\n {loading ? \"Signing in…\" : \"Sign in\"}\n </button>\n </form>\n </div>\n\n <p className=\"lite-auth-footer\" style={styles.footer}>\n Powered by{\" \"}\n <a\n href=\"https://github.com/amide-init/next-lite-auth\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"lite-auth-link\"\n style={styles.link}\n >\n next-lite-auth\n </a>\n </p>\n </div>\n </div>\n </>\n );\n}\n","export function matchesProtect(patterns: (string | RegExp)[], pathname: string): boolean {\n return patterns.some((p) =>\n p instanceof RegExp\n ? p.test(pathname)\n : p === \"/\" || pathname === p || pathname.startsWith(p + \"/\")\n );\n}\n"],"mappings":";AAEA,SAAS,eAAe,YAAY,YAAAA,WAAU,WAAW,mBAA8B;AACvF,SAAS,mBAAmB;;;ACD5B,SAAmC,gBAAgB;AA6M/C,mBACE,KAGI,YAJN;AApMJ,IAAM,SAAwC;AAAA,EAC5C,MAAM;AAAA,IACJ,WAAW;AAAA,IACX,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,eAAe;AAAA,IACf,KAAK;AAAA,EACP;AAAA,EACA,QAAQ;AAAA,IACN,WAAW;AAAA,EACb;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,eAAe;AAAA,IACf,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,eAAe;AAAA,EACjB;AAAA,EACA,aAAa;AAAA,IACX,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AAAA,EACA,MAAM;AAAA,IACJ,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,SAAS;AAAA,IACT,SAAS;AAAA,IACT,eAAe;AAAA,IACf,KAAK;AAAA,IACL,WAAW;AAAA,EACb;AAAA,EACA,OAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,eAAe;AAAA,IACf,KAAK;AAAA,EACP;AAAA,EACA,OAAO;AAAA,IACL,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AAAA,EACA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AAAA,EACA,iBAAiB;AAAA,IACf,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AAAA,EACA,gBAAgB;AAAA,IACd,UAAU;AAAA,IACV,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,YAAY;AAAA,EACd;AAAA,EACA,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,eAAe;AAAA,EACjB;AAAA,EACA,QAAQ;AAAA,IACN,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AAAA,EACA,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACF;AAEA,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqCb,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAChB,GAAuB;AACrB,QAAM,EAAE,MAAM,IAAI,YAAY;AAC9B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AACpE,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AAEtD,iBAAe,aAAa,GAA+B;AACzD,MAAE,eAAe;AACjB,aAAS,EAAE;AACX,eAAW,IAAI;AAEf,UAAM,OAAO,EAAE;AACf,UAAM,SAAS,MAAM,MAAM;AAAA,MACzB,OAAQ,KAAK,SAAS,UAAU,OAAO,EAAuB;AAAA,MAC9D,UAAW,KAAK,SAAS,UAAU,UAAU,EAAuB;AAAA,IACtE,CAAC;AAED,eAAW,KAAK;AAEhB,QAAI,OAAO,OAAO;AAChB,eAAS,OAAO,KAAK;AAAA,IACvB;AAAA,EACF;AAEA,SACE,iCACE;AAAA,wBAAC,WAAO,uBAAY;AAAA,IACpB,oBAAC,SAAI,WAAU,kBAAiB,OAAO,OAAO,MAC5C,+BAAC,SAAI,OAAO,OAAO,WACjB;AAAA,2BAAC,SAAI,OAAO,OAAO,QAChB;AAAA,mBAAW,oBAAC,OAAE,WAAU,qBAAoB,OAAO,OAAO,SAAU,mBAAQ;AAAA,QAC7E,oBAAC,QAAG,WAAU,mBAAkB,OAAO,OAAO,OAAQ,iBAAM;AAAA,QAC5D,oBAAC,OAAE,WAAU,kBAAiB,OAAO,OAAO,aAAc,uBAAY;AAAA,SACxE;AAAA,MAEA,qBAAC,SAAI,WAAU,kBAAiB,OAAO,OAAO,MAC3C;AAAA,iBACC,oBAAC,SAAI,WAAU,mBAAkB,OAAO,OAAO,OAAQ,iBAAM;AAAA,QAG/D,qBAAC,UAAK,UAAU,cAAc,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,OAAO,GAC3F;AAAA,+BAAC,SAAI,OAAO,OAAO,OACjB;AAAA,gCAAC,WAAM,SAAQ,SAAQ,WAAU,mBAAkB,OAAO,OAAO,OAAO,mBAAK;AAAA,YAC7E;AAAA,cAAC;AAAA;AAAA,gBACC,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,UAAQ;AAAA,gBACR,cAAa;AAAA,gBACb,aAAY;AAAA,gBACZ,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,GAAG,OAAO;AAAA,kBACV,GAAI,iBAAiB,UAAU,OAAO,aAAa,CAAC;AAAA,gBACtD;AAAA,gBACA,SAAS,MAAM,gBAAgB,OAAO;AAAA,gBACtC,QAAQ,MAAM,gBAAgB,IAAI;AAAA;AAAA,YACpC;AAAA,aACF;AAAA,UAEA,qBAAC,SAAI,OAAO,OAAO,OACjB;AAAA,gCAAC,WAAM,SAAQ,YAAW,WAAU,mBAAkB,OAAO,OAAO,OAAO,sBAAQ;AAAA,YACnF,qBAAC,SAAI,OAAO,OAAO,iBACjB;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,IAAG;AAAA,kBACH,MAAK;AAAA,kBACL,MAAM,eAAe,SAAS;AAAA,kBAC9B,UAAQ;AAAA,kBACR,cAAa;AAAA,kBACb,aAAY;AAAA,kBACZ,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,GAAG,OAAO;AAAA,oBACV,cAAc;AAAA,oBACd,GAAI,iBAAiB,aAAa,OAAO,aAAa,CAAC;AAAA,kBACzD;AAAA,kBACA,SAAS,MAAM,gBAAgB,UAAU;AAAA,kBACzC,QAAQ,MAAM,gBAAgB,IAAI;AAAA;AAAA,cACpC;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAAA,kBACxC,WAAU;AAAA,kBACV,OAAO,OAAO;AAAA,kBACd,cAAY,eAAe,kBAAkB;AAAA,kBAC7C,UAAU;AAAA,kBAET,yBACC,qBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACrI;AAAA,wCAAC,UAAK,GAAE,mFAAiF;AAAA,oBACzF,oBAAC,UAAK,GAAE,0EAAwE;AAAA,oBAChF,oBAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,MAAI;AAAA,qBACrC,IAEA,qBAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACrI;AAAA,wCAAC,UAAK,GAAE,gDAA8C;AAAA,oBACtD,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAG;AAAA,qBAC/B;AAAA;AAAA,cAEJ;AAAA,eACF;AAAA,aACF;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,UAAU;AAAA,cACV,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,GAAG,OAAO;AAAA,gBACV,GAAI,UAAU,OAAO,iBAAiB,CAAC;AAAA,cACzC;AAAA,cAEC,oBAAU,qBAAgB;AAAA;AAAA,UAC7B;AAAA,WACF;AAAA,SACF;AAAA,MAEA,qBAAC,OAAE,WAAU,oBAAmB,OAAO,OAAO,QAAQ;AAAA;AAAA,QACzC;AAAA,QACX;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,QAAO;AAAA,YACP,KAAI;AAAA,YACJ,WAAU;AAAA,YACV,OAAO,OAAO;AAAA,YACf;AAAA;AAAA,QAED;AAAA,SACF;AAAA,OACF,GACF;AAAA,KACF;AAEJ;;;AC3TO,SAAS,eAAe,UAA+B,UAA2B;AACvF,SAAO,SAAS;AAAA,IAAK,CAAC,MACpB,aAAa,SACT,EAAE,KAAK,QAAQ,IACf,MAAM,OAAO,aAAa,KAAK,SAAS,WAAW,IAAI,GAAG;AAAA,EAChE;AACF;;;AFkEM,gBAAAC,YAAA;AAzDN,IAAM,kBAAkB,cAA2C,IAAI;AAWhE,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AAAA,EACA,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,SAAS;AACX,GAA0B;AACxB,QAAM,CAAC,MAAM,OAAO,IAAIC,UAA4B,IAAI;AACxD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,IAAI;AAC3C,QAAM,WAAW,YAAY;AAE7B,YAAU,MAAM;AACd,UAAM,MAAM,EACT,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EACpB,KAAK,CAAC,EAAE,MAAAC,MAAK,MAAM,QAAQA,SAAQ,IAAI,CAAC,EACxC,MAAM,MAAM,QAAQ,IAAI,CAAC,EACzB,QAAQ,MAAM,WAAW,KAAK,CAAC;AAAA,EACpC,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,QAAQ;AAAA,IACZ,OAAO,EAAE,OAAO,SAAS,MAA2C;AAClE,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,cAAQ,KAAK,IAAI;AACjB,aAAO,CAAC;AAAA,IACV;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,SAAS,YAAY,YAAY;AACrC,UAAM,MAAM,YAAY,EAAE,QAAQ,OAAO,CAAC;AAC1C,YAAQ,IAAI;AAAA,EACd,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,QAAQ,EAAE,MAAM,SAAS,OAAO,OAAO;AAE7C,QAAM,cAAc,eAAe,SAAS,QAAQ;AAEpD,MAAI,SAAS;AACX,WACE,gBAAAF,KAAC,gBAAgB,UAAhB,EAAyB,OACvB,UACH;AAAA,EAEJ;AAEA,MAAI,CAAC,QAAQ,aAAa;AACxB,WACE,gBAAAA,KAAC,gBAAgB,UAAhB,EAAyB,OACxB,0BAAAA,KAAC,iBAAc,SAAkB,GACnC;AAAA,EAEJ;AAEA,SACE,gBAAAA,KAAC,gBAAgB,UAAhB,EAAyB,OACvB,UACH;AAEJ;AAEO,SAAS,cAAoC;AAClD,QAAM,MAAM,WAAW,eAAe;AACtC,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,oDAAoD;AAC9E,SAAO;AACT;","names":["useState","jsx","useState","user"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-lite-auth",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Lightweight JWT auth for Next.js using static JSON users (no database)",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -20,6 +20,16 @@
|
|
|
20
20
|
"files": [
|
|
21
21
|
"dist"
|
|
22
22
|
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"dev": "tsup --watch",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "pnpm build",
|
|
29
|
+
"docs:dev": "vitepress dev docs",
|
|
30
|
+
"docs:build": "vitepress build docs",
|
|
31
|
+
"docs:preview": "vitepress preview docs"
|
|
32
|
+
},
|
|
23
33
|
"peerDependencies": {
|
|
24
34
|
"next": ">=13.0.0",
|
|
25
35
|
"react": ">=18.0.0"
|
|
@@ -41,6 +51,7 @@
|
|
|
41
51
|
"node": ">=20.0.0",
|
|
42
52
|
"pnpm": ">=9.0.0"
|
|
43
53
|
},
|
|
54
|
+
"packageManager": "pnpm@9.0.0",
|
|
44
55
|
"author": "amide-init",
|
|
45
56
|
"repository": {
|
|
46
57
|
"type": "git",
|
|
@@ -56,14 +67,5 @@
|
|
|
56
67
|
"jwt",
|
|
57
68
|
"lightweight"
|
|
58
69
|
],
|
|
59
|
-
"license": "MIT"
|
|
60
|
-
|
|
61
|
-
"build": "tsup",
|
|
62
|
-
"dev": "tsup --watch",
|
|
63
|
-
"test": "vitest run",
|
|
64
|
-
"typecheck": "tsc --noEmit",
|
|
65
|
-
"docs:dev": "vitepress dev docs",
|
|
66
|
-
"docs:build": "vitepress build docs",
|
|
67
|
-
"docs:preview": "vitepress preview docs"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
+
"license": "MIT"
|
|
71
|
+
}
|