next-lite-auth 0.2.0 → 0.2.2

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/dist/client.d.mts CHANGED
@@ -22,18 +22,20 @@ type LiteAuthContextValue = {
22
22
  };
23
23
  type LiteAuthProviderProps = {
24
24
  children: ReactNode;
25
- protect?: string[];
25
+ protect?: (string | RegExp)[];
26
+ appName?: string;
26
27
  loginPath?: string;
27
28
  logoutPath?: string;
28
29
  mePath?: string;
29
30
  };
30
- declare function LiteAuthProvider({ children, protect, loginPath, logoutPath, mePath, }: LiteAuthProviderProps): react_jsx_runtime.JSX.Element;
31
+ declare function LiteAuthProvider({ children, protect, appName, loginPath, logoutPath, mePath, }: LiteAuthProviderProps): react_jsx_runtime.JSX.Element;
31
32
  declare function useLiteAuth(): LiteAuthContextValue;
32
33
 
33
34
  type LiteLoginPageProps = {
35
+ appName?: string;
34
36
  title?: string;
35
37
  description?: string;
36
38
  };
37
- declare function LiteLoginPage({ title, description, }: LiteLoginPageProps): react_jsx_runtime.JSX.Element;
39
+ declare function LiteLoginPage({ appName, title, description, }: LiteLoginPageProps): react_jsx_runtime.JSX.Element;
38
40
 
39
41
  export { LiteAuthProvider, LiteLoginPage, useLiteAuth };
package/dist/client.d.ts CHANGED
@@ -22,18 +22,20 @@ type LiteAuthContextValue = {
22
22
  };
23
23
  type LiteAuthProviderProps = {
24
24
  children: ReactNode;
25
- protect?: string[];
25
+ protect?: (string | RegExp)[];
26
+ appName?: string;
26
27
  loginPath?: string;
27
28
  logoutPath?: string;
28
29
  mePath?: string;
29
30
  };
30
- declare function LiteAuthProvider({ children, protect, loginPath, logoutPath, mePath, }: LiteAuthProviderProps): react_jsx_runtime.JSX.Element;
31
+ declare function LiteAuthProvider({ children, protect, appName, loginPath, logoutPath, mePath, }: LiteAuthProviderProps): react_jsx_runtime.JSX.Element;
31
32
  declare function useLiteAuth(): LiteAuthContextValue;
32
33
 
33
34
  type LiteLoginPageProps = {
35
+ appName?: string;
34
36
  title?: string;
35
37
  description?: string;
36
38
  };
37
- declare function LiteLoginPage({ title, description, }: LiteLoginPageProps): react_jsx_runtime.JSX.Element;
39
+ declare function LiteLoginPage({ appName, title, description, }: LiteLoginPageProps): react_jsx_runtime.JSX.Element;
38
40
 
39
41
  export { LiteAuthProvider, LiteLoginPage, useLiteAuth };
