Use EIP-4361 login method
This commit is contained in:
parent
968ebe07b2
commit
f876b509ba
3 changed files with 75 additions and 12 deletions
|
@ -81,6 +81,28 @@ export async function getAccessToken(user: UserLoginForm): Promise<string> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getAccessTokenEip4361(
|
||||||
|
message: string,
|
||||||
|
signature: string,
|
||||||
|
): Promise<string> {
|
||||||
|
const url = `${BACKEND_URL}/oauth/token`
|
||||||
|
const tokenRequestData = {
|
||||||
|
grant_type: "eip4361",
|
||||||
|
message: message,
|
||||||
|
signature: signature,
|
||||||
|
}
|
||||||
|
const response = await http(url, {
|
||||||
|
method: "POST",
|
||||||
|
json: tokenRequestData,
|
||||||
|
})
|
||||||
|
const data = await response.json()
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(data.message)
|
||||||
|
} else {
|
||||||
|
return data.access_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getCurrentUser(authToken: string): Promise<User | null> {
|
export async function getCurrentUser(authToken: string): Promise<User | null> {
|
||||||
const url = `${BACKEND_URL}/api/v1/accounts/verify_credentials`
|
const url = `${BACKEND_URL}/api/v1/accounts/verify_credentials`
|
||||||
const response = await http(url, { authToken })
|
const response = await http(url, { authToken })
|
||||||
|
|
|
@ -58,3 +58,33 @@ export async function getWalletSignature(
|
||||||
}
|
}
|
||||||
return signature
|
return signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateRandomString(len: number): string {
|
||||||
|
const arr = new Uint8Array(len / 2)
|
||||||
|
window.crypto.getRandomValues(arr)
|
||||||
|
return Array.from(arr, (val) => val.toString(16).padStart(2, "0")).join("")
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createEip4361_SignedMessage(
|
||||||
|
signer: Signer,
|
||||||
|
domain: string,
|
||||||
|
statement: string,
|
||||||
|
): Promise<{ message: string, signature: string }> {
|
||||||
|
const address = await signer.getAddress()
|
||||||
|
const uri = window.location.origin
|
||||||
|
const nonce = generateRandomString(16)
|
||||||
|
const issuedAt = new Date().toISOString()
|
||||||
|
const message = `${domain} wants you to sign in with your Ethereum account:
|
||||||
|
${address}
|
||||||
|
|
||||||
|
${statement}
|
||||||
|
|
||||||
|
URI: ${uri}
|
||||||
|
Version: 1
|
||||||
|
Chain ID: 1
|
||||||
|
Nonce: ${nonce}
|
||||||
|
Issued At: ${issuedAt}`
|
||||||
|
|
||||||
|
const signature = await signer.signMessage(message)
|
||||||
|
return { message, signature }
|
||||||
|
}
|
||||||
|
|
|
@ -53,12 +53,23 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Options, Vue, setup } from "vue-class-component"
|
import { Options, Vue, setup } from "vue-class-component"
|
||||||
|
|
||||||
import { createUser, getAccessToken, getCurrentUser } from "@/api/users"
|
import {
|
||||||
|
createUser,
|
||||||
|
getAccessToken,
|
||||||
|
getAccessTokenEip4361,
|
||||||
|
getCurrentUser,
|
||||||
|
} from "@/api/users"
|
||||||
import { InstanceInfo } from "@/api/instance"
|
import { InstanceInfo } from "@/api/instance"
|
||||||
import Loader from "@/components/Loader.vue"
|
import Loader from "@/components/Loader.vue"
|
||||||
import { useInstanceInfo } from "@/store/instance"
|
import { useInstanceInfo } from "@/store/instance"
|
||||||
import { useCurrentUser } from "@/store/user"
|
import { useCurrentUser } from "@/store/user"
|
||||||
import { getWeb3Provider, getWalletAddress, getWalletSignature } from "@/utils/ethereum"
|
import {
|
||||||
|
getWeb3Provider,
|
||||||
|
getWallet,
|
||||||
|
getWalletAddress,
|
||||||
|
getWalletSignature,
|
||||||
|
createEip4361_SignedMessage,
|
||||||
|
} from "@/utils/ethereum"
|
||||||
|
|
||||||
@Options({
|
@Options({
|
||||||
components: { Loader },
|
components: { Loader },
|
||||||
|
@ -120,24 +131,24 @@ export default class LandingPage extends Vue {
|
||||||
|
|
||||||
async login() {
|
async login() {
|
||||||
this.loginErrorMessage = null
|
this.loginErrorMessage = null
|
||||||
const provider = getWeb3Provider()
|
if (!this.store.instance) {
|
||||||
if (!provider || !this.store.instance) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const instanceHost = this.store.instance.uri
|
||||||
const loginMessage = this.store.instance.login_message
|
const loginMessage = this.store.instance.login_message
|
||||||
const walletAddress = await getWalletAddress(provider)
|
const signer = await getWallet()
|
||||||
if (!walletAddress) {
|
if (!signer) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const signature = await getWalletSignature(provider, walletAddress, loginMessage)
|
const { message, signature } = await createEip4361_SignedMessage(
|
||||||
if (!signature) {
|
signer,
|
||||||
return
|
instanceHost,
|
||||||
}
|
loginMessage,
|
||||||
const loginData = { wallet_address: walletAddress, signature }
|
)
|
||||||
let user
|
let user
|
||||||
let authToken
|
let authToken
|
||||||
try {
|
try {
|
||||||
authToken = await getAccessToken(loginData)
|
authToken = await getAccessTokenEip4361(message, signature)
|
||||||
user = await getCurrentUser(authToken)
|
user = await getCurrentUser(authToken)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.loginErrorMessage = error.message
|
this.loginErrorMessage = error.message
|
||||||
|
|
Loading…
Reference in a new issue