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 && (