Skip to content

Commit

Permalink
🔀 Merge #474 to deploy/rinkeby
Browse files Browse the repository at this point in the history
  • Loading branch information
AuroraHuang22 committed Sep 11, 2024
2 parents a1e52ed + 625e92c commit a29dc20
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 25 deletions.
31 changes: 28 additions & 3 deletions components/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,21 @@ import logTrackerEvent, { setLoggerUser } from '~/utils/logger'
import { IS_TESTNET } from '~/constant'

const walletModule = namespace('wallet')
const bookApiModule = namespace('book-api')

@Component
export default class AppHeader extends Vue {
@walletModule.Getter('getType') walletType!: string | null
@walletModule.Action('disconnectWallet') disconnectWallet!: () => void
@walletModule.Action('openConnectWalletModal') openConnectWalletModal!: (params: { language: string, fullPath?: string }) => Promise<any>
@walletModule.Action('initWallet') initWallet!: (params: { method: any, accounts: any, offlineSigner?: any }) => Promise<any>
@walletModule.Action('signMessageMemo') signMessageMemo!: (action: string, permissions?: string[]) => Promise<any>
@walletModule.Getter('getWalletAddress') currentAddress!: string
@walletModule.Getter('getSigner') signer!: any
@bookApiModule.Action('authenticate') authenticate!: ({ inputWallet, signature }: { inputWallet?: string, signature?: any }) => Promise<any>
@bookApiModule.Action('clearSession') clearSession!: () => void

isLoading = false

// eslint-disable-next-line class-methods-use-this
get isTestnet() {
Expand All @@ -184,11 +191,13 @@ export default class AppHeader extends Vue {
}

async handleConnectWalletButtonClick() {
this.isLoading = true
const connection = await this.openConnectWalletModal({
language: this.$i18n.locale.split('-')[0],
fullPath: this.$route.fullPath,
})
if (connection) {
try {
if (connection) {
const { method, accounts } = connection
logTrackerEvent(
this,
Expand All @@ -201,9 +210,25 @@ export default class AppHeader extends Vue {
wallet: accounts[0].address,
method,
})
return this.initWallet(connection)
await this.initWallet(connection)
if (!this.currentAddress || !this.signer) return
const signature = await this.signMessageMemo('authorize', [
'profile',
'read:nftbook',
'write:nftbook',
'read:nftcollection',
'write:nftcollection',
])
if (!signature) { return }
await this.authenticate({inputWallet:this.currentAddress, signature})
}
} catch (error) {
this.disconnectWallet()
this.clearSession()
// eslint-disable-next-line no-console
console.error('handleConnectWalletButtonClick error', error)
}
return false
this.isLoading = false
}
}
</script>
7 changes: 4 additions & 3 deletions components/RootLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import { Vue, Component, Prop } from 'vue-property-decorator'
import { namespace } from 'vuex-class'
import { IS_CHAIN_UPGRADING } from '~/constant'
const walletModule = namespace('wallet')
const bookApiModule = namespace('book-api')
@Component({
head() {
Expand All @@ -38,15 +39,15 @@ const walletModule = namespace('wallet')
},
})
export default class RootLayout extends Vue {
@walletModule.Action('restoreSessionIfNecessary') restoreSessionIfNecessary!: () => Promise<any>
@bookApiModule.Action('restoreSession') restoreSession!: () => void
@Prop({ default: 'bg-light-gray' }) readonly bgClass!: string
isOpenChainUpgradeBlockingDialog = false
async mounted() {
this.isOpenChainUpgradeBlockingDialog = !!IS_CHAIN_UPGRADING
await this.restoreSessionIfNecessary()
await this.restoreSession()
}
handleChainUpgradeBlockingDialogClose() {
Expand Down
1 change: 1 addition & 0 deletions constant/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const API_GET_ARWEAVE_V2_PUBLIC_KEY = `${LIKE_CO_API_ROOT}/arweave/v2/pub
export const API_POST_ARWEAVE_V2_ESTIMATE = `${LIKE_CO_API_ROOT}/arweave/v2/estimate`;
export const API_POST_ARWEAVE_V2_SIGN = `${LIKE_CO_API_ROOT}/arweave/v2/sign_payment_data`;
export const API_POST_ARWEAVE_V2_REGISTER = `${LIKE_CO_API_ROOT}/arweave/v2/register`;
export const API_POST_AUTHORIZE = `${LIKE_CO_API_ROOT}/wallet/authorize`
export const API_LIKER_NFT_MINT = `${LIKE_CO_API_ROOT}/likernft/mint`;
export const API_LIKER_NFT_PURCHASE = `${LIKE_CO_API_ROOT}/likernft/purchase`;
export const API_LIKER_NFT_HISTORY = `${LIKE_CO_API_ROOT}/likernft/history`;
Expand Down
65 changes: 46 additions & 19 deletions layouts/wallet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ import logTrackerEvent, { setLoggerUser } from '~/utils/logger'
const walletModule = namespace('wallet')
const bookApiModule = namespace('book-api')
@Component
export default class WalletLayout extends Vue {
@walletModule.Getter('getWalletAddress') walletAddress!: string
@walletModule.Action('disconnectWallet') disconnectWallet!: () => void
@walletModule.Action('openConnectWalletModal') openConnectWalletModal!: (params: { language: string, fullPath?: string }) => Promise<any>
@walletModule.Action('initWallet') initWallet!: (params: { method: any, accounts: any, offlineSigner?: any }) => Promise<any>
@walletModule.Action('restoreSessionIfNecessary') restoreSessionIfNecessary!: () => Promise<any>
@walletModule.Action('signMessageMemo') signMessageMemo!: (action: string, permissions?: string[]) => Promise<any>
@walletModule.Getter('getSigner') signer!: any
@bookApiModule.Action('restoreSession') restoreSession!: () => void
@bookApiModule.Action('authenticate') authenticate!: ({ inputWallet, signature }: { inputWallet?: string, signature?: any }) => Promise<any>
@bookApiModule.Action('clearSession') clearSession!: () => void
@walletModule.Action toggleAlert!: (
isShow: boolean,
Expand All @@ -37,31 +43,52 @@ export default class WalletLayout extends Vue {
}
async mounted() {
await this.restoreSessionIfNecessary()
await this.restoreSession()
if (!this.walletAddress) {
const connection = await this.openConnectWalletModal({
language: this.$i18n.locale.split('-')[0],
fullPath: this.$route.fullPath,
})
// Re-login
if (connection) {
const { method, accounts } = connection
logTrackerEvent(
this,
'user',
`connected_wallet_${method}`,
'connected_wallet',
1,
)
setLoggerUser(this, {
wallet: accounts[0].address,
method,
})
return this.initWallet(connection)
try {
if (connection) {
const { method, accounts } = connection
logTrackerEvent(
this,
'user',
`connected_wallet_${method}`,
'connected_wallet',
1,
)
setLoggerUser(this, {
wallet: accounts[0].address,
method,
})
await this.initWallet(connection)
if (!this.walletAddress || !this.signer) return
const signature = await this.signMessageMemo('authorize', [
'profile',
'read:nftbook',
'write:nftbook',
'read:nftcollection',
'write:nftcollection',
])
if (!signature) {
return
}
await this.authenticate({
inputWallet: this.walletAddress,
signature,
})
}
this.$router.go(-1)
} catch (error) {
this.disconnectWallet()
this.clearSession()
// eslint-disable-next-line no-console
console.error('handleConnectWalletButtonClick error', error)
}
return this.$router.go(-1)
}
return true
}
@Watch('walletAddress')
Expand Down
20 changes: 20 additions & 0 deletions pages/auth/redirect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ import { namespace } from 'vuex-class'
import logTrackerEvent, { setLoggerUser } from '~/utils/logger'
const walletModule = namespace('wallet')
const bookApiModule = namespace('book-api')
@Component
export default class RedirectPage extends Vue {
@walletModule.Action('initWallet') initWallet!: (params: { method: any; accounts: any; offlineSigner?: any }) => Promise<any>
@walletModule.Action('disconnectWallet') disconnectWallet!: () => void
@walletModule.Action('handleConnectorRedirect') handleConnectorRedirect!: (params: { method: string; params: any }) => Promise<any>
@walletModule.Action('signMessageMemo') signMessageMemo!: (action: string, permissions?: string[]) => Promise<any>
@walletModule.Getter('getSigner') signer!: any
@walletModule.Getter('getWalletAddress') currentAddress!: string
@bookApiModule.Action('authenticate') authenticate!: ({ inputWallet, signature }: { inputWallet?: string, signature?: any }) => Promise<any>
@bookApiModule.Action('clearSession') clearSession!: () => void
async mounted() {
const { error, method, code } = this.$route.query;
Expand All @@ -41,6 +49,16 @@ export default class RedirectPage extends Vue {
method: method as string,
})
await this.initWallet(connection)
if (!this.currentAddress || !this.signer) return
const signature = await this.signMessageMemo('authorize', [
'profile',
'read:nftbook',
'write:nftbook',
'read:nftcollection',
'write:nftcollection',
])
if (!signature) { return }
await this.authenticate({inputWallet:this.currentAddress, signature})
}
let postAuthRoute = '/';
if (window.sessionStorage) {
Expand All @@ -58,6 +76,8 @@ export default class RedirectPage extends Vue {
statusCode: 400,
message: (err as Error).toString(),
});
this.disconnectWallet()
this.clearSession()
}
} else {
if (window.sessionStorage) {
Expand Down
93 changes: 93 additions & 0 deletions store/book-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* eslint-disable import/no-extraneous-dependencies */
import { Module, VuexModule,Mutation, Action } from 'vuex-module-decorators'

import axios from 'axios'

import { saveAuthSession, clearAuthSession, loadAuthSession} from '~/utils/auth'
import { API_POST_AUTHORIZE } from '~/constant/api'

@Module({
name: 'book-api',
stateFactory: true,
namespaced: true,
})
export default class BookAPI extends VuexModule {
token = ''
sessionWallet = ''
isRestoringSession = false

@Mutation
setToken(inputToken: string) {
this.token = inputToken
}

@Mutation
setSessionWallet(inputWallet: string) {
this.sessionWallet = inputWallet
}

@Mutation
setIsRestoringSession(inputIsRestoringSession: boolean) {
this.isRestoringSession = inputIsRestoringSession
}

@Action
async authenticate({inputWallet = '', signature = {}}: {inputWallet?: string, signature?: any}) {
try {
const { data } = await axios.post(
API_POST_AUTHORIZE,
{
expiresIn: '7d',
...signature,
},
)
const token = (data as any)?.token
if (!token) {
throw new Error('INVALID_SIGNATURE')
}
this.context.commit('setToken', token)
this.context.commit('setSessionWallet', inputWallet)
saveAuthSession({ wallet: inputWallet, token})
} catch (error) {
// eslint-disable-next-line no-console
console.error(error)
throw new Error('AUTHENTICATION_FAILED')
}
}

@Action
clearSession () {
this.context.commit('setToken','')
this.context.commit('setSessionWallet', '')
clearAuthSession()
}

@Action
async restoreSession () {
try {
this.context.commit('setIsRestoringSession', true)
const session = loadAuthSession()
if (session) {
this.context.commit('setToken', session.token)
this.context.commit('setSessionWallet', session.wallet)
if (session.wallet) {
await this.context.dispatch('wallet/restoreSessionIfNecessary', null, { root: true })
}
}
} finally {
this.context.commit('setIsRestoringSession', false)
}
}

get getToken() {
return this.token
}

get getSessionWallet() {
return this.sessionWallet
}

get getIsRestoringSession() {
return this.isRestoringSession
}
}
Loading

0 comments on commit a29dc20

Please sign in to comment.