Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions packages/frontend/src/contexts/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { createContext } from 'react'
import { makeAutoObservable } from 'mobx'

import { SERVER } from '../config'

export default class Auth {
constructor() {
makeAutoObservable(this)
}

async join(platform) {
console.log('join through', platform)

// authorization through relay
const currentUrl = new URL(window.location.href)
const dest = new URL('/join', currentUrl.origin)

if (platform === 'twitter') {
const url = new URL('/api/oauth/twitter', SERVER)
url.searchParams.set('redirectDestination', dest.toString())
url.searchParams.set('isSigningUp', true)
window.location.replace(url.toString())
}
if (platform === 'github') {
const url = new URL('/api/oauth/github', SERVER)
url.searchParams.set('redirectDestination', dest.toString())
url.searchParams.set('isSigningUp', true)
window.location.replace(url.toString())
}
}

async signInWithGithub() {
try {
const res = await fetch('/api/auth/github')
const { url } = await res.json()
window.location.replace(url)
} catch (error) {
console.error(error)
}
}

async signInWithTwitter() {
try {
const res = await fetch('/api/auth/twitter')
const { url } = await res.json()
window.location.replace(url)
} catch (error) {
console.error(error)
}
}
}
3 changes: 3 additions & 0 deletions packages/frontend/src/contexts/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { createContext } from 'react'
import Interface from './interface'
import User from './User'
import Address from './address'
import Auth from './auth'

const state = {}

const address = new Address(state)
const auth = new Auth(state)
const ui = new Interface(state)
const user = new User(state)

Object.assign(state, {
address,
auth,
ui,
user,
})
Expand Down
4 changes: 3 additions & 1 deletion packages/frontend/src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Header from './pages/Header'
import Start from './pages/Start'
import Address from './pages/Address'
import Auth from './pages/Auth'
import './index.css'

export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Header />}>
<Route index element={<Start />} />
<Route index element={<Auth />} />
<Route path="start" element={<Start />} />
<Route path="address" element={<Address />} />
</Route>
</Routes>
Expand Down
111 changes: 111 additions & 0 deletions packages/frontend/src/pages/Auth.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, { useEffect, useState, useContext } from 'react'
import { observer } from 'mobx-react-lite'
import { Link, useNavigate, useSearchParams } from 'react-router-dom'
import Button from '../components/Button'

import state from '../contexts/state'

export default observer(() => {
const navigate = useNavigate()
const [params, setParams] = useSearchParams()

const { auth, user } = useContext(state)

const [isLoading, setIsLoading] = useState(false)
const [errorMsg, setErrorMsg] = useState('')
const [idInput, setIdInput] = useState('')

const signup = async (platform, access_token) => {
setErrorMsg('')
setIsLoading(true)
try {
await user.signup(platform, access_token)
await user.getRep(platform)
return navigate('/user')
} catch (e) {
setErrorMsg(e.toString())
setIsLoading(false)
}
}

useEffect(() => {
const platform = params.get('platform')
const access_token = params.get('access_token')
const signupError = params.get('signupError')
const isSigningUp = params.get('isSigningUp')
if (platform && access_token) {
if (isSigningUp && parseInt(isSigningUp)) {
signup(platform, access_token)
} else {
user.storeAccessToken(platform, access_token)
}
} else if (signupError) {
setErrorMsg(
`Sign up through ${platform.toUpperCase()} error: ${signupError}`
)
}
setParams('')
}, [])

const login = async () => {
try {
await user.login(idInput)
return navigate('/user')
} catch (e) {
setErrorMsg(e.toString())
}
}

const onIdInputChange = (event) => {
setIdInput(event.target.value)
}

return (
<>
{isLoading ? (
<div className="join-container">
<Loader active inline="centered" size="huge" />
<Link to="/help">Any question?</Link>
</div>
) : (
<div className="join-container">
{errorMsg.length > 0 && (
<Message error header="Oops!" content={errorMsg} />
)}
<Button
basic
color="blue"
size="huge"
onClick={() => auth.join('twitter')}
>
<span>Join with Twitter</span>
</Button>
<Button
basic
color="black"
size="huge"
onClick={() => auth.join('github')}
>
<span>Join with Github</span>
</Button>

<div>Already has account?</div>
</div>
)}
</>
)
})

{
/* <Form>
<TextArea
placeholder="Please enter your private key."
style={{ width: '300px' }}
onChange={onIdInputChange}
/>
</Form>
<Button basic size="large" onClick={login}>
Log in
</Button>
<Link to="/help">Any question?</Link> */
}
28 changes: 17 additions & 11 deletions packages/relay/src/config.mjs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { ethers } from "ethers";
import _config from "../../../config.js";
import { config } from "dotenv";
config();
import { ethers } from 'ethers'
import _config from '../../../config.js'
import { config } from 'dotenv'
config()

export const UNIREP_ADDRESS =
process.env.UNIREP_ADDRESS ?? _config.UNIREP_ADDRESS;
process.env.UNIREP_ADDRESS ?? _config.UNIREP_ADDRESS
export const ADDRESS_ADDRESS =
process.env.ADDRESS_ADDRESS ?? _config.ADDRESS_ADDRESS;
process.env.ADDRESS_ADDRESS ?? _config.ADDRESS_ADDRESS
export const ETH_PROVIDER_URL =
process.env.ETH_PROVIDER_URL ?? _config.ETH_PROVIDER_URL;
export const PRIVATE_KEY = process.env.PRIVATE_KEY ?? _config.PRIVATE_KEY;
process.env.ETH_PROVIDER_URL ?? _config.ETH_PROVIDER_URL
export const PRIVATE_KEY = process.env.PRIVATE_KEY ?? _config.PRIVATE_KEY

export const DB_PATH = process.env.DB_PATH ?? ":memory:";
export const DB_PATH = process.env.DB_PATH ?? ':memory:'

export const provider = ETH_PROVIDER_URL.startsWith("http")
export const provider = ETH_PROVIDER_URL.startsWith('http')
? new ethers.providers.JsonRpcProvider(ETH_PROVIDER_URL)
: new ethers.providers.WebSocketProvider(ETH_PROVIDER_URL);
: new ethers.providers.WebSocketProvider(ETH_PROVIDER_URL)

export const TWITTER_CLIENT_ID = process.env.TWITTER_CLIENT_ID ?? ''
export const TWITTER_REDIRECT_URI = process.env.TWITTER_REDIRECT_URI ?? ''
export const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID ?? ''
export const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET ?? ''
export const GITHUB_REDIRECT_URI = process.env.GITHUB_REDIRECT_URI ?? ''
Loading