-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auth structure and LogIn flow (mocked) (#5)
* feat add sign in page and auth module * remove env * remove env * fix after review * feat add setting userDid to mm-zkp context * feat move MMlinkSwitcher to heplers * feat add auth hook * feat: refatore auth module and fix icon * fix rename helper * fix sign in * fixes after review * fix: refactore auth hook
- Loading branch information
1 parent
9b53188
commit 2849088
Showing
18 changed files
with
256 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
export * from './bus' | ||
export * from './icons' | ||
export * from './locals-storage-keys' | ||
export * from './routes' | ||
export * from './theme' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export * from './error-handler' | ||
export * from './event-bus' | ||
export * from './metamask' | ||
export * from './promise' | ||
export * from './store' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { get } from 'lodash' | ||
|
||
const OTHER_BROWSER_METAMASK_LINK = 'https://metamask.io/download/' | ||
const CHROME_METAMASK_ADDON_LINK = 'https://chrome.google.com/webstore/detail/metamask/' | ||
const FIREFOX_METAMASK_ADDON_LINK = 'https://addons.mozilla.org/en-US/firefox/addon/ether-metamask/' | ||
const OPERA_METAMASK_ADDON_LINK = 'https://addons.opera.com/en/extensions/details/metamask-10/' | ||
|
||
export function metamaskLink() { | ||
const browserExtensionsLinks = { | ||
chrome: CHROME_METAMASK_ADDON_LINK, | ||
opera: OPERA_METAMASK_ADDON_LINK, | ||
firefox: FIREFOX_METAMASK_ADDON_LINK, | ||
} | ||
|
||
// Get the user-agent string | ||
const userAgentString = navigator.userAgent | ||
|
||
let chromeAgent = userAgentString.indexOf('Chrome') > -1 ? 'chrome' : '' | ||
const firefoxAgent = userAgentString.indexOf('Firefox') > -1 ? 'firefox' : '' | ||
const operaAgent = userAgentString.indexOf('OP') > -1 ? 'opera' : '' | ||
|
||
// Discard Chrome since it also matches Opera | ||
if (chromeAgent && operaAgent) chromeAgent = '' | ||
|
||
const currentBrowser = chromeAgent || firefoxAgent || operaAgent || '' | ||
|
||
if (!currentBrowser) return OTHER_BROWSER_METAMASK_LINK | ||
|
||
return get(browserExtensionsLinks, currentBrowser, '') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { PROVIDERS } from '@distributedlab/w3p' | ||
import { useCallback, useMemo, useState } from 'react' | ||
|
||
import { useMetamaskZkpSnapContext } from '@/hooks/metamask-zkp-snap' | ||
import { useWeb3Context } from '@/hooks/web3' | ||
import { authStore, useAuthState } from '@/store' | ||
|
||
export const useAuth = () => { | ||
const { jwt: storeJwt } = useAuthState() | ||
const { init, provider } = useWeb3Context() | ||
const { connectOrInstallSnap, isSnapInstalled } = useMetamaskZkpSnapContext() | ||
const [isJwtValid, setIsJwtValid] = useState(false) | ||
|
||
const isAuthorized = useMemo( | ||
() => provider?.isConnected && isSnapInstalled && isJwtValid, | ||
[isJwtValid, isSnapInstalled, provider?.isConnected], | ||
) | ||
|
||
const _setJwt = useCallback((jwt: string) => { | ||
authStore.setJwt(jwt) | ||
}, []) | ||
|
||
const checkJwtValid = useCallback(async () => { | ||
//Todo: add real logic | ||
return true | ||
}, []) | ||
|
||
const logOut = useCallback(async () => { | ||
await provider?.disconnect() | ||
_setJwt('') | ||
setIsJwtValid(false) | ||
}, [_setJwt, provider]) | ||
|
||
const authorize = useCallback( | ||
async (jwt?: string) => { | ||
const currentJwt = jwt || storeJwt | ||
|
||
if (!currentJwt) await logOut() | ||
|
||
const isJwtValid = await checkJwtValid() | ||
|
||
if (isJwtValid) { | ||
setIsJwtValid(true) | ||
_setJwt(currentJwt) | ||
return | ||
} | ||
|
||
logOut() | ||
|
||
// TODO: Replace with real auth check | ||
}, | ||
[_setJwt, checkJwtValid, storeJwt, logOut], | ||
) | ||
|
||
const login = useCallback(async () => { | ||
await init(PROVIDERS.Metamask) | ||
await connectOrInstallSnap() | ||
// TODO: generateProof and /login | ||
const jwt = 'mockJwt' | ||
|
||
await authorize(jwt) | ||
}, [authorize, connectOrInstallSnap, init]) | ||
|
||
return { | ||
isAuthorized, | ||
storeJwt, | ||
login, | ||
authorize, | ||
logOut, | ||
checkJwtValid, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './auth' | ||
export * from './form' | ||
export * from './interval' | ||
export * from './loading' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,89 @@ | ||
import { PROVIDERS } from '@distributedlab/w3p' | ||
import { Stack, Typography } from '@mui/material' | ||
import { useEffect } from 'react' | ||
import { Stack, Typography, useTheme } from '@mui/material' | ||
import { useCallback, useMemo, useState } from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
import { useNavigate } from 'react-router-dom' | ||
|
||
import { Routes } from '@/enums' | ||
import { useMetamaskZkpSnapContext, useWeb3Context } from '@/hooks' | ||
import { UiButton } from '@/ui' | ||
import { BusEvents, Icons } from '@/enums' | ||
import { bus, ErrorHandler, metamaskLink } from '@/helpers' | ||
import { useAuth, useMetamaskZkpSnapContext } from '@/hooks' | ||
import { UiButton, UiIcon } from '@/ui' | ||
|
||
export default function SignIn() { | ||
const navigate = useNavigate() | ||
const { t } = useTranslation() | ||
const { init: initWeb3, provider } = useWeb3Context() | ||
const { connectOrInstallSnap } = useMetamaskZkpSnapContext() | ||
const { login } = useAuth() | ||
const [isPending, setIsPending] = useState(false) | ||
|
||
const connectWallet = async () => { | ||
await initWeb3(PROVIDERS.Metamask) | ||
await connectOrInstallSnap() | ||
} | ||
const { palette } = useTheme() | ||
const { isMetamaskInstalled } = useMetamaskZkpSnapContext() | ||
|
||
useEffect(() => { | ||
if (provider?.isConnected) { | ||
navigate(Routes.Profiles) | ||
const signIn = useCallback(async () => { | ||
setIsPending(true) | ||
|
||
try { | ||
await login() | ||
} catch (error) { | ||
ErrorHandler.process(error) | ||
} | ||
}, [navigate, provider?.isConnected]) | ||
|
||
setIsPending(false) | ||
}, [login]) | ||
|
||
const installMMLink = useMemo(() => { | ||
if (isMetamaskInstalled) return '' | ||
|
||
return metamaskLink() | ||
}, [isMetamaskInstalled]) | ||
|
||
const openInstallMetamaskLink = useCallback(() => { | ||
if (!installMMLink) { | ||
bus.emit(BusEvents.warning, `Your browser is not support Metamask`) | ||
|
||
return | ||
} | ||
|
||
setIsPending(true) | ||
|
||
window.open(installMMLink, '_blank', 'noopener noreferrer') | ||
}, [installMMLink]) | ||
|
||
return ( | ||
<Stack flex={1}> | ||
<Typography>{t('sign-in-page.title')}</Typography> | ||
<Typography>{t('sign-in-page.description')}</Typography> | ||
<UiButton onClick={connectWallet}>Connect</UiButton> | ||
<Stack | ||
maxWidth={520} | ||
borderRadius={4} | ||
p={16} | ||
flexDirection='column' | ||
alignItems='center' | ||
bgcolor={palette.background.paper} | ||
> | ||
<UiIcon | ||
size={22} | ||
name={Icons.User} | ||
sx={{ background: palette.background.default, borderRadius: 100 }} | ||
color={palette.primary.main} | ||
/> | ||
{/*Todo: add metamask not found texts*/} | ||
<Typography component='h4' variant='h4' sx={{ my: 4 }}> | ||
{t('sign-in-page.title')} | ||
</Typography> | ||
<Typography variant='body2' marginBottom={8} textAlign={'center'}> | ||
{t('sign-in-page.description')} | ||
</Typography> | ||
{isMetamaskInstalled ? ( | ||
<UiButton | ||
onClick={signIn} | ||
startIcon={<UiIcon name={Icons.Metamask} />} | ||
disabled={isPending} | ||
> | ||
{t('sign-in-page.connect-btn')} | ||
</UiButton> | ||
) : ( | ||
<UiButton | ||
onClick={openInstallMetamaskLink} | ||
startIcon={<UiIcon name={Icons.Metamask} />} | ||
disabled={isPending} | ||
> | ||
{isPending ? t('sign-in-page.reload-page-btn') : t('sign-in-page.install-btn')} | ||
</UiButton> | ||
)} | ||
</Stack> | ||
) | ||
} |
Oops, something went wrong.