Skip to content

Commit

Permalink
Fix mobile nav and add uuid search
Browse files Browse the repository at this point in the history
  • Loading branch information
peterpolman committed Sep 24, 2024
1 parent 9e42196 commit 5d5a8b2
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 30 deletions.
12 changes: 9 additions & 3 deletions apps/api/src/app/controllers/qr-codes/list.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Account, Wallet, ERC721, ERC721Metadata, QRCodeEntry } from '@thxnetwork/api/models';
import { Account, ERC721, ERC721Metadata, QRCodeEntry, Wallet } from '@thxnetwork/api/models';
import AccountProxy from '@thxnetwork/api/proxies/AccountProxy';
import { Request, Response } from 'express';
import { query } from 'express-validator';
import AccountProxy from '@thxnetwork/api/proxies/AccountProxy';
import { isValidObjectId } from 'mongoose';
import { validate as isValidUUID } from 'uuid';

const validation = [
query('limit').optional().isInt({ gt: 0 }),
Expand All @@ -19,13 +20,18 @@ const controller = async (req: Request, res: Response) => {
if (req.query.erc721Id) query['erc721Id'] = req.query.erc721Id;
if (req.query.erc721MetadataId) query['erc721MetadataId'] = req.query.erc721MetadataId;

// Assuming a mongoId in the query since UI hints at it
// Extend query with sub filter if it is a mongoid
if (req.query.query && isValidObjectId(req.query.query)) {
const results = await Account.find({ _id: { $in: req.query.query } });
const subs = results.map((a) => a.id);
query['sub'] = { $in: subs };
}

// Extend query with uuid filter if it is a uuid
if (req.query.query && isValidUUID(req.query.query as string)) {
query['uuid'] = { $in: [req.query.query] };
}

const total = await QRCodeEntry.countDocuments(query);
const entries = await QRCodeEntry.find(query)
.limit(limit)
Expand Down
1 change: 0 additions & 1 deletion apps/studio/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script src="https://kit.fontawesome.com/06b7267748.js" crossorigin="anonymous"></script>
<script src="https://localhost:3000/v1/wallet/js/66f15a89610f34d5b859f5f3.js"></script>
</body>

</html>
8 changes: 4 additions & 4 deletions apps/studio/src/components/BaseCardProfile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue';
import Imglogo from '@thxnetwork/studio/assets/logo.jpg';
import { API_URL, WALLET_URL } from '@thxnetwork/studio/config/secrets';
import { mapStores } from 'pinia';
import { useAccountStore } from '@thxnetwork/studio/stores';
import { toast } from '@thxnetwork/studio/utils/toast';
import Imglogo from '@thxnetwork/studio/assets/logo.jpg';
import { decodeHTML } from '@thxnetwork/studio/utils/decode-html';
import { toast } from '@thxnetwork/studio/utils/toast';
import { mapStores } from 'pinia';
import { defineComponent, PropType } from 'vue';
export default defineComponent({
name: 'BaseCardProfile',
Expand Down
16 changes: 9 additions & 7 deletions apps/studio/src/views/Studio.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
<template>
<b-container>
<b-row>
<b-navbar>
<b-navbar toggleable="lg">
<b-navbar-brand to="/">
<b-img :src="imgLogo" width="50" />
</b-navbar-brand>
<b-navbar-toggle target="nav-collapse" />
<b-collapse id="nav-collapse" is-nav>
<b-collapse id="nav-collapse" is-nav class="order-1 order-md-0">
<b-navbar-nav>
<b-nav-item to="/collections">My Collections</b-nav-item>
<b-nav-item to="/qr-codes">QR Codes</b-nav-item>
</b-navbar-nav>
<b-navbar-nav class="ms-auto me-3">
<b-nav-item href="https://www.twinstory.io/faq" target="_blank">FAQ</b-nav-item>
<b-nav-item href="https://www.twinstory.io/support" target="_blank">Support</b-nav-item>
</b-navbar-nav>
</b-collapse>
<b-navbar-nav class="me-3">
<b-nav-item href="https://www.twinstory.io/faq" target="_blank">FAQ</b-nav-item>
<b-nav-item href="https://www.twinstory.io/support" target="_blank">Support</b-nav-item>
</b-navbar-nav>
<b-navbar-toggle target="nav-collapse" class="ms-auto me-2 border-0">
<BaseIcon icon="bars" />
</b-navbar-toggle>
<b-nav-item-dropdown end no-caret class="d-flex">
<template #button-content>
<b-avatar
Expand Down
100 changes: 89 additions & 11 deletions apps/wallet/src/components/BaseModalLogin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<BaseFormGroup label="Use your e-mail" label-class="text-opaque">
<b-form-input v-model="email" placeholder="[email protected]" />
</BaseFormGroup>
<b-button :disabled="!isEmailValid" variant="primary" type="submit" class="w-100">
<b-button :disabled="!isEmailValid || isLoadingOTP" variant="primary" type="submit" class="w-100">
<b-spinner v-if="isLoadingOTP" small />
<template v-else>
Send one-time password
Expand All @@ -30,7 +30,7 @@
<BaseFormGroup label="Check your e-mail for the OTP">
<b-form-input v-model="otp" placeholder="******" />
</BaseFormGroup>
<b-button :disabled="!isOTPValid" variant="primary" type="submit" class="w-100">
<b-button :disabled="!isOTPValid || isLoadingOTPVerify" variant="primary" type="submit" class="w-100">
<b-spinner v-if="isLoadingOTPVerify" small />
<template v-else>
Verify OTP
Expand All @@ -41,6 +41,34 @@

<BaseHrOrSeparator />

<b-button
v-if="!isWalletConnected"
:disabled="isLoadingConnectWallet"
variant="primary"
class="w-100"
@click="onClickSigninConnectWallet"
>
<b-spinner v-if="isLoadingConnectWallet" small />
<template v-else>
Connect Wallet
<BaseIcon icon="chevron-right" class="ms-2" />
</template>
</b-button>
<b-button
v-else
:disabled="isLoadingSigninWallet"
variant="success"
class="w-100"
@click="onClickSigninWithWallet"
>
<b-spinner v-if="isLoadingSigninWallet" small />
<template v-else>
Continue with <strong>{{ walletStore.account && shortenAddress(walletStore.account.address) }}</strong>
<BaseIcon icon="chevron-right" class="ms-2" />
</template>
</b-button>

<BaseHrOrSeparator />
<BaseFormGroup label="Use a trusted provider" label-class="text-opaque">
<div class="d-flex justify-content-between w-100 gap-2">
<b-button
Expand All @@ -59,10 +87,12 @@
</template>

<script lang="ts">
import { AccessTokenKind, AccountVariant } from '@thxnetwork/common/enums';
import { useAuthStore, useWalletStore } from '@thxnetwork/wallet/stores';
import { toast } from '@thxnetwork/wallet/utils/toast';
import { mapStores } from 'pinia';
import { defineComponent } from 'vue';
import { useAuthStore } from '@thxnetwork/wallet/stores';
import { AccessTokenKind, AccountVariant } from '@thxnetwork/common/enums';
import { shortenAddress } from '../utils/address';
export default defineComponent({
name: 'BaseModalLogin',
Expand Down Expand Up @@ -98,29 +128,72 @@ export default defineComponent({
title: 'Sign in with Github',
},
} as any,
isLoadingConnectWallet: false,
isLoadingSigninWallet: false,
isLoadingProvider: null as null | AccountVariant,
isLoadingOTP: false,
isLoadingOTPVerify: false,
isEmailSent: false,
shortenAddress,
};
},
computed: {
...mapStores(useAuthStore),
...mapStores(useAuthStore, useWalletStore),
isEmailValid() {
return this.email.length > 0;
},
isOTPValid() {
return this.otp.length === 6;
},
isWalletConnected() {
return this.walletStore.account && this.walletStore.account.isConnected;
},
},
methods: {
async onClickSigninConnectWallet() {
try {
this.isLoadingConnectWallet = true;
await this.walletStore.disconnect();
await this.walletStore.connect();
} catch (error: any) {
this.onError(error);
} finally {
this.isLoadingConnectWallet = false;
}
},
async onClickSigninWithWallet() {
try {
this.isLoadingSigninWallet = true;
const address = this.walletStore.account?.address as `0x${string}`;
const message = 'This signature will be used to proof ownership of a web3 account.';
const signature = await this.walletStore.signMessage(message);
await this.authStore.signinWithWallet(address, { message, signature });
} catch (error: any) {
const { code, details, message } = error;
// Indicates connect state in w3modal but not connected in wallet
if (message === 'connection.connector.getProvider is not a function') {
this.onError(new Error('No wallet connection, please disconnect and try again.'));
}
// Other exceptions are checked for a code to be present, indicating metamask errors
else {
this.onError(new Error(code ? details : message));
}
} finally {
this.isLoadingSigninWallet = false;
}
},
async onSubmitSigninWithOTP() {
this.isLoadingOTP = true;
try {
await this.authStore.signInWithOtp({ email: this.email });
this.isEmailSent = true;
} catch (error) {
this.error = (error as Error).message;
} catch (error: any) {
this.onError(error);
} finally {
this.isLoadingOTP = false;
}
Expand All @@ -130,8 +203,8 @@ export default defineComponent({
try {
await this.authStore.verifyOtp({ email: this.email, token: this.otp });
if (!this.authStore.session) throw new Error('An issue occured while verifying OTP. Please try again.');
} catch (error) {
this.error = (error as Error).message;
} catch (error: any) {
this.onError(error);
} finally {
this.isLoadingOTPVerify = false;
}
Expand All @@ -140,11 +213,16 @@ export default defineComponent({
this.isLoadingProvider = this.providers[variant].kind;
try {
await this.authStore.signInWithOAuth({ variant });
} catch (error) {
this.error = (error as Error).message;
} catch (error: any) {
this.onError(error);
this.isLoadingProvider = null;
}
},
onError(error: Error) {
toast(error.message, 'light', 3000, () => {
return;
});
},
},
});
</script>
2 changes: 1 addition & 1 deletion apps/wallet/src/components/BaseTabWalletVariant.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</p>
</b-button>
</b-form-group>
<b-button :disabled="isDisabled" variant="primary" class="w-100" @click="$emit('next')"> Continue </b-button>
<b-button :disabled="isDisabled" variant="primary" class="w-100 mt-3" @click="$emit('next')"> Continue </b-button>
</template>

<script lang="ts">
Expand Down
4 changes: 2 additions & 2 deletions apps/wallet/src/components/BaseTabWalletWalletConnect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<b-form-group v-if="address" label="Address">
<span class="text-opaque">{{ address }}</span>
</b-form-group>
<b-button v-if="!address" variant="primary" class="w-100" @click="onClickConnect"> Connect Wallet </b-button>
<b-button v-else variant="success" :disabled="isLoading" class="w-100" @click="onClickAdd">
<b-button v-if="!address" variant="primary" class="w-100 mt-3" @click="onClickConnect"> Connect Wallet </b-button>
<b-button v-else variant="success" :disabled="isLoading" class="w-100 mt-3" @click="onClickAdd">
<b-spinner v-if="isLoading" small />
<template v-else>
Add <strong>{{ walletStore.account?.address && shortenAddress(walletStore.account.address) }}</strong>
Expand Down
44 changes: 44 additions & 0 deletions apps/wallet/src/stores/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,50 @@ export const useAuthStore = defineStore('auth', {

popup.open(data.url);
},
async signinWithWallet(address: `0x${string}`, { message, signature }: { message: string; signature: string }) {
const { password } = await this.request('/login/pwd', { method: 'POST', body: { message, signature } });
const { error } = await this._signinWithPassword({ address, password });
if (error) throw error;
},
async _signinWithPassword({ address, password }: { address: string; password: string }) {
try {
// Try to get the user with the address and password
const { data, error } = await supabase.auth.signInWithPassword({
email: `${address}@thx.network`,
password,
});
// If we find a user for these credentials then login
if (data.user) return { data, error };
// If we are noticed that we login using the wrong credentials then we try to signup
if (error && error.message === 'Invalid login credentials') {
return await this._signupWithPassword({ address, password });
}
// If it was a different error we rethrow
if (error) throw error;

// In all other cases we throw an unknown error
throw new Error('Unknown error');
} catch (error) {
return { data: null, error };
}
},
async _signupWithPassword({ address, password }: { address: string; password: string }) {
try {
// If no user is found for this address and password then create a new user
const { data, error } = await supabase.auth.signUp({
email: `${address}@thx.network`,
password,
options: { data: { variant: AccountVariant.Metamask, address } },
});
if (error && error.message === 'User already registered') {
throw new Error('Unable to sign you in.');
}
if (error) throw error;
return { data, error };
} catch (error) {
return { data: null, error };
}
},
async logout() {
await supabase.auth.signOut();
},
Expand Down
2 changes: 1 addition & 1 deletion apps/wallet/src/utils/address.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function shortenAddress(address: string) {
export function shortenAddress(address: `0x${string}` | undefined) {
if (!address) return '';
return `${address.substring(0, 5)}...${address.substring(address.length - 5, address.length)}`;
}

0 comments on commit 5d5a8b2

Please sign in to comment.