Skip to content

Commit

Permalink
feat(unlock-app) - Login and authorized endpoints (#8859)
Browse files Browse the repository at this point in the history
verifiers page with full functionalities
  • Loading branch information
kalidiagne authored Jun 3, 2022
1 parent 194ce25 commit 92507e1
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 42 deletions.
3 changes: 1 addition & 2 deletions packages/unlock-js/src/locksmithService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import fetch from 'cross-fetch'
import fetch, { Headers } from 'cross-fetch'
import { SiweMessage } from 'siwe'
import { FetchError } from './utils'

export const PRODUCTION_HOST = 'https://locksmith.unlock-protocol.com'

interface LocksmithOptions {
Expand Down
1 change: 1 addition & 0 deletions unlock-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"react-hot-toast": "2.2.0",
"react-icons": "4.4.0",
"react-jazzicon": "1.0.3",
"react-jwt": "^1.1.6",
"react-test-renderer": "18.1.0",
"react-use-clipboard": "1.0.8",
"siwe": "1.1.6",
Expand Down
66 changes: 58 additions & 8 deletions unlock-app/src/components/content/VerifiersContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { VerifiersList } from '../interface/verifiers/VerifiersList'
import { getAddressForName } from '../../hooks/useEns'
import { ToastHelper } from '../helpers/toast.helper'
import AuthenticationContext from '../../contexts/AuthenticationContext'
import { useStorageService } from '../../utils/withStorageService'

const styling = {
sectionWrapper: 'text-left mx-2 my-3',
Expand All @@ -30,8 +31,10 @@ export const VerifiersContent: React.FC<VerifiersContentProps> = ({
const [addVerifierModalOpen, setAddVerifierModalOpen] = useState(false)
const [verifierAddress, setVerifierAddress] = useState('')
const [loading, setLoading] = useState(false)
const [verifiers, setVerifiers] = useState<any[]>([])
const lockAddress: string = query?.lockAddress ?? ''
const { network } = useContext(AuthenticationContext)
const storageService = useStorageService()

const onAddVerifier = () => {
setVerifierAddress('')
Expand All @@ -48,30 +51,72 @@ export const VerifiersContent: React.FC<VerifiersContentProps> = ({
const resolvedAddress = await getAddressForName(verifierAddress)
try {
if (resolvedAddress) {
const addVerifierUrl = `/verifier/${network}/${lockAddress}/${resolvedAddress}`
const requestOptions = {
const options = {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
headers: {
'Content-Type': 'application/json',
},
}
await fetch(addVerifierUrl, requestOptions)
.then((res) => res.json())
.then(() => {
ToastHelper.success('Verifier added to list')
await storageService
.getEndpoint(
`/v2/api/verifier/${network}/${lockAddress}/${resolvedAddress}`,
options,
true /* withAuth */
)
.then((res: any) => {
if (res.message) {
ToastHelper.error(res.message)
} else {
ToastHelper.success('Verifier added to list')
getVerifierList() // get updated list with last item added
setAddVerifierModalOpen(false)
}
})

setLoading(false)
} else {
ToastHelper.error('Verified address is not a valid Ethereum address.')
setLoading(false)
}
} catch (err: any) {
setLoading(false)
console.error(err)
ToastHelper.error(
err?.error ??
'There was a problem adding the verifier address, please re-load and try again'
)
}
}

const getVerifierList = async () => {
try {
const options = {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
}
await storageService
.getEndpoint(
`/v2/api/verifier/list/${network}/${lockAddress}`,
options,
true /* withAuth */
)
.then((res: any) => {
if (res.message) {
ToastHelper.error(res.message)
} else {
setVerifiers(res?.results)
}
})
} catch (err: any) {
setLoading(false)
console.error(err)
ToastHelper.error(
err?.error ??
'We could not load the list of verifiers for your lock. Please reload to to try again.'
)
}
}

return (
<Layout title="Verifiers">
<Head>
Expand All @@ -83,7 +128,12 @@ export const VerifiersContent: React.FC<VerifiersContentProps> = ({
<span>A list for all verifiers for your event</span>
<Button onClick={onAddVerifier}>Add verifier</Button>
</Header>
<VerifiersList lockAddress={lockAddress} />
<VerifiersList
lockAddress={lockAddress}
getVerifierList={getVerifierList}
verifiers={verifiers}
setVerifiers={setVerifiers}
/>
</VerifierContent>

<Modal isOpen={addVerifierModalOpen} setIsOpen={onAddVerifier}>
Expand Down
82 changes: 52 additions & 30 deletions unlock-app/src/components/interface/verifiers/VerifiersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { ethers } from 'ethers'
import AuthenticationContext from '../../../contexts/AuthenticationContext'
import { ToastHelper } from '../../helpers/toast.helper'
import Loading from '../Loading'
import { ConfigContext } from '../../../utils/withConfig'
import { WalletServiceContext } from '../../../utils/withWalletService'
import { useStorageService } from '~/utils/withStorageService'

const styling = {
sectionWrapper: 'text-left mx-2 my-3',
Expand All @@ -17,16 +18,23 @@ const styling = {
}
interface VerifiersListProsps {
lockAddress: string
getVerifierList: () => void
verifiers: any[]
setVerifiers: any
}
export const VerifiersList: React.FC<VerifiersListProsps> = ({
lockAddress,
getVerifierList,
verifiers,
setVerifiers,
}) => {
const { network } = useContext(AuthenticationContext)
const { network, account } = useContext(AuthenticationContext)
const [selectedVerifier, setSelectedVerifier] = useState('')
const [showDeleteVerifierModal, setShowDeleteVerifierModal] = useState(false)
const [loading, setLoading] = useState(false)
const [verifiers, setVerifiers] = useState<any[]>([])
const config: any = useContext(ConfigContext)
const [logged, setLogged] = useState(false)
const storageService = useStorageService()
const walletService = useContext(WalletServiceContext)

const setDefaults = () => {
setShowDeleteVerifierModal(false)
Expand All @@ -35,41 +43,41 @@ export const VerifiersList: React.FC<VerifiersListProsps> = ({
}

useEffect(() => {
getVerifierList()
loginAndGetList()
}, [])

const getVerifierList = async () => {
const loginAndGetList = async () => {
try {
const addVerifierUrl = `${config.services.storage.host}/v2/api/verifier/${network}/${lockAddress}/${selectedVerifier}`
const requestOptions = {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
}
await fetch(addVerifierUrl, requestOptions)
.then((res) => res.json())
.then((verifiers: any) => {
setVerifiers(verifiers?.results)
})
} catch (err: any) {
setLoading(false)
ToastHelper.error(
err?.error ??
'We could not load the list of verifiers for your lock. Please reload to to try again.'
)
await storageService.loginPrompt({
walletService,
address: account!,
chainId: network!,
})
setLogged(true)
getVerifierList()
} catch (err) {
setLogged(false)
}
}

const onConfirmDeleteVerifier = async () => {
setLoading(true)
const isValid = ethers.utils.isAddress(selectedVerifier)

try {
if (isValid) {
const addVerifierUrl = `/verifier/${network}/${lockAddress}/${selectedVerifier}`
const requestOptions = {
const options = {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
headers: {
'Content-Type': 'application/json',
},
}
await fetch(addVerifierUrl, requestOptions)
.then((res) => res.json())
await storageService
.getEndpoint(
`/v2/api/verifier/${network}/${lockAddress}/${selectedVerifier}`,
options,
true /* withAuth */
)
.then((verifiers: any) => {
ToastHelper.success('Verifier deleted from list')
setVerifiers(verifiers?.results)
Expand All @@ -83,6 +91,7 @@ export const VerifiersList: React.FC<VerifiersListProsps> = ({
}
} catch (err: any) {
setLoading(false)
console.error(err)
ToastHelper.error(
err?.error ??
'There was a problem adding verifier, please re-load and try again'
Expand All @@ -96,25 +105,38 @@ export const VerifiersList: React.FC<VerifiersListProsps> = ({
setShowDeleteVerifierModal(true)
}

if (!logged) {
return (
<>
<span>Sign message in your wallet to show verifiers list.</span>
</>
)
}
return (
<>
<table className="w-full mt-3">
<thead>
<tr>
<th>Address</th>
<th className="text-left">Created at</th>
<th className="text-left">Verified at</th>
<th className="text-left">Updated at</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{verifiers?.map((verifier: any, index: number) => {
const key = `${verifier?.address}-${index}`
const createdAt = verifier?.createdAt
? new Date(verifier?.createdAt).toLocaleString()
: '-'
const updatedAt = verifier?.updatedAt
? new Date(verifier?.updatedAt).toLocaleString()
: '-'
return (
<tr key={key}>
<td>{verifier?.address ?? '-'}</td>
<td>{verifier?.createdAt ?? '-'}</td>
<td>{verifier?.updatedAt ?? '-'}</td>
<td>{createdAt ?? '-'}</td>
<td>{updatedAt ?? '-'}</td>
<td>
<Tooltip tip="Remove verifier" label="Remove verifier">
<TrashIcon
Expand Down
2 changes: 1 addition & 1 deletion unlock-app/src/hooks/useAppStorage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback } from 'react'

const APP_NAME = '@unlock-app'
export const APP_NAME = '@unlock-app'

export function useAppStorage() {
const isObject = useCallback((value: any) => typeof value === 'object', [])
Expand Down
Loading

0 comments on commit 92507e1

Please sign in to comment.