mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-06 18:31:00 +00:00
Email login is working
This commit is contained in:
parent
9534f83e65
commit
9528010829
19
package-lock.json
generated
19
package-lock.json
generated
@ -12,6 +12,7 @@
|
|||||||
"@getalby/bitcoin-connect-react": "^3.5.3",
|
"@getalby/bitcoin-connect-react": "^3.5.3",
|
||||||
"@getalby/lightning-tools": "^5.0.3",
|
"@getalby/lightning-tools": "^5.0.3",
|
||||||
"@getalby/sdk": "^3.6.1",
|
"@getalby/sdk": "^3.6.1",
|
||||||
|
"@next-auth/prisma-adapter": "^1.0.7",
|
||||||
"@nostr-dev-kit/ndk": "^2.10.0",
|
"@nostr-dev-kit/ndk": "^2.10.0",
|
||||||
"@nostr-dev-kit/ndk-cache-dexie": "^2.5.1",
|
"@nostr-dev-kit/ndk-cache-dexie": "^2.5.1",
|
||||||
"@prisma/client": "^5.17.0",
|
"@prisma/client": "^5.17.0",
|
||||||
@ -25,7 +26,7 @@
|
|||||||
"next": "14.2.5",
|
"next": "14.2.5",
|
||||||
"next-auth": "^4.24.7",
|
"next-auth": "^4.24.7",
|
||||||
"next-remove-imports": "^1.0.12",
|
"next-remove-imports": "^1.0.12",
|
||||||
"nodemailer": "^6.9.14",
|
"nodemailer": "^6.9.15",
|
||||||
"nostr-tools": "^2.7.1",
|
"nostr-tools": "^2.7.1",
|
||||||
"primeicons": "^7.0.0",
|
"primeicons": "^7.0.0",
|
||||||
"primereact": "^10.7.0",
|
"primereact": "^10.7.0",
|
||||||
@ -916,6 +917,16 @@
|
|||||||
"crypto-js": "4.2.0"
|
"crypto-js": "4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@next-auth/prisma-adapter": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-Cdko4KfcmKjsyHFrWwZ//lfLUbcLqlyFqjd/nYE2m3aZ7tjMNUjpks47iw7NTCnXf+5UWz5Ypyt1dSs1EP5QJw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@prisma/client": ">=2.26.0 || >=3",
|
||||||
|
"next-auth": "^4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@next/env": {
|
"node_modules/@next/env": {
|
||||||
"version": "14.2.5",
|
"version": "14.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz",
|
||||||
@ -8832,9 +8843,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/nodemailer": {
|
"node_modules/nodemailer": {
|
||||||
"version": "6.9.14",
|
"version": "6.9.15",
|
||||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz",
|
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz",
|
||||||
"integrity": "sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==",
|
"integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==",
|
||||||
"license": "MIT-0",
|
"license": "MIT-0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"@getalby/bitcoin-connect-react": "^3.5.3",
|
"@getalby/bitcoin-connect-react": "^3.5.3",
|
||||||
"@getalby/lightning-tools": "^5.0.3",
|
"@getalby/lightning-tools": "^5.0.3",
|
||||||
"@getalby/sdk": "^3.6.1",
|
"@getalby/sdk": "^3.6.1",
|
||||||
|
"@next-auth/prisma-adapter": "^1.0.7",
|
||||||
"@nostr-dev-kit/ndk": "^2.10.0",
|
"@nostr-dev-kit/ndk": "^2.10.0",
|
||||||
"@nostr-dev-kit/ndk-cache-dexie": "^2.5.1",
|
"@nostr-dev-kit/ndk-cache-dexie": "^2.5.1",
|
||||||
"@prisma/client": "^5.17.0",
|
"@prisma/client": "^5.17.0",
|
||||||
@ -26,7 +27,7 @@
|
|||||||
"next": "14.2.5",
|
"next": "14.2.5",
|
||||||
"next-auth": "^4.24.7",
|
"next-auth": "^4.24.7",
|
||||||
"next-remove-imports": "^1.0.12",
|
"next-remove-imports": "^1.0.12",
|
||||||
"nodemailer": "^6.9.14",
|
"nodemailer": "^6.9.15",
|
||||||
"nostr-tools": "^2.7.1",
|
"nostr-tools": "^2.7.1",
|
||||||
"primeicons": "^7.0.0",
|
"primeicons": "^7.0.0",
|
||||||
"primereact": "^10.7.0",
|
"primereact": "^10.7.0",
|
||||||
|
71
prisma/migrations/20240906171109_email_auth/migration.sql
Normal file
71
prisma/migrations/20240906171109_email_auth/migration.sql
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- A unique constraint covering the columns `[email]` on the table `User` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ADD COLUMN "email" TEXT,
|
||||||
|
ADD COLUMN "emailVerified" TIMESTAMP(3),
|
||||||
|
ADD COLUMN "image" TEXT,
|
||||||
|
ADD COLUMN "name" TEXT,
|
||||||
|
ADD COLUMN "privkey" TEXT,
|
||||||
|
ALTER COLUMN "pubkey" DROP NOT NULL;
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Session" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"sessionToken" TEXT NOT NULL,
|
||||||
|
"userId" TEXT NOT NULL,
|
||||||
|
"expires" TIMESTAMP(3) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "VerificationToken" (
|
||||||
|
"identifier" TEXT NOT NULL,
|
||||||
|
"token" TEXT NOT NULL,
|
||||||
|
"expires" TIMESTAMP(3) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Account" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"userId" TEXT NOT NULL,
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"provider" TEXT NOT NULL,
|
||||||
|
"providerAccountId" TEXT NOT NULL,
|
||||||
|
"refresh_token" TEXT,
|
||||||
|
"access_token" TEXT,
|
||||||
|
"expires_at" INTEGER,
|
||||||
|
"token_type" TEXT,
|
||||||
|
"scope" TEXT,
|
||||||
|
"id_token" TEXT,
|
||||||
|
"session_state" TEXT,
|
||||||
|
"oauth_token_secret" TEXT,
|
||||||
|
"oauth_token" TEXT,
|
||||||
|
|
||||||
|
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
@ -9,7 +9,12 @@ generator client {
|
|||||||
|
|
||||||
model User {
|
model User {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
pubkey String @unique
|
pubkey String? @unique
|
||||||
|
privkey String?
|
||||||
|
name String?
|
||||||
|
email String? @unique
|
||||||
|
emailVerified DateTime?
|
||||||
|
image String?
|
||||||
username String? @unique
|
username String? @unique
|
||||||
avatar String?
|
avatar String?
|
||||||
purchased Purchase[]
|
purchased Purchase[]
|
||||||
@ -18,10 +23,49 @@ model User {
|
|||||||
courseDrafts CourseDraft[]
|
courseDrafts CourseDraft[]
|
||||||
drafts Draft[]
|
drafts Draft[]
|
||||||
role Role?
|
role Role?
|
||||||
|
accounts Account[]
|
||||||
|
sessions Session[]
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model Session {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
sessionToken String @unique
|
||||||
|
userId String
|
||||||
|
expires DateTime
|
||||||
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
}
|
||||||
|
|
||||||
|
model VerificationToken {
|
||||||
|
identifier String
|
||||||
|
token String @unique
|
||||||
|
expires DateTime
|
||||||
|
|
||||||
|
@@unique([identifier, token])
|
||||||
|
}
|
||||||
|
|
||||||
|
model Account {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
userId String
|
||||||
|
type String
|
||||||
|
provider String
|
||||||
|
providerAccountId String
|
||||||
|
refresh_token String?
|
||||||
|
access_token String?
|
||||||
|
expires_at Int?
|
||||||
|
token_type String?
|
||||||
|
scope String?
|
||||||
|
id_token String?
|
||||||
|
session_state String?
|
||||||
|
oauth_token_secret String?
|
||||||
|
oauth_token String?
|
||||||
|
|
||||||
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@unique([provider, providerAccountId])
|
||||||
|
}
|
||||||
|
|
||||||
model Role {
|
model Role {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
user User @relation(fields: [userId], references: [id])
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
@ -46,7 +46,7 @@ const UserAvatar = () => {
|
|||||||
return null; // Or return a loader/spinner/placeholder
|
return null; // Or return a loader/spinner/placeholder
|
||||||
} else if (user && Object.keys(user).length > 0) {
|
} else if (user && Object.keys(user).length > 0) {
|
||||||
// User exists, show username or pubkey
|
// User exists, show username or pubkey
|
||||||
const displayName = user.username || user.pubkey.slice(0, 10) + '...';
|
const displayName = user.username || user?.email || user?.pubkey.slice(0, 10) + '...';
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
@ -81,7 +81,7 @@ const UserAvatar = () => {
|
|||||||
className={styles.logo}
|
className={styles.logo}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Menu model={items} popup ref={menu} />
|
<Menu model={items} popup ref={menu} className='w-[250px] break-words' />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,7 +70,7 @@ const UserProfile = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 className="text-center text-2xl my-2">
|
<h1 className="text-center text-2xl my-2">
|
||||||
{user.username || "Anon"}
|
{user.username || user?.email || "Anon"}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 className="text-center text-xl my-2 truncate max-tab:px-4 max-mob:px-4">
|
<h2 className="text-center text-xl my-2 truncate max-tab:px-4 max-mob:px-4">
|
||||||
{user.pubkey}
|
{user.pubkey}
|
||||||
|
@ -70,7 +70,7 @@ const UserSettings = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 className="text-center text-2xl my-2">
|
<h1 className="text-center text-2xl my-2">
|
||||||
{user.username || "Anon"}
|
{user.username || user?.email || "Anon"}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 className="text-center text-xl my-2 truncate max-tab:px-4 max-mob:px-4">
|
<h2 className="text-center text-xl my-2 truncate max-tab:px-4 max-mob:px-4">
|
||||||
{user.pubkey}
|
{user.pubkey}
|
||||||
|
@ -85,12 +85,15 @@ export const addCoursePurchaseToUser = async (userId, purchaseData) => {
|
|||||||
|
|
||||||
export const createUser = async (data) => {
|
export const createUser = async (data) => {
|
||||||
return await prisma.user.create({
|
return await prisma.user.create({
|
||||||
data,
|
data: {
|
||||||
|
...data,
|
||||||
|
emailVerified: data.email ? new Date() : null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateUser = async (id, data) => {
|
export const updateUser = async (id, data) => {
|
||||||
console.log("user modelllll", id, data)
|
console.log("Updating user", id, data)
|
||||||
return await prisma.user.update({
|
return await prisma.user.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data,
|
data,
|
||||||
@ -169,3 +172,18 @@ export const expireUserSubscriptions = async (userIds) => {
|
|||||||
await prisma.$transaction(updatePromises);
|
await prisma.$transaction(updatePromises);
|
||||||
return userIds.length;
|
return userIds.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUserByEmail = async (email) => {
|
||||||
|
return await prisma.user.findUnique({
|
||||||
|
where: { email },
|
||||||
|
include: {
|
||||||
|
role: true,
|
||||||
|
purchased: {
|
||||||
|
include: {
|
||||||
|
course: true,
|
||||||
|
resource: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
import NextAuth from "next-auth";
|
import NextAuth from "next-auth";
|
||||||
import CredentialsProvider from "next-auth/providers/credentials";
|
import CredentialsProvider from "next-auth/providers/credentials";
|
||||||
|
import EmailProvider from "next-auth/providers/email";
|
||||||
import NDK from "@nostr-dev-kit/ndk";
|
import NDK from "@nostr-dev-kit/ndk";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||||
|
import prisma from "@/db/prisma";
|
||||||
import { findKind0Fields } from "@/utils/nostr";
|
import { findKind0Fields } from "@/utils/nostr";
|
||||||
|
import { generateSecretKey, getPublicKey } from 'nostr-tools/pure'
|
||||||
|
import { bytesToHex } from '@noble/hashes/utils'
|
||||||
|
import { updateUser } from "@/db/models/userModels";
|
||||||
|
|
||||||
const relayUrls = [
|
const relayUrls = [
|
||||||
"wss://nos.lol/",
|
"wss://nos.lol/",
|
||||||
@ -43,7 +49,6 @@ const authorize = async (pubkey) => {
|
|||||||
// Create user
|
// Create user
|
||||||
if (profile) {
|
if (profile) {
|
||||||
const fields = await findKind0Fields(profile);
|
const fields = await findKind0Fields(profile);
|
||||||
console.log('FEEEEELDS', fields);
|
|
||||||
const payload = { pubkey, ...fields };
|
const payload = { pubkey, ...fields };
|
||||||
|
|
||||||
const createUserResponse = await axios.post(`${BASE_URL}/api/users`, payload);
|
const createUserResponse = await axios.post(`${BASE_URL}/api/users`, payload);
|
||||||
@ -58,6 +63,7 @@ const authorize = async (pubkey) => {
|
|||||||
|
|
||||||
|
|
||||||
export default NextAuth({
|
export default NextAuth({
|
||||||
|
adapter: PrismaAdapter(prisma),
|
||||||
providers: [
|
providers: [
|
||||||
CredentialsProvider({
|
CredentialsProvider({
|
||||||
id: "nostr",
|
id: "nostr",
|
||||||
@ -72,15 +78,43 @@ export default NextAuth({
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
EmailProvider({
|
||||||
|
server: {
|
||||||
|
host: process.env.EMAIL_SERVER_HOST,
|
||||||
|
port: process.env.EMAIL_SERVER_PORT,
|
||||||
|
auth: {
|
||||||
|
user: process.env.EMAIL_SERVER_USER,
|
||||||
|
pass: process.env.EMAIL_SERVER_PASSWORD
|
||||||
|
}
|
||||||
|
},
|
||||||
|
from: process.env.EMAIL_FROM
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
callbacks: {
|
callbacks: {
|
||||||
async jwt({ token, trigger, user }) {
|
async jwt({ token, trigger, user }) {
|
||||||
console.log('TRIGGER', trigger);
|
|
||||||
if (trigger === "update") {
|
if (trigger === "update") {
|
||||||
// if we trigger an update call the authorize function again
|
// if we trigger an update call the authorize function again
|
||||||
const newUser = await authorize(token.user.pubkey);
|
const newUser = await authorize(token.user.pubkey);
|
||||||
token.user = newUser;
|
token.user = newUser;
|
||||||
}
|
}
|
||||||
|
// if the user has no pubkey, generate a new key pair
|
||||||
|
if (token && token?.user && token?.user?.id && !token.user?.pubkey) {
|
||||||
|
try {
|
||||||
|
let sk = generateSecretKey()
|
||||||
|
let pk = getPublicKey(sk)
|
||||||
|
let skHex = bytesToHex(sk)
|
||||||
|
const updatedUser = await updateUser(token.user.id, {pubkey: pk, privkey: skHex});
|
||||||
|
if (!updatedUser) {
|
||||||
|
console.error("Failed to update user");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
token.user = updatedUser;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Ephemeral key pair generation error:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add combined user object to the token
|
// Add combined user object to the token
|
||||||
if (user) {
|
if (user) {
|
||||||
token.user = user;
|
token.user = user;
|
||||||
@ -88,6 +122,7 @@ export default NextAuth({
|
|||||||
return token;
|
return token;
|
||||||
},
|
},
|
||||||
async session({ session, token }) {
|
async session({ session, token }) {
|
||||||
|
console.log('SESSION', session);
|
||||||
// Add user from token to session
|
// Add user from token to session
|
||||||
session.user = token.user;
|
session.user = token.user;
|
||||||
session.jwt = token;
|
session.jwt = token;
|
||||||
@ -97,7 +132,6 @@ export default NextAuth({
|
|||||||
return baseUrl;
|
return baseUrl;
|
||||||
},
|
},
|
||||||
async signOut({ token, session }) {
|
async signOut({ token, session }) {
|
||||||
console.log('signOut', token, session);
|
|
||||||
token = {}
|
token = {}
|
||||||
session = {}
|
session = {}
|
||||||
return true
|
return true
|
||||||
|
@ -2,14 +2,18 @@ import { getUserById, getUserByPubkey, updateUser, deleteUser } from "@/db/model
|
|||||||
|
|
||||||
export default async function handler(req, res) {
|
export default async function handler(req, res) {
|
||||||
const { slug } = req.query;
|
const { slug } = req.query;
|
||||||
// Determine if slug is a pubkey or an ID
|
// Determine if slug is a pubkey, ID, or email
|
||||||
const isPubkey = /^[0-9a-fA-F]{64}$/.test(slug);
|
const isPubkey = /^[0-9a-fA-F]{64}$/.test(slug);
|
||||||
|
const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(slug);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let user;
|
let user;
|
||||||
if (isPubkey) {
|
if (isPubkey) {
|
||||||
// If slug is a pubkey
|
// If slug is a pubkey
|
||||||
user = await getUserByPubkey(slug);
|
user = await getUserByPubkey(slug);
|
||||||
|
} else if (isEmail) {
|
||||||
|
// If slug is an email
|
||||||
|
user = await getUserByEmail(slug);
|
||||||
} else {
|
} else {
|
||||||
// Assume slug is an ID
|
// Assume slug is an ID
|
||||||
const id = parseInt(slug);
|
const id = parseInt(slug);
|
||||||
|
@ -2,36 +2,32 @@ import { signIn, useSession } from "next-auth/react"
|
|||||||
import { useState, useEffect } from "react"
|
import { useState, useEffect } from "react"
|
||||||
import { useNDKContext } from "@/context/NDKContext";
|
import { useNDKContext } from "@/context/NDKContext";
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
|
||||||
export default function SignIn() {
|
export default function SignIn() {
|
||||||
const [email, setEmail] = useState("")
|
const [email, setEmail] = useState("")
|
||||||
|
const [showEmailInput, setShowEmailInput] = useState(false)
|
||||||
const [nostrPubkey, setNostrPubkey] = useState("")
|
const [nostrPubkey, setNostrPubkey] = useState("")
|
||||||
const [nostrPrivkey, setNostrPrivkey] = useState("")
|
const [nostrPrivkey, setNostrPrivkey] = useState("")
|
||||||
|
|
||||||
const {ndk, addSigner} = useNDKContext();
|
const {ndk, addSigner} = useNDKContext();
|
||||||
|
|
||||||
const { data: session, status } = useSession(); // Get the current session's data and status
|
const { data: session, status } = useSession(); // Get the current session's data and status
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("session", session)
|
console.log("session", session)
|
||||||
}, [session])
|
}, [session])
|
||||||
|
|
||||||
const handleEmailSignIn = (e) => {
|
const handleEmailSignIn = async (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
signIn("email", { email })
|
await signIn("email", { email, callbackUrl: '/' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNostrSignIn = async (e) => {
|
const handleNostrSignIn = async (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
if (!ndk.signer) {
|
if (!ndk.signer) {
|
||||||
await addSigner();
|
await addSigner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const user = await ndk.signer.user()
|
const user = await ndk.signer.user()
|
||||||
|
|
||||||
const pubkey = user?._pubkey
|
const pubkey = user?._pubkey
|
||||||
signIn("nostr", { pubkey })
|
signIn("nostr", { pubkey })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -66,8 +62,26 @@ export default function SignIn() {
|
|||||||
icon="pi pi-envelope"
|
icon="pi pi-envelope"
|
||||||
className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
|
className="text-[#f8f8ff] w-[250px] my-4 mx-auto"
|
||||||
rounded
|
rounded
|
||||||
onClick={handleEmailSignIn}
|
onClick={() => setShowEmailInput(!showEmailInput)}
|
||||||
/>
|
/>
|
||||||
|
{showEmailInput && (
|
||||||
|
<form onSubmit={handleEmailSignIn} className="flex flex-col items-center bg-gray-700 w-fit mx-auto p-4 rounded-lg">
|
||||||
|
<InputText
|
||||||
|
type="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
placeholder="Enter your email"
|
||||||
|
className="w-[250px] my-4"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
label={"Submit"}
|
||||||
|
icon="pi pi-check"
|
||||||
|
className="text-[#f8f8ff] w-fit my-4"
|
||||||
|
rounded
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user