sigit.io/src/hooks/useAuth.ts

147 lines
3.8 KiB
TypeScript
Raw Normal View History

import { EventTemplate } from 'nostr-tools'
import { useCallback } from 'react'
import { NostrController } from '../controllers'
import { appPrivateRoutes } from '../routes'
import {
setAuthState,
setRelayMapAction,
setUserProfile
} from '../store/actions'
import {
base64DecodeAuthToken,
compareObjects,
createAndSaveAuthToken,
getAuthToken,
getRelayMapFromNDKRelayList,
unixNow
} from '../utils'
import { useAppDispatch, useAppSelector } from './store'
import { useNDKContext } from './useNDKContext'
import { useDvm } from './useDvm'
2025-01-13 12:13:03 +01:00
import { getFileServerMap } from '../utils/file-servers.ts'
import store from '../store/store.ts'
import { setServerMapAction } from '../store/servers/action.ts'
export const useAuth = () => {
const dispatch = useAppDispatch()
const { getRelayInfo } = useDvm()
2025-01-13 12:13:03 +01:00
const { findMetadata, getNDKRelayList, fetchEvent } = useNDKContext()
2024-12-28 00:43:00 +05:00
const authState = useAppSelector((state) => state.auth)
const relaysState = useAppSelector((state) => state.relays)
const checkSession = useCallback(() => {
const savedAuthToken = getAuthToken()
if (savedAuthToken) {
const signedEvent = base64DecodeAuthToken(savedAuthToken)
dispatch(
setAuthState({
loggedIn: true,
usersPubkey: signedEvent.pubkey
})
)
return
}
dispatch(
setAuthState({
loggedIn: false,
usersPubkey: undefined
})
)
}, [dispatch])
/**
* Function will authenticate user by signing an auth event
* which is done by calling the sign() function, where appropriate
* method will be chosen (extension or keys)
*
* @param pubkey of the user trying to login
* @returns url to redirect if authentication successfull
* or error if otherwise
*/
const authAndGetMetadataAndRelaysMap = useCallback(
async (pubkey: string) => {
try {
2024-12-28 00:43:00 +05:00
const profile = await findMetadata(pubkey)
dispatch(setUserProfile(profile))
} catch (err) {
console.warn('Error occurred while finding metadata', err)
}
const timestamp = unixNow()
const { href } = window.location
const authEvent: EventTemplate = {
kind: 27235,
tags: [
['u', href],
['method', 'GET']
],
content: '',
created_at: timestamp
}
const nostrController = NostrController.getInstance()
const signedAuthEvent = await nostrController.signEvent(authEvent)
createAndSaveAuthToken(signedAuthEvent)
dispatch(
setAuthState({
loggedIn: true,
usersPubkey: pubkey
})
)
2025-01-13 12:13:03 +01:00
const ndkRelayListPromise = getNDKRelayList(pubkey)
const serverMapPromise = getFileServerMap(pubkey, fetchEvent)
const [ndkRelayList, serverMap] = await Promise.all([
ndkRelayListPromise,
serverMapPromise
])
const relays = ndkRelayList.relays
if (relays.length < 1) {
2025-01-13 12:13:03 +01:00
// Navigate user to relays page if a relay map is empty
return appPrivateRoutes.relays
}
2025-01-13 12:13:03 +01:00
if (Object.keys(serverMap).length < 1) {
// Navigate user to servers page if a server map is empty
return appPrivateRoutes.servers
}
getRelayInfo(relays)
const relayMap = getRelayMapFromNDKRelayList(ndkRelayList)
2025-01-13 12:13:03 +01:00
if (authState.loggedIn) {
if (!compareObjects(relaysState?.map, relayMap))
dispatch(setRelayMapAction(relayMap))
if (!compareObjects(store.getState().servers?.map, serverMap.map))
dispatch(setServerMapAction(serverMap.map))
}
return appPrivateRoutes.homePage
},
[
dispatch,
getNDKRelayList,
2025-01-13 12:13:03 +01:00
fetchEvent,
getRelayInfo,
2025-01-13 12:13:03 +01:00
authState.loggedIn,
findMetadata,
relaysState?.map
]
)
return {
authAndGetMetadataAndRelaysMap,
checkSession
}
}