Skip to content

Commit

Permalink
Fix token connect/disconnect flow
Browse files Browse the repository at this point in the history
  • Loading branch information
peterpolman committed Aug 1, 2024
1 parent 21ff7b9 commit 8734fd6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 40 deletions.
5 changes: 0 additions & 5 deletions apps/app/src/components/formgroup/BaseFormGroupConnected.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { mapStores } from 'pinia';
import { defineComponent } from 'vue';
import { OAuthRequiredScopes, platformIconMap } from '../../utils/social';
import { AccessTokenKind } from '../../types/enums/accessTokenKind';
import { UserIdentity } from '@supabase/supabase-js';
export default defineComponent({
name: 'BaseFormGroupUsername',
Expand All @@ -25,7 +24,6 @@ export default defineComponent({
isAlertShown: true,
platformIconMap,
AccessTokenKind,
identities: [] as UserIdentity[],
};
},
computed: {
Expand Down Expand Up @@ -56,8 +54,5 @@ export default defineComponent({
};
},
},
mounted() {
this.accountStore.getSupabaseIdentities();
},
});
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
</strong>
<div class="me-auto">
<strong>{{ provider.label }}</strong>
<div v-if="identity" class="small">
<span class="text-opaque">{{ identity.id }}</span>
<div v-if="token" class="small">
<span class="text-opaque">{{ token.userId }}</span>
<i v-b-tooltip class="fas fa-question-circle ms-1 text-opaque" :title="`${provider.label} User ID`" />
</div>
</div>
<b-spinner v-if="isLoading" small />
<template v-else>
<b-button
v-if="identity"
v-if="token"
:disabled="isDisabled"
variant="link"
class="text-decoration-none text-primary"
Expand All @@ -22,17 +22,18 @@
>
Disconnect
</b-button>
<b-button v-else variant="primary" size="sm" @click="onClickConnect(provider)"> Connect </b-button>
<b-button v-else :disabled="isDisabled" variant="primary" size="sm" @click="onClickConnect(provider)">
Connect
</b-button>
</template>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { kindAccountVariantMap, platformIconMap } from '../../utils/social';
import { platformIconMap } from '../../utils/social';
import { AccessTokenKind } from '../../types/enums/accessTokenKind';
import { useAccountStore } from '../../stores/Account';
import { mapStores } from 'pinia';
import { UserIdentity } from '@supabase/supabase-js';
export default defineComponent({
name: 'BaseFormGroupUsername',
Expand All @@ -57,12 +58,12 @@ export default defineComponent({
computed: {
...mapStores(useAccountStore),
isDisabled() {
if (!this.accountStore.account || !this.identity) return true;
return this.accountStore.account.variant === kindAccountVariantMap[this.identity.provider];
return this.isLoading;
},
identity() {
return this.accountStore.identities.find(
(identity: UserIdentity) => identity.provider === this.provider.kind,
token() {
if (!this.accountStore.account) return;
return this.accountStore.account.tokens.find(
(token: { kind: string }) => token.kind === this.provider.kind,
);
},
},
Expand Down
63 changes: 39 additions & 24 deletions apps/app/src/stores/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useWalletStore } from './Wallet';
import { AuthChangeEvent, createClient, Provider, Session, UserIdentity } from '@supabase/supabase-js';
import { popup } from '../utils/popup';
import poll from 'promise-poller';
import axios from 'axios';

// Feature only available on mobile devices
const isMobileDevice = !!window.matchMedia('(pointer:coarse)').matches;
Expand Down Expand Up @@ -176,35 +177,49 @@ export const useAccountStore = defineStore('account', {
}
},
async connect(kind: AccessTokenKind, scopes: TOAuthScope[]) {
const variant = kindAccountVariantMap[kind];
const provider = accountVariantProviderKindMap[variant] as Provider;
if (!provider) throw new Error('Requested provider not available.');

const config = this._getOAuthConfig(provider, {
scopes,
redirectTo: WIDGET_URL + '/auth/redirect',
});
const { data, error } = await supabase.auth.linkIdentity(config);
if (error) throw error;
if (config.options.skipBrowserRedirect) {
try {
const data = await this.api.request.get('/v1/oauth/authorize/' + kind, {
params: {
scopes: scopes.map((scope) => encodeURIComponent(scope)).join(','),
returnTo: WIDGET_URL + '/auth/redirect',
},
});
if (!data.url) throw new Error('Could not get authorize URL');
popup.open(data.url);

await this.waitForToken({ kind, scopes });
} catch (error) {
console.error(error);
throw error;
}
},
async disconnect(kind: AccessTokenKind) {
const identity = await this._getSupabaseIdentity(kind);
await supabase.auth.unlinkIdentity(identity);
await this.getSupabaseIdentities();
},
async getSupabaseIdentities() {
const { data, error } = await supabase.auth.getUserIdentities();
if (error) throw error;
this.identities = data.identities;
try {
await this.api.request.delete('/v1/account/disconnect/' + kind);
await this.waitForToken({ kind, scopes: [] });
} catch (error) {
console.error(error);
}
},
async _getSupabaseIdentity(kind: AccessTokenKind) {
await this.getSupabaseIdentities();
const identity = this.identities.find((i: UserIdentity) => i.provider === kind);
if (!identity) throw new Error('Identity not found');
return identity;
async waitForToken({ kind, scopes }: { kind: AccessTokenKind; scopes: TOAuthScope[] }) {
return new Promise((resolve, reject) => {
const poll = async () => {
await this.getAccount();

if (!this.account) {
setTimeout(poll, 1000);
return reject('account_not_found');
}

const isAuthorized = this.account.tokens.find(
(token) => token.kind === kind && scopes.every((scope) => token.scopes.includes(scope)),
);
if (!isAuthorized) setTimeout(poll, 1000);

return isAuthorized ? resolve('') : reject('token_invalid');
};
poll();
});
},
async signinWithWallet(address: string, { message, signature }: { message: string; signature: string }) {
const { password } = await this.api.request.post('/v1/login/pwd', { data: { message, signature } });
Expand Down

0 comments on commit 8734fd6

Please sign in to comment.