Skip to content

Commit

Permalink
fix: encrypt issue
Browse files Browse the repository at this point in the history
  • Loading branch information
AricRedemption committed Sep 4, 2024
1 parent 8ad53f7 commit 28c7f1f
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 211 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
"tailwind-merge": "^2.2.2",
"tailwindcss": "^3.2.7",
"typescript": "^5.0.4",
"vite": "^4.4.9",
"vite": "5.4.1",
"vite-plugin-node-polyfills": "^0.14.1",
"vite-plugin-svg": "^0.7.0",
"vite-plugin-svg-icons": "^2.0.1",
Expand Down
2 changes: 1 addition & 1 deletion src/assets/icons-v3/fail.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/components/AssetLogo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ withDefaults(
<div
class="aspect-square flex items-center justify-center rounded-full text-white bg-blue-primary shrink-0 shadow"
>
{{ symbol?.[0].toLocaleUpperCase() }}
{{ symbol?.[0]?.toLocaleUpperCase() }}
</div>
</template>
<template #error>
<div
class="aspect-square flex items-center justify-center rounded-full text-white bg-blue-primary shrink-0 shadow"
>
{{ symbol?.[0].toLocaleUpperCase() }}
{{ symbol?.[0]?.toLocaleUpperCase() }}
</div>
</template>
</UseImage>
Expand Down
23 changes: 9 additions & 14 deletions src/components/PasswordInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,27 @@ const levelColors = computed(() => {
<template>
<form @submit.prevent>
<h4 class="mb-2 text-sm">{{ title || 'Password' }}</h4>
<div class="relative">
<input
name="password"
autocomplete="on"
:type="passwordInputType"
@input="(event) => emit('update:password', (event.target as HTMLInputElement).value)"
:class="[
<div class="relative h-15">
<input name="password" autocomplete="on" :type="passwordInputType"
@input="(event: Event) => emit('update:password', (event.target as HTMLInputElement).value)" :class="[
'block w-full rounded-md border border-gray-soft outline-blue-primary p-4 pr-12',
{ 'border-red-500': !!error },
]"
/>
<div class="absolute right-0 top-0 flex h-full items-center pr-4">
]" />
<div class="absolute right-0 top-0 h-full flex items-center pr-4">
<button type="button" @click="isCovered = !isCovered">
<EyeIcon v-if="isCovered" class="h-5 w-5 text-gray-400 transition hover:text-blue-500" />
<EyeSlashIcon v-else class="h-5 w-5 text-gray-400 transition hover:text-blue-500" />
<EyeIcon v-if="isCovered" class="size-5 text-gray-400 transition hover:text-blue-500" />
<EyeSlashIcon v-else class="size-5 text-gray-400 transition hover:text-blue-500" />
</button>
</div>
<div class="absolute -bottom-8 left-0 flex items-center justify-between w-full text-sm" v-if="validate">
<div class="absolute py-1 left-0 flex items-center justify-between w-full text-sm" v-if="validate">
<div class="flex items-center gap-1">
<div :class="['w-8 h-1.5 rounded-md', bgColor]" v-for="(bgColor, index) in levelColors" :key="index"></div>
</div>
<div v-if="password">
<span :class="securityColor">{{ securityLevel }}</span>
</div>
</div>
<p v-if="error" class="absolute -bottom-8 left-0 text-sm text-red-500">{{ error }}</p>
<p v-if="error" class="absolute py-1 left-0 text-sm text-red-500">{{ error }}</p>
</div>
</form>
</template>
5 changes: 1 addition & 4 deletions src/components/ResetModal.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import useStorage from '@/lib/storage'
import { PASSWORD_KEY } from '@/lib/password'
import { Checkbox } from '@/components/ui/checkbox'
import { XMarkIcon } from '@heroicons/vue/20/solid'
import { V3_ENCRYPTED_WALLETS_STORAGE_KEY } from '@/lib/storage/key'
defineProps<{
show: boolean
Expand All @@ -22,9 +20,8 @@ const checked3 = ref(false)
const checkedAll = computed(() => checked1.value && checked2.value && checked3.value && resetText.value === 'RESET')
const disconnect = async () => {
await storage.clear()
emit('update:show', false)
await storage.delete(PASSWORD_KEY)
await storage.delete(V3_ENCRYPTED_WALLETS_STORAGE_KEY)
window.location.reload()
}
Expand Down
3 changes: 1 addition & 2 deletions src/lib/backup.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import useStorage from './storage'
import { BACKUP_V3_KEY } from './storage/key'
import { getCurrentWalletId } from './wallet'

const storage = useStorage()

const BACKUP_V3_KEY = 'backup_v3'

export const getBackupV3Wallet = async () => {
return await storage.get<string[]>(BACKUP_V3_KEY, { defaultValue: [] })
}
Expand Down
3 changes: 1 addition & 2 deletions src/lib/lock.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import useStorage from './storage'
import { IS_DEV } from '@/data/config'
import { notifyBg } from './notify-bg'
import { LAST_LOCK_TIME_KEY, LOCK_KEY } from './storage/key'
import { checkPassword, hasPassword, getEncryptedPassword } from './password'

const storage = useStorage()

const LOCK_KEY = 'locked'
const LAST_LOCK_TIME_KEY = 'LAST_LOCK_TIME'

export async function lock() {
await storage.set(LOCK_KEY, true)
Expand Down
17 changes: 8 additions & 9 deletions src/lib/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@ import { notifyBg } from '@/lib/notify-bg'
import { getCurrentAccountId } from './account'
import { notifyContent } from '@/lib/notify-content'
import { Chain, type Net } from '@metalet/utxo-wallet-service'
import { SERVICE_NETWORK_KEY, NETWORK_KEY } from './storage/key'

// TODO: refactor to use global state

export type Service = Chain[]
export type Service = Chain[]
export type ServiceStorage = { [accountId: string]: Chain[] }

export type Network = 'mainnet' | 'testnet' | 'regtest'

export const Service_Network_Key = 'service_network'

const storage = useStorage()

export async function setServiceNetwork(_service: ServiceStorage) {
await storage.set(Service_Network_Key, _service)
await storage.set(SERVICE_NETWORK_KEY, _service)
}

export async function getServiceNetworkStorage(): Promise<ServiceStorage> {
return await storage.get(Service_Network_Key, { defaultValue: {} })
return await storage.get(SERVICE_NETWORK_KEY, { defaultValue: {} })
}

export async function getServiceNetwork(): Promise<Chain[]> {
Expand All @@ -35,19 +34,19 @@ export async function getServiceNetwork(): Promise<Chain[]> {
}

export async function hasServiceNetwork(): Promise<boolean> {
return !!(await storage.get(Service_Network_Key))
return !!(await storage.get(SERVICE_NETWORK_KEY))
}
export const network = ref<Network>(await storage.get('network', { defaultValue: 'mainnet' }))
export const network = ref<Network>(await storage.get(NETWORK_KEY, { defaultValue: 'mainnet' }))

export async function setNetwork(_network: Network) {
network.value = _network
notifyBg('networkChanged')(_network)
notifyContent('networkChanged')(_network)
await storage.set('network', _network)
await storage.set(NETWORK_KEY, _network)
}

export async function getNetwork(): Promise<Network> {
return await storage.get('network', { defaultValue: 'mainnet' })
return await storage.get(NETWORK_KEY, { defaultValue: 'mainnet' })
}

export function getBtcNetwork() {
Expand Down
3 changes: 1 addition & 2 deletions src/lib/password.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import hash from 'object-hash'
import CryptoJS from 'crypto-js'
import useStorage from './storage'

export const PASSWORD_KEY = 'password'
import { PASSWORD_KEY } from './storage/key'

const storage = useStorage()

Expand Down
11 changes: 11 additions & 0 deletions src/lib/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface Storage {
get<T = string>(key: string, option: { defaultValue: T }): Promise<T>
set(key: string, value: any): Promise<void>
delete(key: string): Promise<void>
clear(): Promise<void>
}

let globalStorage: Storage
Expand All @@ -31,6 +32,7 @@ function useStorage(storageType: StorageType = 'local'): Storage {
get: <T>(key: string) => Promise<T | string | undefined>
set: (key: string, value: string) => Promise<void>
remove: (key: string) => Promise<void>
clear: () => Promise<void>
}
if (IS_DEV) {
const _storage = getDevStorage(storageType)
Expand All @@ -44,6 +46,9 @@ function useStorage(storageType: StorageType = 'local'): Storage {
remove: async function (key: string) {
_storage.removeItem(key)
},
clear: async function () {
_storage.clear()
},
}
} else {
let extension
Expand All @@ -69,6 +74,9 @@ function useStorage(storageType: StorageType = 'local'): Storage {
remove: async function (key: string) {
await _storage.remove(key)
},
clear: async function () {
await _storage.clear()
},
}
}

Expand Down Expand Up @@ -96,6 +104,9 @@ function useStorage(storageType: StorageType = 'local'): Storage {
async delete(key: string): Promise<void> {
return await storage.remove(key)
},
async clear(): Promise<void> {
return await storage.clear()
},
}

return globalStorage
Expand Down
14 changes: 13 additions & 1 deletion src/lib/storage/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export interface MigrateErrorAccount {
errorLog: string
}

// Account/Wallet
// wallet
export const BACKUP_V3_KEY = 'backup_v3'
export const CURRENT_ACCOUNT_ID = 'currentAccountId'
export const V0_ACCOUNT_STORAGE_KEY = 'currentAccount'
export const V1_ACCOUNTS_STORAGE_KEY = 'accounts'
Expand All @@ -23,3 +24,14 @@ export const CURRENT_WALLET_ID = 'currentWalletId'
export const V3_WALLETS_STORAGE_KEY = 'wallets_v3'
export const V3_ENCRYPTED_WALLETS_STORAGE_KEY = 'encrypted_wallets_v3'
export const V3_ENCRYPTED_WALLETS_STORAGE_BACKUP_KEY = 'encrypted_wallets_v3_backup'

// network
export const NETWORK_KEY = 'network'
export const SERVICE_NETWORK_KEY = 'service_network'

// password
export const PASSWORD_KEY = 'password'

// lock
export const LOCK_KEY = 'locked'
export const LAST_LOCK_TIME_KEY = 'last_lock_time'
4 changes: 4 additions & 0 deletions src/pages/wallet/Backup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ getV3CurrentWallet().then((_wallet) => {
const mnemonic = computed(() => {
if (wallet.value && password) {
console.log("mnemonic", wallet.value.mnemonic, "password", password.value, "hash password", hashWithSha256(password.value))
console.log("decrypt", decrypt(wallet.value.mnemonic, IS_DEV ? hashWithSha256(password.value) : password.value))
return decrypt(wallet.value.mnemonic, IS_DEV ? hashWithSha256(password.value) : password.value)
}
return ''
Expand Down
6 changes: 4 additions & 2 deletions src/pages/wallet/InitService.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import { ref } from 'vue'
import useStorage from '@/lib/storage'
import { useRouter } from 'vue-router'
import { type Service } from '@/lib/network'
import { Chain } from '@metalet/utxo-wallet-service'
import { SERVICE_NETWORK_KEY } from '@/lib/storage/key'
import BtcLogoImg from '@/assets/icons-v3/btc-logo.svg?url'
import CheckIcon from '@/assets/icons/check.svg?component'
import SpaceLogoImg from '@/assets/icons-v3/space.svg?url'
import NetworkIcon from '@/assets/icons/network.svg?component'
import { RadioGroup, RadioGroupOption } from '@headlessui/vue'
import { type Service, Service_Network_Key } from '@/lib/network'
const service = ref<Service>(Object.values(Chain))
Expand All @@ -17,7 +19,7 @@ const router = useRouter()
const storage = useStorage()
const goOn = async () => {
await storage.set(Service_Network_Key, service.value)
await storage.set(SERVICE_NETWORK_KEY, service.value)
router.push('/wallet/create-success')
}
</script>
Expand Down
20 changes: 12 additions & 8 deletions src/pages/wallet/SetPassword.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { IS_DEV } from '@/data/config'
import { useRouter } from 'vue-router'
import passwordManager from '@/lib/password'
import { PasswordInput } from '@/components'
import { toast } from '@/components/ui/toast'
import { ChevronLeftIcon } from '@heroicons/vue/24/outline'
import { backupV3EncryptedWalletsStorage, getV3EncryptedWalletsStorage, setV3EncryptedWalletsStorage } from '@/lib/wallet'
import { decrypt, encrypt, hashWithSha256 } from '@/lib/crypto'
import { IS_DEV } from '@/data/config'
import { backupV3EncryptedWalletsStorage, getV3EncryptedWalletsStorage, setV3EncryptedWalletsStorage } from '@/lib/wallet'
const router = useRouter()
const phase = ref<1 | 2>(1)
Expand All @@ -19,11 +19,12 @@ passwordManager.has().then((_hasPassword) => {
})
const error = ref('')
const oldPassword = ref('')
const password = ref('')
const confirmPassword = ref('')
const canPass = computed(() => {
return password.value.length >= 6
return (oldPassword.value.length >= 6 && phase.value === 1) || (password.value.length >= 6 && confirmPassword.value.length >= 6 && phase.value === 2)
})
// 按钮
Expand All @@ -37,23 +38,26 @@ const back = () => {
const next = async () => {
if (phase.value === 1) {
const isCorrect = await passwordManager.check(password.value)
const isCorrect = await passwordManager.check(oldPassword.value)
if (isCorrect) {
password.value = ''
error.value = ''
phase.value = 2
} else {
error.value = 'Incorrect password. Try again.'
}
} else {
if (password.value !== confirmPassword.value) {
if (password.value === oldPassword.value) {
error.value = "New password can't be the same as old password."
}
else if (password.value !== confirmPassword.value) {
error.value = "Passwords don't match. Try again."
} else {
await backupV3EncryptedWalletsStorage()
const wallets = await getV3EncryptedWalletsStorage()
for (const key in wallets) {
if (wallets.hasOwnProperty(key)) {
wallets[key].mnemonic = encrypt(wallets[key].mnemonic, IS_DEV ? hashWithSha256(password.value) : password.value);
const mnemonic = decrypt(wallets[key].mnemonic, IS_DEV ? hashWithSha256(oldPassword.value) : oldPassword.value)
wallets[key].mnemonic = encrypt(mnemonic, IS_DEV ? hashWithSha256(password.value) : password.value)
}
}
await setV3EncryptedWalletsStorage(wallets)
Expand All @@ -78,7 +82,7 @@ const next = async () => {
</p>
</div>
<div class="grow">
<PasswordInput v-if="phase === 1" v-model:password="password" title="Old Password" v-model:error="error"
<PasswordInput v-if="phase === 1" v-model:password="oldPassword" title="Old Password" v-model:error="error"
class="mt-9" />

<div v-if="phase === 2" class="mt-9 space-y-9">
Expand Down
Loading

0 comments on commit 28c7f1f

Please sign in to comment.