From fbd12b54e66f9267034cdde51628396cc95478cf Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 16 Jan 2025 16:20:06 +0200 Subject: [PATCH 01/30] Refactor(ProfileManager): use wallet key from window.env --- packages/playground/public/config.js | 1 + packages/playground/scripts/build-env.sh | 2 ++ packages/playground/src/global-components.d.ts | 1 + packages/playground/src/utils/credentials.ts | 3 +-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/playground/public/config.js b/packages/playground/public/config.js index 536d51f27f..d51cc24ed1 100644 --- a/packages/playground/public/config.js +++ b/packages/playground/public/config.js @@ -1,4 +1,5 @@ window.env = { + WALLET_KEY: "wallet.v1", NETWORK: "dev", GRAPHQL_STACKS: ["https://graphql.dev.grid.tf/graphql", "https://graphql.02.dev.grid.tf/graphql"], GRIDPROXY_STACKS: ["https://gridproxy.dev.grid.tf", "https://gridproxy.02.dev.grid.tf"], diff --git a/packages/playground/scripts/build-env.sh b/packages/playground/scripts/build-env.sh index 52244a51d4..9039faab02 100644 --- a/packages/playground/scripts/build-env.sh +++ b/packages/playground/scripts/build-env.sh @@ -12,6 +12,7 @@ STELLAR_ENV_Vars=( STELLAR_HORIZON_URL TFT_ASSET_ISSUER ) +WALLET_KEY="${WALLET_KEY:=wallet.v1}" case $MODE in "dev") @@ -102,6 +103,7 @@ parss_array(){ configs=" window.env = { + WALLET_KEY: '$WALLET_KEY', NETWORK: '$MODE', GRAPHQL_STACKS: "[$(parss_array "$GRAPHQL_URL")]", GRIDPROXY_STACKS: "[$(parss_array "$GRIDPROXY_URL")]", diff --git a/packages/playground/src/global-components.d.ts b/packages/playground/src/global-components.d.ts index 32afd556ce..206e8e4297 100644 --- a/packages/playground/src/global-components.d.ts +++ b/packages/playground/src/global-components.d.ts @@ -66,6 +66,7 @@ declare global { MANUAL_URL: string; SENTRY_DSN: string; ENABLE_TELEMETRY: boolean; + WALLET_KEY: string; }; } } diff --git a/packages/playground/src/utils/credentials.ts b/packages/playground/src/utils/credentials.ts index 1e9617a2f7..40c920a655 100644 --- a/packages/playground/src/utils/credentials.ts +++ b/packages/playground/src/utils/credentials.ts @@ -11,8 +11,7 @@ export interface Credentials { emailHash?: string; } -const version = 1; -const WALLET_KEY = "wallet.v" + version; +const WALLET_KEY = window.env.WALLET_KEY; export function getCredentials() { const getCredentials = localStorage.getItem(WALLET_KEY); let credentials: Credentials = {}; From 6668980ff01ff154f36f6be7b8ad8b6a60532066 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 16 Jan 2025 17:36:42 +0200 Subject: [PATCH 02/30] WIP: add password field --- .../profile_manager/Wallet_password.vue | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 packages/playground/src/components/profile_manager/Wallet_password.vue diff --git a/packages/playground/src/components/profile_manager/Wallet_password.vue b/packages/playground/src/components/profile_manager/Wallet_password.vue new file mode 100644 index 0000000000..dd57c08498 --- /dev/null +++ b/packages/playground/src/components/profile_manager/Wallet_password.vue @@ -0,0 +1,71 @@ + + + + + From e2427a3784478a5707243974f2f4bda04d9a80c7 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Mon, 20 Jan 2025 16:45:26 +0200 Subject: [PATCH 03/30] Refactor(ProfileManager): create the post login logic --- .../playground/src/utils/profile_manager.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/playground/src/utils/profile_manager.ts diff --git a/packages/playground/src/utils/profile_manager.ts b/packages/playground/src/utils/profile_manager.ts new file mode 100644 index 0000000000..f4810a428d --- /dev/null +++ b/packages/playground/src/utils/profile_manager.ts @@ -0,0 +1,23 @@ +import { GridClient } from "@threefold/grid_client"; + +import router from "@/router"; + +import { createCustomToast, ToastType } from "./custom_toast"; +import { readEmail, storeEmail } from "./grid"; +import SSHKeysManagement from "./ssh"; + +export async function handlePostLogin(grid: GridClient) { + throw new Error("Not implemented"); + const storedEmail = await readEmail(grid!); + if (!storedEmail) { + createCustomToast("Email is Missing! Please enter your Email.", ToastType.warning); + router.push({ path: "/tf-chain/your-profile" }); + } + + // Migrate the ssh-key + const sshKeysManagement = new SSHKeysManagement(); + if (!sshKeysManagement.migrated()) { + const newKeys = sshKeysManagement.migrate(); + await sshKeysManagement.update(newKeys); + } +} From 5cc3af935dcbabfa7c6e23e010bc2f718cc71ecd Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Mon, 20 Jan 2025 17:21:32 +0200 Subject: [PATCH 04/30] Refactor(ProfileManager): create login tab --- packages/playground/src/utils/profile_manager.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/playground/src/utils/profile_manager.ts b/packages/playground/src/utils/profile_manager.ts index f4810a428d..2aa69ae17e 100644 --- a/packages/playground/src/utils/profile_manager.ts +++ b/packages/playground/src/utils/profile_manager.ts @@ -3,11 +3,10 @@ import { GridClient } from "@threefold/grid_client"; import router from "@/router"; import { createCustomToast, ToastType } from "./custom_toast"; -import { readEmail, storeEmail } from "./grid"; +import { readEmail } from "./grid"; import SSHKeysManagement from "./ssh"; - +//TODO add docstring export async function handlePostLogin(grid: GridClient) { - throw new Error("Not implemented"); const storedEmail = await readEmail(grid!); if (!storedEmail) { createCustomToast("Email is Missing! Please enter your Email.", ToastType.warning); From fe7c49536edbe9ecbaf2bee2ab2736d164315f8e Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Mon, 20 Jan 2025 18:45:01 +0200 Subject: [PATCH 05/30] Refactor(ProfileManager): create login, enahnce pawwsord field --- .../profile_manager/Wallet_password.vue | 21 +++- .../profile_manager/wallet_login.vue | 110 ++++++++++++++++++ 2 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 packages/playground/src/components/profile_manager/wallet_login.vue diff --git a/packages/playground/src/components/profile_manager/Wallet_password.vue b/packages/playground/src/components/profile_manager/Wallet_password.vue index dd57c08498..a948a06b91 100644 --- a/packages/playground/src/components/profile_manager/Wallet_password.vue +++ b/packages/playground/src/components/profile_manager/Wallet_password.vue @@ -10,6 +10,7 @@ ]" #="{ props: validationProps }" ref="passwordInput" + @update:status="setStatus($event)" > import md5 from "md5"; +import { ref } from "vue"; +import { ValidatorStatus } from "@/hooks/form_validator"; import { getCredentials } from "@/utils/credentials"; -defineEmits(["update:modelValue"]); +const emit = defineEmits(["update:modelValue", "update:isValid"]); const props = defineProps({ modelValue: { required: true, @@ -48,20 +51,32 @@ const props = defineProps({ type: String as () => "Login" | "Create", default: "Create", }, + isValid: { + required: false, + type: Boolean, + default: false, + }, }); - +const passwordInput = ref(null); function validatePassword(value: string) { if (!localStorage.getItem(window.env.WALLET_KEY)) { return { message: "We couldn't find a matching wallet for this password. Please connect your wallet first.", }; } - if (getCredentials().passwordHash !== md5(props.modelValue)) { + if (getCredentials().passwordHash !== md5(value)) { return { message: "We couldn't find a matching wallet for this password. Please connect your wallet first.", }; } } +function setStatus(status: ValidatorStatus) { + if (status === ValidatorStatus.Valid) { + emit("update:isValid", true); + } else { + emit("update:isValid", false); + } +} + From 0959d9d22e9fed93ac67f3ddc8b15fb7a547a6c8 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Tue, 21 Jan 2025 16:11:24 +0200 Subject: [PATCH 06/30] Refactor(ProfileManager): - add form to the login, this will handle the stats tabs more effictive, - remove the emits that change the field status not needed --- .../profile_manager/Wallet_password.vue | 11 +--- .../profile_manager/wallet_login.vue | 63 +++++++++---------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Wallet_password.vue b/packages/playground/src/components/profile_manager/Wallet_password.vue index a948a06b91..580d63d642 100644 --- a/packages/playground/src/components/profile_manager/Wallet_password.vue +++ b/packages/playground/src/components/profile_manager/Wallet_password.vue @@ -6,11 +6,10 @@ :rules="[ validators.required('Password is required.'), validators.minLength('Password must be at least 6 characters.', 6), - props.mode === 'Login' ? validatePassword : null, + validatePassword, ]" #="{ props: validationProps }" ref="passwordInput" - @update:status="setStatus($event)" > + From e56c4f74a3a76555649e11f26d943f601d9da8cf Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 22 Jan 2025 14:38:53 +0200 Subject: [PATCH 08/30] Refactor(ProfileManager)/WIP: add a flag to prevent user to add email before mnemonics to avoid conflicts and losing entred data --- .../src/components/profile_manager/Connect_wallet.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index 6824fa6317..f57ae461b0 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -110,7 +110,13 @@ v-model="email" v-bind="props" :loading="loadEmail" - :disabled="creatingAccount || activatingAccount || activating || loadEmail" + :disabled=" + creatingAccount || + activatingAccount || + activating || + loadEmail || + mnemonicInput.status !== ValidatorStatus.Valid + " ref="emailRef" /> From 87dacc9dda14885edf490c86711b11e3fe20ffcb Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 22 Jan 2025 14:43:14 +0200 Subject: [PATCH 09/30] Refactor(ProfileManager)/WIP: Enhance mnemonic validation flow - getting a grid checking a twin should be in validate mnemonic, moved and marked as asyncRule - load email only getting email and set it - also the reload validation now only if there is an issue with getting the grid, in validate mnemonic --- .../profile_manager/Connect_wallet.vue | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index f57ae461b0..8812b64506 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -27,17 +27,15 @@
From e02a3bf342d99a275463f71c217c380c5ad822bb Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 22 Jan 2025 18:13:26 +0200 Subject: [PATCH 12/30] Refactor(ProfileManager:LoginTab): - passing the mnemonic or hex to profile - disable password on logning - add emit to update loading --- .../components/profile_manager/wallet_login.vue | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/playground/src/components/profile_manager/wallet_login.vue b/packages/playground/src/components/profile_manager/wallet_login.vue index ae765a52d8..29b97db7fb 100644 --- a/packages/playground/src/components/profile_manager/wallet_login.vue +++ b/packages/playground/src/components/profile_manager/wallet_login.vue @@ -7,7 +7,7 @@ You will need to provide the password used while connecting your wallet.

- + {{ loginError }} @@ -44,14 +44,13 @@ import { normalizeError } from "@/utils/helpers"; import { handlePostLogin } from "@/utils/profile_manager"; const profileManager = useProfileManager(); const password = ref(""); -const emit = defineEmits(["closeDialog"]); +const emit = defineEmits(["closeDialog", "update:loading"]); const isValidForm = ref(false); -const loading = ref(false); +const loading = ref(false); const loginError = ref(""); onMounted(async () => { if (getCredentials()) { - console.log("Stored credentials found"); const credentials: Credentials = getCredentials(); const sessionPassword = sessionStorage.getItem("password"); @@ -67,6 +66,8 @@ onMounted(async () => { async function login() { loading.value = true; + emit("update:loading", true); + await new Promise(resolve => setTimeout(resolve, 1000)); loginError.value = ""; try { const credentials: Credentials = getCredentials(); @@ -79,10 +80,8 @@ async function login() { : KeypairType.sr25519; const grid = await getGrid({ mnemonic: mnemonic, keypairType: keypairType as KeypairType }); - await handlePostLogin(grid!); - - profileManager.set(await loadProfile(grid!)); - sessionStorage.setItem("password", password.value); + await handlePostLogin(grid!, password.value); + profileManager.set({ ...(await loadProfile(grid!)), mnemonic }); emit("closeDialog"); } } else { @@ -94,6 +93,7 @@ async function login() { loginError.value = normalizeError(error, message); } finally { loading.value = false; + emit("update:loading", false); } } From 4e5c6b262feb83f86e03a94ab19f3d7c6e9f95d4 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 22 Jan 2025 18:14:30 +0200 Subject: [PATCH 13/30] Refactor(ProfileManager:WalletPassword): add disabled prop --- .../src/components/profile_manager/Wallet_password.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Wallet_password.vue b/packages/playground/src/components/profile_manager/Wallet_password.vue index 580d63d642..a76b9c2da3 100644 --- a/packages/playground/src/components/profile_manager/Wallet_password.vue +++ b/packages/playground/src/components/profile_manager/Wallet_password.vue @@ -25,6 +25,7 @@ @update:modelValue="$emit('update:modelValue', $event)" v-bind="{ ...passwordInputProps, ...validationProps }" autocomplete="off" + :disabled="props.disabled" />
@@ -39,7 +40,7 @@ import { ref } from "vue"; import { ValidatorStatus } from "@/hooks/form_validator"; import { getCredentials } from "@/utils/credentials"; -const emit = defineEmits(["update:modelValue", "update:isValid"]); + const props = defineProps({ modelValue: { required: true, @@ -50,10 +51,9 @@ const props = defineProps({ type: String as () => "Login" | "Create", default: "Create", }, - isValid: { + disabled: { required: false, type: Boolean, - default: false, }, }); const passwordInput = ref(null); From fa7a8b8b7f40f70952795d82775a10c4ae8592ce Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 22 Jan 2025 18:19:06 +0200 Subject: [PATCH 14/30] Refactor(ProfileManager:ConnectWallet)WIP: support create and activate account flow --- .../profile_manager/Connect_wallet.vue | 115 +++++++++++++----- 1 file changed, 85 insertions(+), 30 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index 249aaf1c1b..70fc444262 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -1,6 +1,5 @@
@@ -76,21 +76,21 @@ -
+
- create account
- - {{ createAccountError || activatingAccountError }} + + {{ createOrActivateError }} @@ -108,19 +108,13 @@ v-model="email" v-bind="props" :loading="loadEmail" - :disabled=" - creatingAccount || - activatingAccount || - activating || - loadEmail || - mnemonicInput.status !== ValidatorStatus.Valid - " + :disabled="creatingAccount || connecting || loadEmail || mnemonicInput?.status !== ValidatorStatus.Valid" ref="emailRef" /> - + @@ -151,14 +145,15 @@ class="ml-2" type="submit" color="secondary" - :loading="activating" - :disabled="!isValidForm || creatingAccount || activatingAccount" + :loading="connecting" + :disabled="!isValidForm || creatingAccount" > Connect
+ From 1a87fe41c9a21855af12a7689199b444c0b44775 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 23 Jan 2025 19:23:03 +0200 Subject: [PATCH 15/30] Refactor(ProfileManager:Walletlogin): - enhance getting credentials logic --- .../components/profile_manager/wallet_login.vue | 14 ++++---------- packages/playground/src/utils/credentials.ts | 5 +++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/playground/src/components/profile_manager/wallet_login.vue b/packages/playground/src/components/profile_manager/wallet_login.vue index 29b97db7fb..0d25497995 100644 --- a/packages/playground/src/components/profile_manager/wallet_login.vue +++ b/packages/playground/src/components/profile_manager/wallet_login.vue @@ -38,7 +38,8 @@ import { onMounted, ref } from "vue"; import WalletPassword from "@/components/profile_manager/Wallet_password.vue"; import { useProfileManager } from "@/stores/profile_manager"; -import { Credentials, getCredentials } from "@/utils/credentials"; +import { type Credentials, isStoredCredentials } from "@/utils/credentials"; +import { getCredentials } from "@/utils/credentials"; import { getGrid, loadProfile } from "@/utils/grid"; import { normalizeError } from "@/utils/helpers"; import { handlePostLogin } from "@/utils/profile_manager"; @@ -50,24 +51,17 @@ const loading = ref(false); const loginError = ref(""); onMounted(async () => { - if (getCredentials()) { - const credentials: Credentials = getCredentials(); + if (isStoredCredentials()) { const sessionPassword = sessionStorage.getItem("password"); - if (!sessionPassword) return; - password.value = sessionPassword; - - if (credentials.passwordHash) { - return await login(); - } + login(); } }); async function login() { loading.value = true; emit("update:loading", true); - await new Promise(resolve => setTimeout(resolve, 1000)); loginError.value = ""; try { const credentials: Credentials = getCredentials(); diff --git a/packages/playground/src/utils/credentials.ts b/packages/playground/src/utils/credentials.ts index 40c920a655..ab671c4f42 100644 --- a/packages/playground/src/utils/credentials.ts +++ b/packages/playground/src/utils/credentials.ts @@ -12,6 +12,11 @@ export interface Credentials { } const WALLET_KEY = window.env.WALLET_KEY; + +export function isStoredCredentials() { + const credentials = getCredentials(); + return credentials?.passwordHash && credentials?.mnemonicHash && credentials?.keypairTypeHash; +} export function getCredentials() { const getCredentials = localStorage.getItem(WALLET_KEY); let credentials: Credentials = {}; From dfabd7d8244871857991af3c42252b8b6d20c6ce Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 23 Jan 2025 19:25:04 +0200 Subject: [PATCH 16/30] Refactor(ProfileManager:Walletlogin): - enhance getting credentials logic --- .../playground/src/components/profile_manager/wallet_login.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/playground/src/components/profile_manager/wallet_login.vue b/packages/playground/src/components/profile_manager/wallet_login.vue index 0d25497995..c29de4e336 100644 --- a/packages/playground/src/components/profile_manager/wallet_login.vue +++ b/packages/playground/src/components/profile_manager/wallet_login.vue @@ -50,7 +50,7 @@ const isValidForm = ref(false); const loading = ref(false); const loginError = ref(""); -onMounted(async () => { +onMounted(() => { if (isStoredCredentials()) { const sessionPassword = sessionStorage.getItem("password"); if (!sessionPassword) return; From 3332700eef49ea1f2a90c25b8bd3443cf805dc0f Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 23 Jan 2025 19:26:39 +0200 Subject: [PATCH 17/30] Refactor(ProfileManager:ConnectWallet)WIP: - disable auto complete - set the session password in handlePostLogin --- .../src/components/profile_manager/Connect_wallet.vue | 1 + packages/playground/src/utils/profile_manager.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index 70fc444262..eacb3c4fed 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -110,6 +110,7 @@ :loading="loadEmail" :disabled="creatingAccount || connecting || loadEmail || mnemonicInput?.status !== ValidatorStatus.Valid" ref="emailRef" + autocomplete="off" /> diff --git a/packages/playground/src/utils/profile_manager.ts b/packages/playground/src/utils/profile_manager.ts index 2aa69ae17e..03ac9db856 100644 --- a/packages/playground/src/utils/profile_manager.ts +++ b/packages/playground/src/utils/profile_manager.ts @@ -6,7 +6,8 @@ import { createCustomToast, ToastType } from "./custom_toast"; import { readEmail } from "./grid"; import SSHKeysManagement from "./ssh"; //TODO add docstring -export async function handlePostLogin(grid: GridClient) { +export async function handlePostLogin(grid: GridClient, password: string) { + sessionStorage.setItem("password", password); const storedEmail = await readEmail(grid!); if (!storedEmail) { createCustomToast("Email is Missing! Please enter your Email.", ToastType.warning); From 36d2815d4c2d542fe0a7626ea4539221f7e212dc Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 23 Jan 2025 19:50:51 +0200 Subject: [PATCH 18/30] Refactor(ProfileManager): apply the new components and cleanup the code --- .../src/weblets/profile_manager.vue | 637 +----------------- 1 file changed, 22 insertions(+), 615 deletions(-) diff --git a/packages/playground/src/weblets/profile_manager.vue b/packages/playground/src/weblets/profile_manager.vue index 33ae90af70..9368cdfd49 100644 --- a/packages/playground/src/weblets/profile_manager.vue +++ b/packages/playground/src/weblets/profile_manager.vue @@ -84,273 +84,14 @@ v-if="!profileManager.profile" :tabs="getTabs()" v-model="activeTab" - :disabled="creatingAccount || activatingAccount || activating" + :disabled="loading" ref="tabsRef" - @tab:change=" - () => { - clearError(); - clearFields(); - } - " destroy > - -
- - -

- To connect your wallet, you will need to enter your Mnemonic or Hex Seed which will be encrypted using - the password. Mnemonic or Hex Seed will never be shared outside of this device. -

-
- - -

- Please note that generation or activation of ed25519 Keys isn't supported, you can only import pre - existing ones. -

-
- - - - - - - - - - - - - - - - - - - - - {{ createAccountError || activatingAccountError }} - - - -

- You will need to provide the password used while connecting your wallet. -

-
- - - - - - - - - - - - - - - - - - - - - - - {{ loginError }} - -
- -
- Close - - {{ activeTab === 0 ? "Login" : "Connect" }} - -
-
-
+ + From f68826e8bd8e8824455321c678b93a40690cba48 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 23 Jan 2025 21:02:41 +0200 Subject: [PATCH 19/30] Feature(ProfileManager): add skeleton loader --- .../profile_manager/SkeletonLoader.vue | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 packages/playground/src/components/profile_manager/SkeletonLoader.vue diff --git a/packages/playground/src/components/profile_manager/SkeletonLoader.vue b/packages/playground/src/components/profile_manager/SkeletonLoader.vue new file mode 100644 index 0000000000..05303f029f --- /dev/null +++ b/packages/playground/src/components/profile_manager/SkeletonLoader.vue @@ -0,0 +1,27 @@ + + + + From 2acadf21f3782a9613200035aa2f28aa5111ed14 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Thu, 23 Jan 2025 21:59:50 +0200 Subject: [PATCH 20/30] Feature(ProfileManager): add suspense to fallback to the skeletonLoader if one of the commponents is still loading --- .../profile_manager/SkeletonLoader.vue | 32 ++-- .../src/weblets/profile_manager.vue | 167 ++++++++++-------- 2 files changed, 106 insertions(+), 93 deletions(-) diff --git a/packages/playground/src/components/profile_manager/SkeletonLoader.vue b/packages/playground/src/components/profile_manager/SkeletonLoader.vue index 05303f029f..c141c519af 100644 --- a/packages/playground/src/components/profile_manager/SkeletonLoader.vue +++ b/packages/playground/src/components/profile_manager/SkeletonLoader.vue @@ -1,19 +1,21 @@ - From fc93a45bcbe5384959ccd740b01d49e59bf96d56 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 29 Jan 2025 11:54:09 +0200 Subject: [PATCH 23/30] FIX(ProfileManager): remove session storage --- .../playground/src/utils/profile_manager.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/playground/src/utils/profile_manager.ts b/packages/playground/src/utils/profile_manager.ts index 03ac9db856..77c7d246f6 100644 --- a/packages/playground/src/utils/profile_manager.ts +++ b/packages/playground/src/utils/profile_manager.ts @@ -1,13 +1,23 @@ -import { GridClient } from "@threefold/grid_client"; +import type { GridClient } from "@threefold/grid_client"; import router from "@/router"; import { createCustomToast, ToastType } from "./custom_toast"; import { readEmail } from "./grid"; import SSHKeysManagement from "./ssh"; -//TODO add docstring -export async function handlePostLogin(grid: GridClient, password: string) { - sessionStorage.setItem("password", password); + +/** + * Handles the actions to be performed after a successful login "including create account and activate account". + * + * - Retrieves the stored email address and checks its presence. + * If the email is missing, triggers a warning toast and navigates to the profile creation page. + * - Ensures that SSH keys are migrated if not already done. If not migrated, it performs the migration and updates the SSH keys. + * + * @param grid - The instance of the GridClient used to interact with the grid. + * + * @throws {Error} If any operation (like reading the email or updating SSH keys) fails. + */ +export async function handlePostLogin(grid: GridClient) { const storedEmail = await readEmail(grid!); if (!storedEmail) { createCustomToast("Email is Missing! Please enter your Email.", ToastType.warning); From 91b9e146376da7736f1becb3d337c4a7912d1520 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 29 Jan 2025 11:56:11 +0200 Subject: [PATCH 24/30] FIX(ProfileManager): remove session storage --- .../src/components/profile_manager/Connect_wallet.vue | 2 +- .../playground/src/components/profile_manager/wallet_login.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index 781beb8ead..eede173320 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -319,7 +319,7 @@ async function storeAndLogin() { const grid = await getGrid({ mnemonic: mnemonic.value, keypairType: keypairType.value }); storeEmail(grid!, email.value); setCredentials(md5(password.value), mnemonicHash, keypairTypeHash, md5(email.value)); - await handlePostLogin(grid!, password.value); + await handlePostLogin(grid!); const profile = await loadProfile(grid!); if (email.value && profile.email !== email.value) { profile.email = email.value; diff --git a/packages/playground/src/components/profile_manager/wallet_login.vue b/packages/playground/src/components/profile_manager/wallet_login.vue index c29de4e336..293125ce55 100644 --- a/packages/playground/src/components/profile_manager/wallet_login.vue +++ b/packages/playground/src/components/profile_manager/wallet_login.vue @@ -74,7 +74,7 @@ async function login() { : KeypairType.sr25519; const grid = await getGrid({ mnemonic: mnemonic, keypairType: keypairType as KeypairType }); - await handlePostLogin(grid!, password.value); + await handlePostLogin(grid!); profileManager.set({ ...(await loadProfile(grid!)), mnemonic }); emit("closeDialog"); } From bb5f2eb34a5c65ade1d0edf70de021acc6acad07 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 29 Jan 2025 12:53:39 +0200 Subject: [PATCH 25/30] chore(ProfileManager): remove logs and enhance errors pass the email to postlogin method: to not check if the email is stored; as we already have a new one to store --- .../components/profile_manager/Connect_wallet.vue | 6 +++--- packages/playground/src/utils/profile_manager.ts | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index eede173320..2a87cc9bda 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -228,7 +228,6 @@ const handleAcceptTerms = () => { const emit = defineEmits(["closeDialog", "update:loading"]); watch([connecting, creatingAccount], () => { - console.log(connecting.value || creatingAccount.value); emit("update:loading", connecting.value || creatingAccount.value); }); async function getEmail(grid: GridClient) { @@ -260,7 +259,7 @@ const validateMnemonicInput = async (input: string) => { if (e instanceof TwinNotExistError) { isNonActiveMnemonic.value = true; } else { - console.log("error", e); + console.error("ValidateMnemonicInput error", e); enableReload.value = true; return { message: normalizeError(e, "Something went wrong. please try again.") }; } @@ -319,7 +318,7 @@ async function storeAndLogin() { const grid = await getGrid({ mnemonic: mnemonic.value, keypairType: keypairType.value }); storeEmail(grid!, email.value); setCredentials(md5(password.value), mnemonicHash, keypairTypeHash, md5(email.value)); - await handlePostLogin(grid!); + await handlePostLogin(grid!, email.value); const profile = await loadProfile(grid!); if (email.value && profile.email !== email.value) { profile.email = email.value; @@ -329,6 +328,7 @@ async function storeAndLogin() { if (e instanceof TwinNotExistError) { openAcceptTerms.value = true; isNonActiveMnemonic.value = true; + return; } console.error("error", e); enableReload.value = false; diff --git a/packages/playground/src/utils/profile_manager.ts b/packages/playground/src/utils/profile_manager.ts index 77c7d246f6..6a23884625 100644 --- a/packages/playground/src/utils/profile_manager.ts +++ b/packages/playground/src/utils/profile_manager.ts @@ -17,11 +17,13 @@ import SSHKeysManagement from "./ssh"; * * @throws {Error} If any operation (like reading the email or updating SSH keys) fails. */ -export async function handlePostLogin(grid: GridClient) { - const storedEmail = await readEmail(grid!); - if (!storedEmail) { - createCustomToast("Email is Missing! Please enter your Email.", ToastType.warning); - router.push({ path: "/tf-chain/your-profile" }); +export async function handlePostLogin(grid: GridClient, email?: string) { + if (!email) { + const storedEmail = await readEmail(grid!); + if (!storedEmail) { + createCustomToast("Email is Missing! Please enter your Email.", ToastType.warning); + router.push({ path: "/tf-chain/your-profile" }); + } } // Migrate the ssh-key From ce9eb7e9d718ad4995726700edeaafe42c618f1e Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 29 Jan 2025 13:05:46 +0200 Subject: [PATCH 26/30] FIX(ProfileManager): restore session storage --- .../components/profile_manager/Connect_wallet.vue | 2 +- .../src/components/profile_manager/wallet_login.vue | 2 +- packages/playground/src/utils/profile_manager.ts | 13 +++++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index 2a87cc9bda..c9ec9fc89f 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -318,7 +318,7 @@ async function storeAndLogin() { const grid = await getGrid({ mnemonic: mnemonic.value, keypairType: keypairType.value }); storeEmail(grid!, email.value); setCredentials(md5(password.value), mnemonicHash, keypairTypeHash, md5(email.value)); - await handlePostLogin(grid!, email.value); + await handlePostLogin(grid!, password.value, email.value); const profile = await loadProfile(grid!); if (email.value && profile.email !== email.value) { profile.email = email.value; diff --git a/packages/playground/src/components/profile_manager/wallet_login.vue b/packages/playground/src/components/profile_manager/wallet_login.vue index 293125ce55..c29de4e336 100644 --- a/packages/playground/src/components/profile_manager/wallet_login.vue +++ b/packages/playground/src/components/profile_manager/wallet_login.vue @@ -74,7 +74,7 @@ async function login() { : KeypairType.sr25519; const grid = await getGrid({ mnemonic: mnemonic, keypairType: keypairType as KeypairType }); - await handlePostLogin(grid!); + await handlePostLogin(grid!, password.value); profileManager.set({ ...(await loadProfile(grid!)), mnemonic }); emit("closeDialog"); } diff --git a/packages/playground/src/utils/profile_manager.ts b/packages/playground/src/utils/profile_manager.ts index 6a23884625..98e487ccbe 100644 --- a/packages/playground/src/utils/profile_manager.ts +++ b/packages/playground/src/utils/profile_manager.ts @@ -7,17 +7,22 @@ import { readEmail } from "./grid"; import SSHKeysManagement from "./ssh"; /** - * Handles the actions to be performed after a successful login "including create account and activate account". + * Handles the actions to be performed after a successful login. * - * - Retrieves the stored email address and checks its presence. - * If the email is missing, triggers a warning toast and navigates to the profile creation page. + * - Saves the password in session storage for future use. + * - Retrieves and checks the provided or stored email address. + * If neither is available, triggers a warning toast and navigates to the profile creation page. * - Ensures that SSH keys are migrated if not already done. If not migrated, it performs the migration and updates the SSH keys. * * @param grid - The instance of the GridClient used to interact with the grid. + * @param password - The user's password to be stored in session storage. + * @param email - Optional email address provided during login. If not provided, it will attempt to retrieve the stored email. * * @throws {Error} If any operation (like reading the email or updating SSH keys) fails. */ -export async function handlePostLogin(grid: GridClient, email?: string) { +export async function handlePostLogin(grid: GridClient, password: string, email?: string) { + sessionStorage.setItem("password", password); + if (!email) { const storedEmail = await readEmail(grid!); if (!storedEmail) { From d80959840582e851d82c25a216ae958cd9253e4e Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 29 Jan 2025 14:39:22 +0200 Subject: [PATCH 27/30] Chore(ProfileManager): fix activate flow and add clear error function --- .../profile_manager/Connect_wallet.vue | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/Connect_wallet.vue index c9ec9fc89f..d34e6e7a37 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/Connect_wallet.vue @@ -76,7 +76,7 @@ :items="[...keyType]" item-title="name" v-model="keypairType" - @onchange="mnemonicInput.validate()" + @update:modelValue="mnemonic !== '' ? reloadValidation() : null" />
@@ -241,11 +241,17 @@ async function getEmail(grid: GridClient) { } } +const clearErrors = () => { + createOrActivateError.value = ""; + storeAndLoginError.value = ""; +}; + function reloadValidation() { enableReload.value = false; mnemonicInput.value.validate(); } const validateMnemonicInput = async (input: string) => { + clearErrors(); enableReload.value = false; isNonActiveMnemonic.value = false; if ( @@ -278,6 +284,7 @@ function validateConfirmPassword(value: string) { } async function createNewAccount() { + clearErrors(); mnemonicInput.value.reset(); creatingAccount.value = true; try { @@ -291,6 +298,7 @@ async function createNewAccount() { } async function activateAccount() { + clearErrors(); creatingAccount.value = true; connecting.value = true; try { @@ -310,6 +318,7 @@ async function activateAccount() { } async function storeAndLogin() { + clearErrors(); connecting.value = true; const cryptr = new Cryptr(password.value, { pbkdf2Iterations: 10, saltLength: 10 }); const mnemonicHash = cryptr.encrypt(mnemonic.value); @@ -326,8 +335,13 @@ async function storeAndLogin() { profileManager.set({ ...profile, mnemonic: mnemonic.value }); } catch (e) { if (e instanceof TwinNotExistError) { - openAcceptTerms.value = true; isNonActiveMnemonic.value = true; + if (keypairType.value === KeypairType.ed25519) { + createOrActivateError.value = "Activation ed25519 Keys isn't supported, you can only import pre-existing ones."; + return; + } + + openAcceptTerms.value = true; return; } console.error("error", e); From 47262c90646b3e9467b6795e2cbb4b45c7e30ea4 Mon Sep 17 00:00:00 2001 From: Omar Kassem Date: Wed, 29 Jan 2025 14:47:39 +0200 Subject: [PATCH 28/30] Chore(ProfileManager): rename files and fix imports --- .../profile_manager/{Connect_wallet.vue => ConnectWallet.vue} | 2 +- .../profile_manager/{wallet_login.vue => LoginWallet.vue} | 2 +- .../{Wallet_password.vue => WalletPassword.vue} | 0 packages/playground/src/weblets/profile_manager.vue | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) rename packages/playground/src/components/profile_manager/{Connect_wallet.vue => ConnectWallet.vue} (99%) rename packages/playground/src/components/profile_manager/{wallet_login.vue => LoginWallet.vue} (97%) rename packages/playground/src/components/profile_manager/{Wallet_password.vue => WalletPassword.vue} (100%) diff --git a/packages/playground/src/components/profile_manager/Connect_wallet.vue b/packages/playground/src/components/profile_manager/ConnectWallet.vue similarity index 99% rename from packages/playground/src/components/profile_manager/Connect_wallet.vue rename to packages/playground/src/components/profile_manager/ConnectWallet.vue index d34e6e7a37..45f40f10e8 100644 --- a/packages/playground/src/components/profile_manager/Connect_wallet.vue +++ b/packages/playground/src/components/profile_manager/ConnectWallet.vue @@ -356,7 +356,7 @@ async function storeAndLogin() { import { handlePostLogin } from "@/utils/profile_manager"; import AcceptTermsDialog from "./AcceptTermsDialog.vue"; -import WalletPassword from "./Wallet_password.vue"; +import WalletPassword from "./WalletPassword.vue"; export default { name: "ConnectWallet", diff --git a/packages/playground/src/components/profile_manager/wallet_login.vue b/packages/playground/src/components/profile_manager/LoginWallet.vue similarity index 97% rename from packages/playground/src/components/profile_manager/wallet_login.vue rename to packages/playground/src/components/profile_manager/LoginWallet.vue index c29de4e336..084ed7effa 100644 --- a/packages/playground/src/components/profile_manager/wallet_login.vue +++ b/packages/playground/src/components/profile_manager/LoginWallet.vue @@ -36,7 +36,7 @@ import Cryptr from "cryptr"; import md5 from "md5"; import { onMounted, ref } from "vue"; -import WalletPassword from "@/components/profile_manager/Wallet_password.vue"; +import WalletPassword from "@/components/profile_manager/WalletPassword.vue"; import { useProfileManager } from "@/stores/profile_manager"; import { type Credentials, isStoredCredentials } from "@/utils/credentials"; import { getCredentials } from "@/utils/credentials"; diff --git a/packages/playground/src/components/profile_manager/Wallet_password.vue b/packages/playground/src/components/profile_manager/WalletPassword.vue similarity index 100% rename from packages/playground/src/components/profile_manager/Wallet_password.vue rename to packages/playground/src/components/profile_manager/WalletPassword.vue diff --git a/packages/playground/src/weblets/profile_manager.vue b/packages/playground/src/weblets/profile_manager.vue index 777c98a194..7f8fbf5cd6 100644 --- a/packages/playground/src/weblets/profile_manager.vue +++ b/packages/playground/src/weblets/profile_manager.vue @@ -319,12 +319,12 @@ profileManagerController.set({ loadBalance: __loadBalance });