2024-08-07 16:02:13 -05:00
|
|
|
import NextAuth from "next-auth";
|
|
|
|
import CredentialsProvider from "next-auth/providers/credentials";
|
|
|
|
import NDK from "@nostr-dev-kit/ndk";
|
|
|
|
import axios from "axios";
|
|
|
|
import { findKind0Fields } from "@/utils/nostr";
|
|
|
|
|
|
|
|
const relayUrls = [
|
|
|
|
"wss://nos.lol/",
|
|
|
|
"wss://relay.damus.io/",
|
|
|
|
"wss://relay.snort.social/",
|
|
|
|
"wss://relay.nostr.band/",
|
|
|
|
"wss://nostr.mutinywallet.com/",
|
|
|
|
"wss://relay.mutinywallet.com/",
|
|
|
|
"wss://relay.primal.net/"
|
|
|
|
];
|
|
|
|
|
|
|
|
const BASE_URL = process.env.BASE_URL;
|
|
|
|
|
|
|
|
const ndk = new NDK({
|
|
|
|
explicitRelayUrls: relayUrls,
|
|
|
|
});
|
|
|
|
|
2024-08-12 17:27:47 -05:00
|
|
|
const authorize = async (pubkey) => {
|
|
|
|
await ndk.connect();
|
|
|
|
const user = ndk.getUser({ pubkey });
|
|
|
|
|
|
|
|
try {
|
|
|
|
const profile = await user.fetchProfile();
|
|
|
|
|
|
|
|
// Check if user exists, create if not
|
|
|
|
const response = await axios.get(`${BASE_URL}/api/users/${pubkey}`);
|
|
|
|
if (response.status === 200 && response.data) {
|
|
|
|
const fields = await findKind0Fields(profile);
|
|
|
|
|
|
|
|
// Combine user object with kind0Fields, giving priority to kind0Fields
|
|
|
|
const combinedUser = { ...fields, ...response.data };
|
|
|
|
|
|
|
|
// Update the user on the backend if necessary
|
|
|
|
// await axios.put(`${BASE_URL}/api/users/${combinedUser.id}`, combinedUser);
|
|
|
|
|
|
|
|
return combinedUser;
|
|
|
|
} else if (response.status === 204) {
|
|
|
|
// Create user
|
|
|
|
if (profile) {
|
|
|
|
const fields = await findKind0Fields(profile);
|
|
|
|
console.log('FEEEEELDS', fields);
|
|
|
|
const payload = { pubkey, ...fields };
|
|
|
|
|
|
|
|
const createUserResponse = await axios.post(`${BASE_URL}/api/users`, payload);
|
|
|
|
return createUserResponse.data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error("Nostr login error:", error);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-08-07 16:02:13 -05:00
|
|
|
export default NextAuth({
|
|
|
|
providers: [
|
|
|
|
CredentialsProvider({
|
|
|
|
id: "nostr",
|
|
|
|
name: "Nostr",
|
|
|
|
credentials: {
|
|
|
|
pubkey: { label: "Public Key", type: "text" },
|
|
|
|
},
|
|
|
|
authorize: async (credentials) => {
|
|
|
|
if (credentials?.pubkey) {
|
2024-08-12 17:27:47 -05:00
|
|
|
return await authorize(credentials.pubkey);
|
2024-08-07 16:02:13 -05:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
callbacks: {
|
2024-08-12 17:27:47 -05:00
|
|
|
async jwt({ token, trigger, user }) {
|
2024-08-13 16:28:25 -05:00
|
|
|
console.log('TRIGGER', trigger);
|
2024-08-12 17:27:47 -05:00
|
|
|
if (trigger === "update") {
|
|
|
|
// if we trigger an update call the authorize function again
|
|
|
|
const newUser = await authorize(token.user.pubkey);
|
|
|
|
token.user = newUser;
|
|
|
|
}
|
2024-08-09 14:28:57 -05:00
|
|
|
// Add combined user object to the token
|
2024-08-07 16:02:13 -05:00
|
|
|
if (user) {
|
2024-08-07 17:06:53 -05:00
|
|
|
token.user = user;
|
2024-08-07 16:02:13 -05:00
|
|
|
}
|
|
|
|
return token;
|
|
|
|
},
|
|
|
|
async session({ session, token }) {
|
2024-08-07 17:06:53 -05:00
|
|
|
// Add user from token to session
|
|
|
|
session.user = token.user;
|
|
|
|
session.jwt = token;
|
2024-08-07 16:02:13 -05:00
|
|
|
return session;
|
|
|
|
},
|
|
|
|
async redirect({ url, baseUrl }) {
|
2024-08-07 17:06:53 -05:00
|
|
|
return baseUrl;
|
2024-08-07 16:02:13 -05:00
|
|
|
},
|
2024-08-13 16:28:25 -05:00
|
|
|
async signOut({ token, session }) {
|
|
|
|
console.log('signOut', token, session);
|
|
|
|
token = {}
|
|
|
|
session = {}
|
|
|
|
return true
|
|
|
|
},
|
2024-08-07 16:02:13 -05:00
|
|
|
},
|
|
|
|
secret: process.env.NEXTAUTH_SECRET,
|
2024-08-07 17:06:53 -05:00
|
|
|
session: { strategy: "jwt" },
|
2024-08-07 16:02:13 -05:00
|
|
|
jwt: {
|
|
|
|
signingKey: process.env.JWT_SECRET,
|
|
|
|
},
|
|
|
|
pages: {
|
|
|
|
signIn: "/auth/signin",
|
|
|
|
},
|
2024-08-07 17:06:53 -05:00
|
|
|
});
|