From 497372160843f11d0b206fa490992d257004d773 Mon Sep 17 00:00:00 2001 From: Sabir Hassan Date: Fri, 22 Mar 2024 12:29:23 +0500 Subject: [PATCH] feat: added the ability to login with nsecbunker connection string --- src/components/AppBar/AppBar.tsx | 4 +- src/pages/login/index.tsx | 71 ++++++++++++++++++++++++++++++-- src/store/actionTypes.ts | 1 + src/store/auth/action.ts | 10 ++++- src/store/auth/reducer.ts | 12 +++++- src/store/auth/types.ts | 7 ++++ 6 files changed, 99 insertions(+), 6 deletions(-) diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx index 7beae68..763af39 100644 --- a/src/components/AppBar/AppBar.tsx +++ b/src/components/AppBar/AppBar.tsx @@ -67,7 +67,9 @@ export const AppBar = () => { setAuthState({ loggedIn: false, usersPubkey: undefined, - loginMethod: undefined + loginMethod: undefined, + nsecBunkerPubkey: undefined, + nsecbunkerRelay: undefined }) ) diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 63e4bc6..034f603 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -12,13 +12,14 @@ import { import { updateKeyPair, updateLoginMethod, - updateNsecbunkerPubkey + updateNsecbunkerPubkey, + updateNsecbunkerRelay } from '../../store/actions' import { LoginMethods } from '../../store/auth/types' import { Dispatch } from '../../store/store' import styles from './style.module.scss' import { useNavigate } from 'react-router-dom' -import { queryNip05 } from '../../utils' +import { pubToHex, queryNip05 } from '../../utils' export const Login = () => { const dispatch: Dispatch = useDispatch() @@ -206,7 +207,71 @@ export const Login = () => { }) } + const loginWithBunkerConnectionString = async () => { + // Extract the key + const keyStartIndex = inputValue.indexOf('bunker://') + 'bunker://'.length + const keyEndIndex = inputValue.indexOf('?relay=') + const key = inputValue.substring(keyStartIndex, keyEndIndex) + + const pubkey = await pubToHex(key) + + if (!pubkey) { + toast.error('Invalid pubkey in bunker connection string.') + setIsLoading(false) + return + } + + // Extract the relay value + const relayIndex = inputValue.indexOf('relay=') + const relay = inputValue.substring( + relayIndex + 'relay='.length, + inputValue.length + ) + + setIsLoading(true) + setLoadingSpinnerDesc('Initializing bunker NDK') + + await nostrController.nsecBunkerInit([relay]) + + setLoadingSpinnerDesc('Creating remote signer') + await nostrController + .createNsecBunkerSigner(pubkey) + .then(async (signer) => { + signer.on('authUrl', (url: string) => { + setAuthUrl(url) + }) + + dispatch(updateLoginMethod(LoginMethods.nsecBunker)) + dispatch(updateNsecbunkerPubkey(pubkey)) + dispatch(updateNsecbunkerRelay(relay)) + + setLoadingSpinnerDesc('Authenticating and finding metadata') + + const redirectPath = await authController + .authenticateAndFindMetadata(pubkey!) + .catch((err) => { + toast.error('Error occurred in authentication: ' + err) + return null + }) + + if (redirectPath) navigate(redirectPath) + }) + .catch((err) => { + toast.error( + 'An error occurred while creating nsecbunker signer: ' + err + ) + }) + .finally(() => { + setIsLoading(false) + setLoadingSpinnerDesc('') + }) + } + const login = () => { + if (inputValue.startsWith('bunker://')) { + return loginWithBunkerConnectionString() + } + if (inputValue.startsWith('nsec')) { return loginWithNsec() } @@ -238,7 +303,7 @@ export const Login = () => {
Welcome to Sigit setInputValue(e.target.value)} sx={{ width: '100%', mt: 2 }} diff --git a/src/store/actionTypes.ts b/src/store/actionTypes.ts index f1d649f..233d73c 100644 --- a/src/store/actionTypes.ts +++ b/src/store/actionTypes.ts @@ -4,5 +4,6 @@ export const SET_AUTH_STATE = 'SET_AUTH_STATE' export const UPDATE_LOGIN_METHOD = 'UPDATE_LOGIN_METHOD' export const UPDATE_KEYPAIR = 'UPDATE_KEYPAIR' export const UPDATE_NSECBUNKER_PUBKEY = 'UPDATE_NSECBUNKER_PUBKEY' +export const UPDATE_NSECBUNKER_RELAY = 'UPDATE_NSECBUNKER_RELAY' export const SET_METADATA_EVENT = 'SET_METADATA_EVENT' diff --git a/src/store/auth/action.ts b/src/store/auth/action.ts index ac9e39d..ce37944 100644 --- a/src/store/auth/action.ts +++ b/src/store/auth/action.ts @@ -6,7 +6,8 @@ import { SetAuthState, UpdateKeyPair, UpdateLoginMethod, - UpdateNsecBunkerPubkey + UpdateNsecBunkerPubkey, + UpdateNsecbunkerRelay } from './types' export const setAuthState = (payload: AuthState): SetAuthState => ({ @@ -32,3 +33,10 @@ export const updateNsecbunkerPubkey = ( type: ActionTypes.UPDATE_NSECBUNKER_PUBKEY, payload }) + +export const updateNsecbunkerRelay = ( + payload: string | undefined +): UpdateNsecbunkerRelay => ({ + type: ActionTypes.UPDATE_NSECBUNKER_RELAY, + payload +}) diff --git a/src/store/auth/reducer.ts b/src/store/auth/reducer.ts index e384076..a67488f 100644 --- a/src/store/auth/reducer.ts +++ b/src/store/auth/reducer.ts @@ -11,12 +11,13 @@ const reducer = ( ): AuthState | null => { switch (action.type) { case ActionTypes.SET_AUTH_STATE: { - const { loginMethod, keyPair, nsecBunkerPubkey } = state + const { loginMethod, keyPair, nsecBunkerPubkey, nsecbunkerRelay } = state return { loginMethod, keyPair, nsecBunkerPubkey, + nsecbunkerRelay, ...action.payload } } @@ -47,6 +48,15 @@ const reducer = ( } } + case ActionTypes.UPDATE_NSECBUNKER_RELAY: { + const { payload } = action + + return { + ...state, + nsecbunkerRelay: payload + } + } + default: return state } diff --git a/src/store/auth/types.ts b/src/store/auth/types.ts index 41e76be..fbecf09 100644 --- a/src/store/auth/types.ts +++ b/src/store/auth/types.ts @@ -18,6 +18,7 @@ export interface AuthState { loginMethod?: LoginMethods keyPair?: Keys nsecBunkerPubkey?: string + nsecbunkerRelay?: string } export interface SetAuthState { @@ -40,8 +41,14 @@ export interface UpdateNsecBunkerPubkey { payload: string | undefined } +export interface UpdateNsecbunkerRelay { + type: typeof ActionTypes.UPDATE_NSECBUNKER_RELAY + payload: string | undefined +} + export type AuthDispatchTypes = | SetAuthState | UpdateLoginMethod | UpdateKeyPair | UpdateNsecBunkerPubkey + | UpdateNsecbunkerRelay