UNPKG

next-auth-pubkey

Version:

A light-weight Lightning and Nostr auth provider for your Next.js app that's entirely self-hosted and plugs seamlessly into the next-auth framework.

145 lines (143 loc) 5.7 kB
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime"; import { renderToStaticMarkup } from "preact-render-to-string"; import { hardConfig } from "../config/index.js"; import { vanilla } from "../utils/vanilla-nostr.js"; import { NostrAuth } from "../components/NostrAuth.js"; import { Loading } from "../components/Loading.js"; import { signInValidation } from "../validation/api.js"; function NostrAuthPage({ title, config }) { return (_jsx("body", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "100vh", boxSizing: "border-box", margin: 0, padding: 20, fontFamily: `ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji`, background: config.theme.background, color: config.theme.text, }, children: _jsxs("div", { children: [_jsx(Loading, { style: { width: "36px", height: "36px", border: `4px solid ${config.theme.backgroundCard}`, borderBottomColor: config.theme.text, borderRadius: "50%", display: "inline-block", boxSizing: "border-box", animation: `${hardConfig.ids.loading}-rotation 1s linear infinite`, // NOTE: further styles are defined below within the <style> tag } }), _jsx(NostrAuth, { title: title, theme: { wrapper: { display: "none", textAlign: "center", maxWidth: 400, background: config.theme.backgroundCard, color: config.theme.text, padding: "20px 30px", borderRadius: 20, }, title: { fontSize: 25, color: config.theme.text, marginTop: 0, marginBottom: 5, }, error: { fontSize: 16, color: "red", marginTop: 0, }, details: { marginTop: 15, display: "none", textAlign: "left", }, button: { display: "none", margin: "auto", alignItems: "center", backgroundColor: config.theme.background, textDecoration: "none", border: `2px solid rgba(110, 110, 110, 0.3)`, borderRadius: 10, color: config.theme.text, fontSize: "1.1rem", fontWeight: "500", justifyContent: "center", minHeight: "30px", padding: ".75rem 1rem", position: "relative", cursor: "pointer", }, } })] }) })); } export default async function handler({ query, cookies, url, config, }) { try { try { signInValidation.parse(query); } catch (e) { return { error: "BadRequest", status: 302, log: e instanceof Error ? e.message : "", }; } if (cookies.sessionToken) { return { error: "Forbidden", status: 302, // 302 trigger a redirect }; } // if a custom auth page is specified, send them there if they try and access this API if (config.pages.nostrSignIn !== config.apis.nostrSignIn) { const params = url.searchParams.toString(); return { redirect: new URL(`${config.baseUrl}${config.pages.nostrSignIn}?${params}`), }; } const title = "Login with Nostr"; const html = renderToStaticMarkup(_jsx(NostrAuthPage, { title: title, config: config })); return { status: 200, headers: { "content-type": "text/html", }, response: `<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>${title}</title> <style> #${hardConfig.ids.loading} span { display: none; } @keyframes ${hardConfig.ids.loading}-rotation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> </head> ${html} <script> var init = ${vanilla.toString()}; window.onload = function(){ init(${JSON.stringify({ hardConfig, query })}) }; </script> </html>`, }; } catch (e) { return { error: "Default", message: e instanceof Error ? e.message : "", status: 302, // 302 trigger a redirect }; } }