Combine login logic

This commit is contained in:
austinkelsay 2024-02-11 10:09:43 -06:00
parent 9287c9bd49
commit 9a86c71754
4 changed files with 98 additions and 114 deletions

View File

@ -1,9 +1,8 @@
import React from 'react';
import { useAutoLogin } from '@/hooks/useAutoLogin';
import { useLogin } from '@/hooks/useLogin';
const Layout = ({ children }) => {
useAutoLogin();
console.log('Layout');
useLogin();
return <>{children}</>;
};

View File

@ -1,39 +0,0 @@
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { useDispatch } from 'react-redux';
import axios from 'axios';
import { setPubkey, setUsername } from "@/redux/reducers/userReducer";
export const useAutoLogin = () => {
const dispatch = useDispatch();
const router = useRouter();
console.log('useAutoLogin');
useEffect(() => {
const publicKey = window.localStorage.getItem('pubkey');
console.log('Auto logging in with public key:', publicKey);
if (publicKey) {
const login = async () => {
try {
const response = await axios.get(`/api/users/${publicKey}`);
if (response.status === 200 && response.data) {
dispatch(setPubkey(publicKey));
if (response.data.username) {
dispatch(setUsername(response.data.username));
}
} else {
// Handle user not found or other errors appropriately
}
} catch (error) {
console.error('Error during auto login:', error);
// Handle error
}
};
login();
}
}, [dispatch]);
return null;
};

93
src/hooks/useLogin.js Normal file
View File

@ -0,0 +1,93 @@
import { useCallback, useEffect } from 'react';
import { useRouter } from 'next/router';
import { useDispatch } from 'react-redux';
import axios from 'axios';
import { setPubkey, setUsername } from "@/redux/reducers/userReducer";
import { generateSecretKey, getPublicKey } from 'nostr-tools';
import { findKind0Username } from "@/utils/nostr";
export const useLogin = () => {
const dispatch = useDispatch();
const router = useRouter();
// Handle Auto Login
useEffect(() => {
const autoLogin = async () => {
const publicKey = window.localStorage.getItem('pubkey');
console.log('Auto logging in with public key:', publicKey);
if (!publicKey) return;
try {
const response = await axios.get(`/api/users/${publicKey}`);
if (response.status === 200 && response.data) {
dispatch(setPubkey(publicKey));
if (response.data.username) {
dispatch(setUsername(response.data.username));
}
router.push('/');
}
} catch (error) {
console.error('Error during auto login:', error);
}
};
autoLogin();
}, []);
// Handle Nostr Login
const nostrLogin = useCallback(async () => {
if (!window || !window.nostr) {
alert('Nostr is not available');
return;
}
const publicKey = await window.nostr.getPublicKey();
if (!publicKey) {
alert('Failed to obtain public key');
return;
}
try {
const response = await axios.get(`/api/users/${publicKey}`);
if (response.status !== 200) throw new Error('User not found');
dispatch(setPubkey(publicKey));
window.localStorage.setItem('pubkey', publicKey);
if (response.data.username) dispatch(setUsername(response.data.username));
router.push('/');
} catch (error) {
// User not found, create a new user
const kind0 = await findKind0Username({ authors: [publicKey], kinds: [0] }); // Adjust based on actual implementation
const username = kind0 ? kind0 : undefined;
const payload = { pubkey: publicKey, ...(username && { username }) };
try {
const createUserResponse = await axios.post(`/api/users`, payload);
if (createUserResponse.status === 201) {
dispatch(setPubkey(publicKey));
window.localStorage.setItem('pubkey', publicKey);
if (username) dispatch(setUsername(username));
router.push('/');
} else {
alert('User not created');
}
} catch (createError) {
console.error('Error creating user:', createError);
}
}
}, [dispatch, router]);
// Handle Anonymous Login
const anonymousLogin = useCallback(() => {
const secretKey = generateSecretKey();
const publicKey = getPublicKey(secretKey);
dispatch(setPubkey(publicKey));
window.localStorage.setItem('pubkey', publicKey);
window.localStorage.setItem('seckey', secretKey);
router.push('/');
}, [dispatch, router]);
return { nostrLogin, anonymousLogin };
};

View File

@ -1,79 +1,10 @@
import React from "react";
import axios from "axios";
import { useDispatch } from "react-redux";
import { useRouter } from "next/router";
import { Button } from 'primereact/button';
import { useToast } from "@/hooks/useToast";
import { useNostr } from "@/hooks/useNostr";
import { generateSecretKey, getPublicKey } from 'nostr-tools'
import { findKind0Username } from "@/utils/nostr";
import { setPubkey, setUsername } from "@/redux/reducers/userReducer";
import { useLogin } from "@/hooks/useLogin";
const Login = () => {
const dispatch = useDispatch();
const router = useRouter();
const { showToast } = useToast();
const { fetchKind0 } = useNostr();
const nostrLogin = async () => {
try {
if (!window || !window.nostr) {
throw new Error('Nostr is not available');
}
const publicKey = await window.nostr.getPublicKey();
if (!publicKey) {
throw new Error('Failed to obtain public key');
}
try {
const response = await axios.get(`/api/users/${publicKey}`);
if (response.status === 200 && response.data) {
dispatch(setPubkey(publicKey));
window.localStorage.setItem('pubkey', publicKey);
if (response.data.username) {
dispatch(setUsername(response.data.username));
}
router.push('/');
return;
}
} catch (error) {
if (error.response?.status !== 204) {
throw error; // Rethrow error if it's not the expected 204 status
}
// Handle user creation if status is 204 (No Content)
const kind0 = await fetchKind0([{ authors: [publicKey], kinds: [0] }], {});
const username = kind0 ? await findKind0Username(kind0) : undefined;
const payload = { pubkey: publicKey, ...(username && { username }) };
const createUserResponse = await axios.post(`/api/users`, payload);
if (createUserResponse.status === 201) {
dispatch(setPubkey(publicKey));
window.localStorage.setItem('pubkey', publicKey);
if (username) {
dispatch(setUsername(username));
}
router.push('/');
} else {
showToast('error', 'Error', 'User not created');
}
}
} catch (error) {
showToast('error', 'Error', error.message || 'An unexpected error occurred');
}
};
const anonymousLogin = async () => {
const secretKey = generateSecretKey();
const publicKey = getPublicKey(secretKey);
dispatch(setPubkey(publicKey));
window.localStorage.setItem('pubkey', publicKey);
window.localStorage.setItem('seckey', secretKey);
router.push('/');
};
const { nostrLogin, anonymousLogin } = useLogin();
return (
<div className="w-fit mx-auto mt-24 flex flex-col justify-center">
<h1 className="text-center mb-8">Login</h1>