package/dist/client.js CHANGED
@@ -53,6 +53,14 @@ var styles = {
53
53
  header: {
54
54
  textAlign: "center"
55
55
  },
56
+ appName: {
57
+ margin: "0 0 8px",
58
+ fontSize: "13px",
59
+ fontWeight: 600,
60
+ color: "#6366f1",
61
+ textTransform: "uppercase",
62
+ letterSpacing: "0.08em"
63
+ },
56
64
  title: {
57
65
  margin: "0 0 4px",
58
66
  fontSize: "22px",
@@ -107,7 +115,7 @@ var styles = {
107
115
  transition: "border-color 0.15s"
108
116
  },
109
117
  inputFocus: {
110
- borderColor: "#6366f1",
118
+ border: "1px solid #6366f1",
111
119
  boxShadow: "0 0 0 3px rgba(99,102,241,0.15)"
112
120
  },
113
121
  button: {
@@ -140,6 +148,7 @@ var styles = {
140
148
  var darkModeCSS = `
141
149
  @media (prefers-color-scheme: dark) {
142
150
  .lite-auth-page { background-color: #09090b !important; }
151
+ .lite-auth-appname { color: #818cf8 !important; }
143
152
  .lite-auth-title { color: #fafafa !important; }
144
153
  .lite-auth-desc { color: #a1a1aa !important; }
145
154
  .lite-auth-card {
@@ -172,6 +181,7 @@ var darkModeCSS = `
172
181
  }
173
182
  `;
174
183
  function LiteLoginPage({
184
+ appName,
175
185
  title = "Sign in",
176
186
  description = "Enter your credentials to continue"
177
187
  }) {
@@ -197,6 +207,7 @@ function LiteLoginPage({
197
207
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: darkModeCSS }),
198
208
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "lite-auth-page", style: styles.page, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.container, children: [
199
209
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.header, children: [
210
+ appName && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "lite-auth-appname", style: styles.appName, children: appName }),
200
211
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "lite-auth-title", style: styles.title, children: title }),
201
212
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "lite-auth-desc", style: styles.description, children: description })
202
213
  ] }),
@@ -279,12 +290,20 @@ function LiteLoginPage({
279
290
  ] });
280
291
  }
281
292
 
293
+ // src/core/matchesProtect.ts
294
+ function matchesProtect(patterns, pathname) {
295
+ return patterns.some(
296
+ (p) => p instanceof RegExp ? p.test(pathname) : p === "/" || pathname === p || pathname.startsWith(p + "/")
297
+ );
298
+ }
299
+
282
300
  // src/client/LiteAuthProvider.tsx
283
301
  var import_jsx_runtime2 = require("react/jsx-runtime");
284
302
  var LiteAuthContext = (0, import_react2.createContext)(null);
285
303
  function LiteAuthProvider({
286
304
  children,
287
305
  protect = [],
306
+ appName,
288
307
  loginPath = "/api/auth/login",
289
308
  logoutPath = "/api/auth/logout",
290
309
  mePath = "/api/auth/me"
@@ -314,14 +333,12 @@ function LiteAuthProvider({
314
333
  setUser(null);
315
334
  }, [logoutPath]);
316
335
  const value = { user, loading, login, logout };
317
- const isProtected = protect.some(
318
- (p) => pathname === p || pathname.startsWith(p + "/")
319
- );
336
+ const isProtected = matchesProtect(protect, pathname);
320
337
  if (loading) {
321
338
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LiteAuthContext.Provider, { value, children });
322
339
  }
323
340
  if (!user && isProtected) {
324
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LiteAuthContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LiteLoginPage, {}) });
341
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LiteAuthContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LiteLoginPage, { appName }) });
325
342
  }
326
343
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LiteAuthContext.Provider, { value, children });
327
344
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/index.ts","../src/client/LiteAuthProvider.tsx","../src/client/LiteLoginPage.tsx"],"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\";\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[];\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function LiteAuthProvider({\n children,\n protect = [],\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 = protect.some(\n (p) => pathname === p || pathname.startsWith(p + \"/\")\n );\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 />\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 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 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 borderColor: \"#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-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 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 <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"],"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 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"]}
package/dist/client.mjs CHANGED
@@ -25,6 +25,14 @@ var styles = {
25
25
  header: {
26
26
  textAlign: "center"
27
27
  },
28
+ appName: {
29
+ margin: "0 0 8px",
30
+ fontSize: "13px",
31
+ fontWeight: 600,
32
+ color: "#6366f1",
33
+ textTransform: "uppercase",
34
+ letterSpacing: "0.08em"
35
+ },
28
36
  title: {
29
37
  margin: "0 0 4px",
30
38
  fontSize: "22px",
@@ -79,7 +87,7 @@ var styles = {
79
87
  transition: "border-color 0.15s"
80
88
  },
81
89
  inputFocus: {
82
- borderColor: "#6366f1",
90
+ border: "1px solid #6366f1",
83
91
  boxShadow: "0 0 0 3px rgba(99,102,241,0.15)"
84
92
  },
85
93
  button: {
@@ -112,6 +120,7 @@ var styles = {
112
120
  var darkModeCSS = `
113
121
  @media (prefers-color-scheme: dark) {
114
122
  .lite-auth-page { background-color: #09090b !important; }
123
+ .lite-auth-appname { color: #818cf8 !important; }
115
124
  .lite-auth-title { color: #fafafa !important; }
116
125
  .lite-auth-desc { color: #a1a1aa !important; }
117
126
  .lite-auth-card {
@@ -144,6 +153,7 @@ var darkModeCSS = `
144
153
  }
145
154
  `;
146
155
  function LiteLoginPage({
156
+ appName,
147
157
  title = "Sign in",
148
158
  description = "Enter your credentials to continue"
149
159
  }) {
@@ -169,6 +179,7 @@ function LiteLoginPage({
169
179
  /* @__PURE__ */ jsx("style", { children: darkModeCSS }),
170
180
  /* @__PURE__ */ jsx("div", { className: "lite-auth-page", style: styles.page, children: /* @__PURE__ */ jsxs("div", { style: styles.container, children: [
171
181
  /* @__PURE__ */ jsxs("div", { style: styles.header, children: [
182
+ appName && /* @__PURE__ */ jsx("p", { className: "lite-auth-appname", style: styles.appName, children: appName }),
172
183
  /* @__PURE__ */ jsx("h1", { className: "lite-auth-title", style: styles.title, children: title }),
173
184
  /* @__PURE__ */ jsx("p", { className: "lite-auth-desc", style: styles.description, children: description })
174
185
  ] }),
@@ -251,12 +262,20 @@ function LiteLoginPage({
251
262
  ] });
252
263
  }
253
264
 
265
+ // src/core/matchesProtect.ts
266
+ function matchesProtect(patterns, pathname) {
267
+ return patterns.some(
268
+ (p) => p instanceof RegExp ? p.test(pathname) : p === "/" || pathname === p || pathname.startsWith(p + "/")
269
+ );
270
+ }
271
+
254
272
  // src/client/LiteAuthProvider.tsx
255
273
  import { jsx as jsx2 } from "react/jsx-runtime";
256
274
  var LiteAuthContext = createContext(null);
257
275
  function LiteAuthProvider({
258
276
  children,
259
277
  protect = [],
278
+ appName,
260
279
  loginPath = "/api/auth/login",
261
280
  logoutPath = "/api/auth/logout",
262
281
  mePath = "/api/auth/me"
@@ -286,14 +305,12 @@ function LiteAuthProvider({
286
305
  setUser(null);
287
306
  }, [logoutPath]);
288
307
  const value = { user, loading, login, logout };
289
- const isProtected = protect.some(
290
- (p) => pathname === p || pathname.startsWith(p + "/")
291
- );
308
+ const isProtected = matchesProtect(protect, pathname);
292
309
  if (loading) {
293
310
  return /* @__PURE__ */ jsx2(LiteAuthContext.Provider, { value, children });
294
311
  }
295
312
  if (!user && isProtected) {
296
- return /* @__PURE__ */ jsx2(LiteAuthContext.Provider, { value, children: /* @__PURE__ */ jsx2(LiteLoginPage, {}) });
313
+ return /* @__PURE__ */ jsx2(LiteAuthContext.Provider, { value, children: /* @__PURE__ */ jsx2(LiteLoginPage, { appName }) });
297
314
  }
298
315
  return /* @__PURE__ */ jsx2(LiteAuthContext.Provider, { value, children });
299
316
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/LiteAuthProvider.tsx","../src/client/LiteLoginPage.tsx"],"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\";\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[];\n loginPath?: string;\n logoutPath?: string;\n mePath?: string;\n};\n\nexport function LiteAuthProvider({\n children,\n protect = [],\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 = protect.some(\n (p) => pathname === p || pathname.startsWith(p + \"/\")\n );\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 />\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 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 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 borderColor: \"#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-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 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 <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"],"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 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":";AAEA,SAAS,eAAe,YAAY,YAAAA,WAAU,WAAW,mBAA8B;AACvF,SAAS,mBAAmB;;;ACD5B,SAAmC,gBAAgB;AA2L/C,mBACE,KAGI,YAJN;AAlLJ,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,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;AAoCb,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;AAEpE,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;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,aAAa,OAAO,aAAa,CAAC;AAAA,gBACzD;AAAA,gBACA,SAAS,MAAM,gBAAgB,UAAU;AAAA,gBACzC,QAAQ,MAAM,gBAAgB,IAAI;AAAA;AAAA,YACpC;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;;;ACjRO,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/dist/index.d.mts CHANGED
@@ -21,7 +21,7 @@ declare function createLiteAuth(config: LiteAuthConfig): {
21
21
  POST: (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
22
22
  };
23
23
  middleware: (options: {
24
- protect: string[];
24
+ protect: (string | RegExp)[];
25
25
  redirectTo?: string;
26
26
  }) => (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
27
27
  getUserFromCookies: (cookies: next_dist_server_web_spec_extension_adapters_request_cookies.ReadonlyRequestCookies) => Promise<PublicUser | null>;
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ declare function createLiteAuth(config: LiteAuthConfig): {
21
21
  POST: (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
22
22
  };
23
23
  middleware: (options: {
24
- protect: string[];
24
+ protect: (string | RegExp)[];
25
25
  redirectTo?: string;
26
26
  }) => (req: next_server.NextRequest) => Promise<next_server.NextResponse>;
27
27
  getUserFromCookies: (cookies: next_dist_server_web_spec_extension_adapters_request_cookies.ReadonlyRequestCookies) => Promise<PublicUser | null>;
package/dist/index.js CHANGED
@@ -113,15 +113,22 @@ function getUserFromCookies(ctx) {
113
113
 
114
114
  // src/middleware/index.ts
115
115
  var import_server2 = require("next/server");
116
+
117
+ // src/core/matchesProtect.ts
118
+ function matchesProtect(patterns, pathname) {
119
+ return patterns.some(
120
+ (p) => p instanceof RegExp ? p.test(pathname) : p === "/" || pathname === p || pathname.startsWith(p + "/")
121
+ );
122
+ }
123
+
124
+ // src/middleware/index.ts
116
125
  function makeMiddleware(ctx) {
117
126
  return function middleware(options) {
118
127
  return async function(req) {
119
128
  if (!ctx.enabled) return import_server2.NextResponse.next();
120
129
  const { protect, redirectTo = "/login" } = options;
121
130
  const { pathname } = req.nextUrl;
122
- const isProtected = protect.some(
123
- (pattern) => pathname === pattern || pathname.startsWith(pattern + "/")
124
- );
131
+ const isProtected = matchesProtect(protect, pathname);
125
132
  if (!isProtected) {
126
133
  return import_server2.NextResponse.next();
127
134
  }
package/dist/index.js.map CHANGED
@@ -1 +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","../src/core/usersFromEnv.ts"],"sourcesContent":["export { createLiteAuth } from \"./core/createLiteAuth\";\nexport { usersFromEnv } from \"./core/usersFromEnv\";\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 makeHandlers(ctx: LiteAuthContext) {\n async function login(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,\n });\n return res;\n }\n\n async function logout(_req: NextRequest): Promise<NextResponse> {\n const res = NextResponse.json({ ok: true });\n res.cookies.set(ctx.cookieName, \"\", { httpOnly: true, path: \"/\", maxAge: 0 });\n return res;\n }\n\n async function me(req: NextRequest): Promise<NextResponse> {\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (!token) return NextResponse.json({ user: null }, { status: 401 });\n const user = await verifyToken(token, ctx.jwtSecret);\n if (!user) return NextResponse.json({ user: null }, { status: 401 });\n return NextResponse.json({ user });\n }\n\n async function GET(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ user: null });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"me\") return me(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n async function POST(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ ok: true });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"login\") return login(req);\n if (action === \"logout\") return logout(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return { GET, POST };\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 if (!ctx.enabled) return NextResponse.next();\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 { makeHandlers, 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 enabled: config.enabled ?? true,\n };\n\n return {\n handlers: makeHandlers(ctx),\n middleware: makeMiddleware(ctx),\n getUserFromCookies: getUserFromCookies(ctx),\n };\n}\n","import { User } from \"./types\";\n\nexport function usersFromEnv(): User[] {\n const raw = process.env.LITE_AUTH_USERS;\n\n if (!raw) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS environment variable is not set. \" +\n \"Set it to a JSON array of users, e.g.: \" +\n 'LITE_AUTH_USERS=\\'[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]\\''\n );\n }\n\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS is not valid JSON. \" +\n \"Expected a JSON array of users.\"\n );\n }\n\n if (!Array.isArray(parsed)) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS must be a JSON array, e.g.: \" +\n '[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]'\n );\n }\n\n return parsed as User[];\n}\n"],"mappings":"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","names":["import_server"]}
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/matchesProtect.ts","../src/core/createLiteAuth.ts","../src/core/usersFromEnv.ts"],"sourcesContent":["export { createLiteAuth } from \"./core/createLiteAuth\";\nexport { usersFromEnv } from \"./core/usersFromEnv\";\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 makeHandlers(ctx: LiteAuthContext) {\n async function login(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,\n });\n return res;\n }\n\n async function logout(_req: NextRequest): Promise<NextResponse> {\n const res = NextResponse.json({ ok: true });\n res.cookies.set(ctx.cookieName, \"\", { httpOnly: true, path: \"/\", maxAge: 0 });\n return res;\n }\n\n async function me(req: NextRequest): Promise<NextResponse> {\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (!token) return NextResponse.json({ user: null }, { status: 401 });\n const user = await verifyToken(token, ctx.jwtSecret);\n if (!user) return NextResponse.json({ user: null }, { status: 401 });\n return NextResponse.json({ user });\n }\n\n async function GET(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ user: null });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"me\") return me(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n async function POST(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ ok: true });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"login\") return login(req);\n if (action === \"logout\") return logout(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return { GET, POST };\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\";\nimport { matchesProtect } from \"../core/matchesProtect\";\n\ntype MiddlewareOptions = {\n protect: (string | RegExp)[];\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 if (!ctx.enabled) return NextResponse.next();\n const { protect, redirectTo = \"/login\" } = options;\n const { pathname } = req.nextUrl;\n\n const isProtected = matchesProtect(protect, pathname);\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","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","import { LiteAuthConfig, LiteAuthContext } from \"./types\";\nimport { makeHandlers, 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 enabled: config.enabled ?? true,\n };\n\n return {\n handlers: makeHandlers(ctx),\n middleware: makeMiddleware(ctx),\n getUserFromCookies: getUserFromCookies(ctx),\n };\n}\n","import { User } from \"./types\";\n\nexport function usersFromEnv(): User[] {\n const raw = process.env.LITE_AUTH_USERS;\n\n if (!raw) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS environment variable is not set. \" +\n \"Set it to a JSON array of users, e.g.: \" +\n 'LITE_AUTH_USERS=\\'[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]\\''\n );\n }\n\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS is not valid JSON. \" +\n \"Expected a JSON array of users.\"\n );\n }\n\n if (!Array.isArray(parsed)) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS must be a JSON array, e.g.: \" +\n '[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]'\n );\n }\n\n return parsed as User[];\n}\n"],"mappings":"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","names":["import_server"]}
package/dist/index.mjs CHANGED
@@ -86,15 +86,22 @@ function getUserFromCookies(ctx) {
86
86
 
87
87
  // src/middleware/index.ts
88
88
  import { NextResponse as NextResponse2 } from "next/server";
89
+
90
+ // src/core/matchesProtect.ts
91
+ function matchesProtect(patterns, pathname) {
92
+ return patterns.some(
93
+ (p) => p instanceof RegExp ? p.test(pathname) : p === "/" || pathname === p || pathname.startsWith(p + "/")
94
+ );
95
+ }
96
+
97
+ // src/middleware/index.ts
89
98
  function makeMiddleware(ctx) {
90
99
  return function middleware(options) {
91
100
  return async function(req) {
92
101
  if (!ctx.enabled) return NextResponse2.next();
93
102
  const { protect, redirectTo = "/login" } = options;
94
103
  const { pathname } = req.nextUrl;
95
- const isProtected = protect.some(
96
- (pattern) => pathname === pattern || pathname.startsWith(pattern + "/")
97
- );
104
+ const isProtected = matchesProtect(protect, pathname);
98
105
  if (!isProtected) {
99
106
  return NextResponse2.next();
100
107
  }
@@ -1 +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","../src/core/usersFromEnv.ts"],"sourcesContent":["import { NextRequest, NextResponse } from \"next/server\";\nimport { LiteAuthContext } from \"../core/types\";\nimport { signToken, verifyToken } from \"./jwt\";\n\nexport function makeHandlers(ctx: LiteAuthContext) {\n async function login(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,\n });\n return res;\n }\n\n async function logout(_req: NextRequest): Promise<NextResponse> {\n const res = NextResponse.json({ ok: true });\n res.cookies.set(ctx.cookieName, \"\", { httpOnly: true, path: \"/\", maxAge: 0 });\n return res;\n }\n\n async function me(req: NextRequest): Promise<NextResponse> {\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (!token) return NextResponse.json({ user: null }, { status: 401 });\n const user = await verifyToken(token, ctx.jwtSecret);\n if (!user) return NextResponse.json({ user: null }, { status: 401 });\n return NextResponse.json({ user });\n }\n\n async function GET(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ user: null });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"me\") return me(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n async function POST(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ ok: true });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"login\") return login(req);\n if (action === \"logout\") return logout(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return { GET, POST };\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 if (!ctx.enabled) return NextResponse.next();\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 { makeHandlers, 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 enabled: config.enabled ?? true,\n };\n\n return {\n handlers: makeHandlers(ctx),\n middleware: makeMiddleware(ctx),\n getUserFromCookies: getUserFromCookies(ctx),\n };\n}\n","import { User } from \"./types\";\n\nexport function usersFromEnv(): User[] {\n const raw = process.env.LITE_AUTH_USERS;\n\n if (!raw) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS environment variable is not set. \" +\n \"Set it to a JSON array of users, e.g.: \" +\n 'LITE_AUTH_USERS=\\'[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]\\''\n );\n }\n\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS is not valid JSON. \" +\n \"Expected a JSON array of users.\"\n );\n }\n\n if (!Array.isArray(parsed)) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS must be a JSON array, e.g.: \" +\n '[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]'\n );\n }\n\n return parsed as User[];\n}\n"],"mappings":"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","names":["NextResponse","NextResponse"]}
1
+ {"version":3,"sources":["../src/server/handlers.ts","../src/server/jwt.ts","../src/server/getUserFromCookies.ts","../src/middleware/index.ts","../src/core/matchesProtect.ts","../src/core/createLiteAuth.ts","../src/core/usersFromEnv.ts"],"sourcesContent":["import { NextRequest, NextResponse } from \"next/server\";\nimport { LiteAuthContext } from \"../core/types\";\nimport { signToken, verifyToken } from \"./jwt\";\n\nexport function makeHandlers(ctx: LiteAuthContext) {\n async function login(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,\n });\n return res;\n }\n\n async function logout(_req: NextRequest): Promise<NextResponse> {\n const res = NextResponse.json({ ok: true });\n res.cookies.set(ctx.cookieName, \"\", { httpOnly: true, path: \"/\", maxAge: 0 });\n return res;\n }\n\n async function me(req: NextRequest): Promise<NextResponse> {\n const token = req.cookies.get(ctx.cookieName)?.value;\n if (!token) return NextResponse.json({ user: null }, { status: 401 });\n const user = await verifyToken(token, ctx.jwtSecret);\n if (!user) return NextResponse.json({ user: null }, { status: 401 });\n return NextResponse.json({ user });\n }\n\n async function GET(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ user: null });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"me\") return me(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n async function POST(req: NextRequest): Promise<NextResponse> {\n if (!ctx.enabled) return NextResponse.json({ ok: true });\n const action = req.nextUrl.pathname.split(\"/\").pop();\n if (action === \"login\") return login(req);\n if (action === \"logout\") return logout(req);\n return NextResponse.json({ error: \"Not found\" }, { status: 404 });\n }\n\n return { GET, POST };\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\";\nimport { matchesProtect } from \"../core/matchesProtect\";\n\ntype MiddlewareOptions = {\n protect: (string | RegExp)[];\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 if (!ctx.enabled) return NextResponse.next();\n const { protect, redirectTo = \"/login\" } = options;\n const { pathname } = req.nextUrl;\n\n const isProtected = matchesProtect(protect, pathname);\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","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","import { LiteAuthConfig, LiteAuthContext } from \"./types\";\nimport { makeHandlers, 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 enabled: config.enabled ?? true,\n };\n\n return {\n handlers: makeHandlers(ctx),\n middleware: makeMiddleware(ctx),\n getUserFromCookies: getUserFromCookies(ctx),\n };\n}\n","import { User } from \"./types\";\n\nexport function usersFromEnv(): User[] {\n const raw = process.env.LITE_AUTH_USERS;\n\n if (!raw) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS environment variable is not set. \" +\n \"Set it to a JSON array of users, e.g.: \" +\n 'LITE_AUTH_USERS=\\'[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]\\''\n );\n }\n\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS is not valid JSON. \" +\n \"Expected a JSON array of users.\"\n );\n }\n\n if (!Array.isArray(parsed)) {\n throw new Error(\n \"[next-lite-auth] LITE_AUTH_USERS must be a JSON array, e.g.: \" +\n '[{\"email\":\"admin@example.com\",\"password\":\"secret\"}]'\n );\n }\n\n return parsed as User[];\n}\n"],"mappings":";AAAA,SAAsB,oBAAoB;;;ACA1C,SAAS,SAAS,iBAAiB;AAGnC,SAAS,UAAU,QAAgB;AACjC,SAAO,IAAI,YAAY,EAAE,OAAO,MAAM;AACxC;AAEA,eAAsB,UAAU,MAAkB,QAAiC;AACjF,SAAO,IAAI,QAAQ,EAAE,GAAG,KAAK,CAAC,EAC3B,mBAAmB,EAAE,KAAK,QAAQ,CAAC,EACnC,YAAY,EACZ,kBAAkB,IAAI,EACtB,KAAK,UAAU,MAAM,CAAC;AAC3B;AAEA,eAAsB,YAAY,OAAe,QAA4C;AAC3F,MAAI;AACF,UAAM,EAAE,QAAQ,IAAI,MAAM,UAAU,OAAO,UAAU,MAAM,CAAC;AAC5D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADlBO,SAAS,aAAa,KAAsB;AACjD,iBAAe,MAAM,KAAyC;AAC5D,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,IAAI,KAAK;AAAA,IACxB,QAAQ;AACN,aAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACrE;AAEA,UAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,QAAI,CAAC,SAAS,CAAC,UAAU;AACvB,aAAO,aAAa,KAAK,EAAE,OAAO,kCAAkC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACxF;AAEA,UAAM,OAAO,IAAI,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS,EAAE,aAAa,QAAQ;AAC/E,QAAI,CAAC,MAAM;AACT,aAAO,aAAa,KAAK,EAAE,OAAO,sBAAsB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC5E;AAEA,UAAM,EAAE,UAAU,GAAG,GAAG,WAAW,IAAI;AACvC,UAAM,QAAQ,MAAM,UAAU,YAAY,IAAI,SAAS;AAEvD,UAAM,MAAM,aAAa,KAAK,EAAE,MAAM,WAAW,CAAC;AAClD,QAAI,QAAQ,IAAI,IAAI,YAAY,OAAO;AAAA,MACrC,UAAU;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,MACjC,QAAQ,KAAK,KAAK,KAAK;AAAA,IACzB,CAAC;AACD,WAAO;AAAA,EACT;AAEA,iBAAe,OAAO,MAA0C;AAC9D,UAAM,MAAM,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC;AAC1C,QAAI,QAAQ,IAAI,IAAI,YAAY,IAAI,EAAE,UAAU,MAAM,MAAM,KAAK,QAAQ,EAAE,CAAC;AAC5E,WAAO;AAAA,EACT;AAEA,iBAAe,GAAG,KAAyC;AACzD,UAAM,QAAQ,IAAI,QAAQ,IAAI,IAAI,UAAU,GAAG;AAC/C,QAAI,CAAC,MAAO,QAAO,aAAa,KAAK,EAAE,MAAM,KAAK,GAAG,EAAE,QAAQ,IAAI,CAAC;AACpE,UAAM,OAAO,MAAM,YAAY,OAAO,IAAI,SAAS;AACnD,QAAI,CAAC,KAAM,QAAO,aAAa,KAAK,EAAE,MAAM,KAAK,GAAG,EAAE,QAAQ,IAAI,CAAC;AACnE,WAAO,aAAa,KAAK,EAAE,KAAK,CAAC;AAAA,EACnC;AAEA,iBAAe,IAAI,KAAyC;AAC1D,QAAI,CAAC,IAAI,QAAS,QAAO,aAAa,KAAK,EAAE,MAAM,KAAK,CAAC;AACzD,UAAM,SAAS,IAAI,QAAQ,SAAS,MAAM,GAAG,EAAE,IAAI;AACnD,QAAI,WAAW,KAAM,QAAO,GAAG,GAAG;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,YAAY,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClE;AAEA,iBAAe,KAAK,KAAyC;AAC3D,QAAI,CAAC,IAAI,QAAS,QAAO,aAAa,KAAK,EAAE,IAAI,KAAK,CAAC;AACvD,UAAM,SAAS,IAAI,QAAQ,SAAS,MAAM,GAAG,EAAE,IAAI;AACnD,QAAI,WAAW,QAAS,QAAO,MAAM,GAAG;AACxC,QAAI,WAAW,SAAU,QAAO,OAAO,GAAG;AAC1C,WAAO,aAAa,KAAK,EAAE,OAAO,YAAY,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAClE;AAEA,SAAO,EAAE,KAAK,KAAK;AACrB;;;AE/DO,SAAS,mBAAmB,KAAsB;AACvD,SAAO,eAAgB,SAA6D;AAClF,UAAM,QAAQ,QAAQ,IAAI,IAAI,UAAU,GAAG;AAC3C,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,YAAY,OAAO,IAAI,SAAS;AAAA,EACzC;AACF;;;ACVA,SAAsB,gBAAAA,qBAAoB;;;ACAnC,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;;;ADIO,SAAS,eAAe,KAAsB;AACnD,SAAO,SAAS,WAAW,SAA4B;AACrD,WAAO,eAAgB,KAAyC;AAC9D,UAAI,CAAC,IAAI,QAAS,QAAOC,cAAa,KAAK;AAC3C,YAAM,EAAE,SAAS,aAAa,SAAS,IAAI;AAC3C,YAAM,EAAE,SAAS,IAAI,IAAI;AAEzB,YAAM,cAAc,eAAe,SAAS,QAAQ;AAEpD,UAAI,CAAC,aAAa;AAChB,eAAOA,cAAa,KAAK;AAAA,MAC3B;AAEA,YAAM,QAAQ,IAAI,QAAQ,IAAI,IAAI,UAAU,GAAG;AAC/C,UAAI,OAAO;AACT,cAAM,OAAO,MAAM,YAAY,OAAO,IAAI,SAAS;AACnD,YAAI,KAAM,QAAOA,cAAa,KAAK;AAAA,MACrC;AAEA,YAAM,WAAW,IAAI,IAAI,YAAY,IAAI,GAAG;AAC5C,eAAS,aAAa,IAAI,QAAQ,QAAQ;AAC1C,aAAOA,cAAa,SAAS,QAAQ;AAAA,IACvC;AAAA,EACF;AACF;;;AE9BO,SAAS,eAAe,QAAwB;AACrD,QAAM,MAAuB;AAAA,IAC3B,OAAO,OAAO;AAAA,IACd,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO,cAAc;AAAA,IACjC,SAAS,OAAO,WAAW;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,UAAU,aAAa,GAAG;AAAA,IAC1B,YAAY,eAAe,GAAG;AAAA,IAC9B,oBAAoB,mBAAmB,GAAG;AAAA,EAC5C;AACF;;;ACfO,SAAS,eAAuB;AACrC,QAAM,MAAM,QAAQ,IAAI;AAExB,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IAGF;AAAA,EACF;AAEA,MAAI;AAEJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,SAAO;AACT;","names":["NextResponse","NextResponse"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-lite-auth",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
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",
@@ -34,7 +34,8 @@
34
34
  "react": "^18.0.0",
35
35
  "tsup": "^8.0.0",
36
36
  "typescript": "^5.0.0",
37
- "vitepress": "^1.0.0"
37
+ "vitepress": "^1.0.0",
38
+ "vitest": "^2.1.9"
38
39
  },
39
40
  "engines": {
40
41
  "node": ">=20.0.0",
@@ -59,6 +60,7 @@
59
60
  "scripts": {
60
61
  "build": "tsup",
61
62
  "dev": "tsup --watch",
63
+ "test": "vitest run",
62
64
  "typecheck": "tsc --noEmit",
63
65
  "docs:dev": "vitepress dev docs",
64
66
  "docs:build": "vitepress build docs",