feat(auth): nsec login with url params
All checks were successful
Open PR on Staging / audit_and_check (pull_request) Successful in 34s

This commit is contained in:
enes 2024-10-07 19:17:19 +02:00
parent 532cdaed8e
commit 995c7ce293

View File

@ -1,6 +1,5 @@
import { Event, kinds } from 'nostr-tools'
import { Event, getPublicKey, kinds, nip19 } from 'nostr-tools'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Outlet, useNavigate, useSearchParams } from 'react-router-dom'
import { AppBar } from '../components/AppBar/AppBar'
import { LoadingSpinner } from '../components/LoadingSpinner'
@ -12,12 +11,11 @@ import {
import {
restoreState,
setMetadataEvent,
updateKeyPair,
updateLoginMethod,
updateNostrLoginAuthMethod,
updateUserAppData
} from '../store/actions'
import { State } from '../store/rootReducer'
import { Dispatch } from '../store/store'
import { setUserRobotImage } from '../store/userRobotImage/action'
import {
getRoboHashPicture,
@ -25,7 +23,7 @@ import {
loadState,
subscribeForSigits
} from '../utils'
import { useAppSelector } from '../hooks'
import { useAppDispatch, useAppSelector } from '../hooks'
import styles from './style.module.scss'
import { useLogout } from '../hooks/useLogout'
import { LoginMethod } from '../store/auth/types'
@ -33,13 +31,13 @@ import { NostrLoginAuthOptions } from 'nostr-login/dist/types'
import { init as initNostrLogin } from 'nostr-login'
export const MainLayout = () => {
const [searchParams] = useSearchParams()
const [searchParams, setSearchParams] = useSearchParams()
const navigate = useNavigate()
const dispatch: Dispatch = useDispatch()
const dispatch = useAppDispatch()
const logout = useLogout()
const [isLoading, setIsLoading] = useState(true)
const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState(`Loading App`)
const authState = useSelector((state: State) => state.auth)
const authState = useAppSelector((state) => state.auth)
const usersAppData = useAppSelector((state) => state.userAppData)
// Ref to track if `subscribeForSigits` has been called
@ -125,7 +123,7 @@ export const MainLayout = () => {
}, [])
useEffect(() => {
if (authState.loggedIn && usersAppData) {
if (authState && authState.loggedIn && usersAppData) {
const pubkey = authState.usersPubkey || authState.keyPair?.public
if (pubkey && !hasSubscribed.current) {
@ -164,6 +162,53 @@ export const MainLayout = () => {
}
}, [authState, dispatch])
useEffect(() => {
// Developer login with ?nsec= (not recommended)
const nsec = searchParams.get('nsec')
if (!nsec) return
// Clear nsec from the url immediately
searchParams.delete('nsec')
setSearchParams(searchParams)
if (!authState?.loggedIn) {
if (!nsec.startsWith('nsec')) {
console.error('Invalid format, use private key (nsec)')
return
}
try {
const privateKey = nip19.decode(nsec).data as Uint8Array
if (!privateKey) {
console.error('Failed to convert the private key.')
return
}
const publickey = getPublicKey(privateKey)
dispatch(
updateKeyPair({
private: nsec,
public: publickey
})
)
dispatch(updateLoginMethod(LoginMethod.privateKey))
;(async () => {
const authController = new AuthController()
await authController
.authAndGetMetadataAndRelaysMap(publickey)
.catch((err) => {
console.error('Error occurred in authentication: ' + err)
return null
})
})()
} catch (err) {
console.error(`Error decoding the nsec. ${err}`)
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dispatch, searchParams])
if (isLoading) return <LoadingSpinner desc={loadingSpinnerDesc} />
const isDev = import.meta.env.MODE === 'development'