From c9d702576e3d3ff735cecdf27a5b68392979e677 Mon Sep 17 00:00:00 2001 From: austinkelsay Date: Mon, 18 Nov 2024 16:42:40 -0600 Subject: [PATCH] github signup, creates user and kind0, can open nostr profile from plebdevs profile now --- src/components/navbar/user/UserAvatar.js | 2 +- src/components/profile/UserProfile.js | 7 ++- src/components/profile/UserSettings.js | 7 ++- src/pages/api/auth/[...nextauth].js | 76 +++++++++++++++++++----- src/pages/auth/signin.js | 7 +++ 5 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/components/navbar/user/UserAvatar.js b/src/components/navbar/user/UserAvatar.js index 47edc80..f25c1fb 100644 --- a/src/components/navbar/user/UserAvatar.js +++ b/src/components/navbar/user/UserAvatar.js @@ -56,7 +56,7 @@ const UserAvatar = () => { return null; // Or return a loader/spinner/placeholder } else if (user && Object.keys(user).length > 0) { // User exists, show username or pubkey - const displayName = user.username || user?.email || user?.pubkey.slice(0, 10) + '...'; + const displayName = user.username || user?.name || user?.email || user?.pubkey.slice(0, 10) + '...' || "Anon"; const items = [ { diff --git a/src/components/profile/UserProfile.js b/src/components/profile/UserProfile.js index 18b3535..ba61070 100644 --- a/src/components/profile/UserProfile.js +++ b/src/components/profile/UserProfile.js @@ -70,6 +70,11 @@ const UserProfile = () => { copyToClipboard(nip19.npubEncode(user?.pubkey)); } } + }, + { + label: 'Open Nostr Profile', + icon: 'pi pi-external-link', + command: () => window.open(`https://nostr.com/${nip19.npubEncode(user?.pubkey)}`, '_blank') } ]; @@ -106,7 +111,7 @@ const UserProfile = () => {

- {user.username || user?.email || "Anon"} + {user.username || user?.name || user?.email || "Anon"}

{user.pubkey && (

diff --git a/src/components/profile/UserSettings.js b/src/components/profile/UserSettings.js index be4456d..2020a77 100644 --- a/src/components/profile/UserSettings.js +++ b/src/components/profile/UserSettings.js @@ -176,6 +176,11 @@ const UserSettings = () => { command: () => { copyToClipboard(nip19.npubEncode(user?.pubkey)); } + }, + { + label: 'Open Nostr Profile', + icon: 'pi pi-external-link', + command: () => window.open(`https://nostr.com/${nip19.npubEncode(user?.pubkey)}`, '_blank') } ]; @@ -211,7 +216,7 @@ const UserSettings = () => {

- {user.username || user?.email || "Anon"} + {user.username || user?.name || user?.email || "Anon"}

{user.pubkey && (

diff --git a/src/pages/api/auth/[...nextauth].js b/src/pages/api/auth/[...nextauth].js index bd41991..5d7760a 100644 --- a/src/pages/api/auth/[...nextauth].js +++ b/src/pages/api/auth/[...nextauth].js @@ -1,23 +1,21 @@ import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import EmailProvider from "next-auth/providers/email"; -import NDK from "@nostr-dev-kit/ndk"; import { PrismaAdapter } from "@next-auth/prisma-adapter"; import prisma from "@/db/prisma"; import nodemailer from 'nodemailer'; import { findKind0Fields } from "@/utils/nostr"; import { generateSecretKey, getPublicKey } from 'nostr-tools/pure' import { bytesToHex } from '@noble/hashes/utils' -import { updateUser, getUserByPubkey, createUser, getUserByEmail } from "@/db/models/userModels"; +import { updateUser, getUserByPubkey, createUser } from "@/db/models/userModels"; import { createRole } from "@/db/models/roleModels"; import appConfig from "@/config/appConfig"; +import GithubProvider from "next-auth/providers/github"; +import { SimplePool } from "nostr-tools"; +import { finalizeEvent } from "nostr-tools"; // todo: currently email accounts ephemeral privkey gets saved to db but not anon user, is this required at all given the newer auth setup? -const ndk = new NDK({ - explicitRelayUrls: [...appConfig.defaultRelayUrls] -}); - const authorize = async (pubkey) => { await ndk.connect(); const user = ndk.getUser({ pubkey }); @@ -125,6 +123,10 @@ export const authOptions = { }); } }), + GithubProvider({ + clientId: process.env.GITHUB_CLIENT_ID, + clientSecret: process.env.GITHUB_CLIENT_SECRET + }), CredentialsProvider({ id: "anonymous", name: "Anonymous", @@ -148,7 +150,7 @@ export const authOptions = { // Check if user exists in the database let dbUser = await getUserByPubkey(pubkey); - + if (!dbUser) { // Create new user if not exists dbUser = await createUser({ @@ -156,7 +158,7 @@ export const authOptions = { username: pubkey.slice(0, 8), // Use first 8 characters of pubkey as username }); } - + // Return user object with pubkey and privkey return { ...dbUser, pubkey, privkey }; }, @@ -175,18 +177,60 @@ export const authOptions = { const sk = generateSecretKey(); const pubkey = getPublicKey(sk); const privkey = bytesToHex(sk); - + // Update the user in the database await prisma.user.update({ where: { id: user.id }, data: { pubkey, privkey } }); - + // Update the user object user.pubkey = pubkey; user.privkey = privkey; } + // Add new condition for first-time GitHub sign up + if (trigger === "signUp" && account?.provider === "github") { + const sk = generateSecretKey(); + const pubkey = getPublicKey(sk); + const privkey = bytesToHex(sk); + + // Update the user in the database + await prisma.user.update({ + where: { id: user.id }, + data: { pubkey, privkey, name: user.name, username: user.name, avatar: user.image || null } + }); + + // Publish kind0 event to nostr + try { + const pool = new SimplePool(); + const relays = [ + "wss://relay.damus.io", + "wss://relay.nostr.band", + "wss://relay.primal.net", + "wss://relay.devs.tools" + ]; + + const event = finalizeEvent({ + kind: 0, + created_at: Math.floor(Date.now() / 1000), + tags: [], + content: JSON.stringify({ + name: user.name, + picture: user.image + }) + }, privkey); + + await Promise.any(pool.publish(relays, event)); + } catch (error) { + console.error('Failed to publish kind0 event:', error); + } + + // Update user object with nostr keys + user.pubkey = pubkey; + user.privkey = privkey; + } + if (user) { token.user = user; if (user.pubkey && user.privkey) { @@ -218,14 +262,14 @@ export const authOptions = { }, async signIn({ user, account }) { if (account.provider === 'anonymous') { - return { - ...user, - pubkey: user.pubkey, - privkey: user.privkey, - }; + return { + ...user, + pubkey: user.pubkey, + privkey: user.privkey, + }; } return true; - }, + }, }, secret: process.env.NEXTAUTH_SECRET, session: { strategy: "jwt" }, diff --git a/src/pages/auth/signin.js b/src/pages/auth/signin.js index 3a688df..692a416 100644 --- a/src/pages/auth/signin.js +++ b/src/pages/auth/signin.js @@ -78,6 +78,13 @@ export default function SignIn() { rounded onClick={() => setShowEmailInput(!showEmailInput)} /> + signIn("github")} + /> {showEmailInput && (