mirror of
https://github.com/haexhub/haex-hub.git
synced 2025-12-17 06:30:50 +01:00
removed haex-pass components
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { readFile } from '@tauri-apps/plugin-fs'
|
||||
import { EXTENSION_PROTOCOL_PREFIX } from '~/config/constants'
|
||||
import { getExtensionUrl } from '~/utils/extension'
|
||||
|
||||
import type {
|
||||
IHaexHubExtension,
|
||||
@ -55,30 +55,18 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
const extensionEntry = computed(() => {
|
||||
if (
|
||||
!currentExtension.value?.version ||
|
||||
!currentExtension.value?.id ||
|
||||
!currentExtension.value?.publicKey ||
|
||||
!currentExtension.value?.name
|
||||
)
|
||||
return null
|
||||
|
||||
// Extract key_hash from full_extension_id (everything before first underscore)
|
||||
const firstUnderscoreIndex = currentExtension.value.id.indexOf('_')
|
||||
if (firstUnderscoreIndex === -1) {
|
||||
console.error(
|
||||
'Invalid full_extension_id format:',
|
||||
currentExtension.value.id,
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
const keyHash = currentExtension.value.id.substring(0, firstUnderscoreIndex)
|
||||
|
||||
const encodedInfo = encodeExtensionInfo(
|
||||
keyHash,
|
||||
return getExtensionUrl(
|
||||
currentExtension.value.publicKey,
|
||||
currentExtension.value.name,
|
||||
currentExtension.value.version,
|
||||
'index.html',
|
||||
currentExtension.value.devServerUrl ?? undefined
|
||||
)
|
||||
|
||||
return `${EXTENSION_PROTOCOL_PREFIX}localhost/${encodedInfo}/index.html`
|
||||
})
|
||||
|
||||
/* const getExtensionPathAsync = async (
|
||||
@ -116,16 +104,8 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
const extensions =
|
||||
await invoke<ExtensionInfoResponse[]>('get_all_extensions')
|
||||
|
||||
availableExtensions.value = extensions.map((ext) => ({
|
||||
id: ext.fullId,
|
||||
name: ext.displayName || ext.name,
|
||||
version: ext.version,
|
||||
author: ext.namespace,
|
||||
icon: ext.icon,
|
||||
enabled: ext.enabled,
|
||||
description: ext.description,
|
||||
homepage: ext.homepage,
|
||||
}))
|
||||
// ExtensionInfoResponse is now directly compatible with IHaexHubExtension
|
||||
availableExtensions.value = extensions
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der Extensions:', error)
|
||||
throw error
|
||||
@ -185,22 +165,16 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
const removeExtensionAsync = async (extensionId: string, version: string) => {
|
||||
const removeExtensionAsync = async (
|
||||
publicKey: string,
|
||||
name: string,
|
||||
version: string,
|
||||
) => {
|
||||
try {
|
||||
await invoke('remove_extension', {
|
||||
extensionId,
|
||||
extensionVersion: version,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Entfernen der Extension:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const removeExtensionByFullIdAsync = async (fullExtensionId: string) => {
|
||||
try {
|
||||
await invoke('remove_extension_by_full_id', {
|
||||
fullExtensionId,
|
||||
publicKey,
|
||||
name,
|
||||
version,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Entfernen der Extension:', error)
|
||||
@ -219,15 +193,18 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
} */
|
||||
|
||||
const isExtensionInstalledAsync = async ({
|
||||
id,
|
||||
publicKey,
|
||||
name,
|
||||
version,
|
||||
}: {
|
||||
id: string
|
||||
publicKey: string
|
||||
name: string
|
||||
version: string
|
||||
}) => {
|
||||
try {
|
||||
return await invoke<boolean>('is_extension_installed', {
|
||||
extensionId: id,
|
||||
publicKey,
|
||||
name,
|
||||
extensionVersion: version,
|
||||
})
|
||||
} catch (error) {
|
||||
@ -314,7 +291,6 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
loadExtensionsAsync,
|
||||
previewManifestAsync,
|
||||
removeExtensionAsync,
|
||||
removeExtensionByFullIdAsync,
|
||||
}
|
||||
})
|
||||
|
||||
@ -370,20 +346,3 @@ export const useExtensionsStore = defineStore('extensionsStore', () => {
|
||||
throw new Error(JSON.stringify(error))
|
||||
}
|
||||
} */
|
||||
|
||||
function encodeExtensionInfo(
|
||||
keyHash: string,
|
||||
name: string,
|
||||
version: string,
|
||||
): string {
|
||||
const info = {
|
||||
key_hash: keyHash,
|
||||
name: name,
|
||||
version: version,
|
||||
}
|
||||
const jsonString = JSON.stringify(info)
|
||||
const bytes = new TextEncoder().encode(jsonString)
|
||||
return Array.from(bytes)
|
||||
.map((b) => b.toString(16).padStart(2, '0'))
|
||||
.join('')
|
||||
}
|
||||
|
||||
@ -28,10 +28,10 @@ export const useExtensionTabsStore = defineStore('extensionTabsStore', () => {
|
||||
)
|
||||
})
|
||||
|
||||
const extensionsStore = useExtensionsStore()
|
||||
|
||||
// Actions
|
||||
const openTab = (extensionId: string) => {
|
||||
// Hole Extension-Info aus dem anderen Store
|
||||
const extensionsStore = useExtensionsStore()
|
||||
const extension = extensionsStore.availableExtensions.find(
|
||||
(ext) => ext.id === extensionId,
|
||||
)
|
||||
@ -43,7 +43,9 @@ export const useExtensionTabsStore = defineStore('extensionTabsStore', () => {
|
||||
|
||||
// Check if extension is enabled
|
||||
if (!extension.enabled) {
|
||||
console.warn(`Extension ${extensionId} ist deaktiviert und kann nicht geöffnet werden`)
|
||||
console.warn(
|
||||
`Extension ${extensionId} ist deaktiviert und kann nicht geöffnet werden`,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
@ -91,7 +93,9 @@ export const useExtensionTabsStore = defineStore('extensionTabsStore', () => {
|
||||
|
||||
// Reload iframe if inactive for more than 10 minutes
|
||||
if (inactiveDuration > TEN_MINUTES && newTab.iframe) {
|
||||
console.log(`[TabStore] Reloading extension ${extensionId} after ${Math.round(inactiveDuration / 1000)}s inactivity`)
|
||||
console.log(
|
||||
`[TabStore] Reloading extension ${extensionId} after ${Math.round(inactiveDuration / 1000)}s inactivity`,
|
||||
)
|
||||
const currentSrc = newTab.iframe.src
|
||||
newTab.iframe.src = 'about:blank'
|
||||
// Small delay to ensure reload
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
{
|
||||
"group": {
|
||||
"create": "Gruppe erstellen"
|
||||
},
|
||||
"entry": {
|
||||
"create": "Eintrag erstellen"
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
{
|
||||
"group": {
|
||||
"create": "Create Group"
|
||||
},
|
||||
"entry": {
|
||||
"create": "Create Entry"
|
||||
}
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
//import type { IActionMenuItem } from '~/components/ui/button/types'
|
||||
import type { DropdownMenuItem } from '@nuxt/ui'
|
||||
import de from './de.json'
|
||||
import en from './en.json'
|
||||
|
||||
export const usePasswordsActionMenuStore = defineStore(
|
||||
'passwordsActionMenuStore',
|
||||
() => {
|
||||
const { $i18n } = useNuxtApp()
|
||||
|
||||
$i18n.setLocaleMessage('de', {
|
||||
...de,
|
||||
})
|
||||
$i18n.setLocaleMessage('en', { ...en })
|
||||
|
||||
const localeRoute = useLocaleRoute()
|
||||
const menu = computed<DropdownMenuItem[]>(() => [
|
||||
{
|
||||
label: $i18n.t('group.create'),
|
||||
icon: 'mdi:folder-plus-outline',
|
||||
type: 'link',
|
||||
onSelect: () => {
|
||||
navigateTo(
|
||||
localeRoute({
|
||||
name: 'passwordGroupCreate',
|
||||
params: {
|
||||
...useRouter().currentRoute.value.params,
|
||||
groupId: usePasswordGroupStore().currentGroupId,
|
||||
},
|
||||
}),
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
label: $i18n.t('entry.create'),
|
||||
icon: 'mdi:key-plus',
|
||||
type: 'link',
|
||||
onSelect: () => {
|
||||
navigateTo(
|
||||
localeRoute({
|
||||
name: 'passwordItemCreate',
|
||||
params: {
|
||||
...useRouter().currentRoute.value.params,
|
||||
groupId: usePasswordGroupStore().currentGroupId,
|
||||
},
|
||||
}),
|
||||
)
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
return {
|
||||
menu,
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -1,353 +0,0 @@
|
||||
import { eq, isNull, sql } from 'drizzle-orm'
|
||||
import type { IPasswordMenuItem } from '~/components/haex/pass/mobile/menu/types'
|
||||
import {
|
||||
haexPasswordsGroupItems,
|
||||
haexPasswordsGroups,
|
||||
type InsertHaexPasswordsGroups,
|
||||
type SelectHaexPasswordsGroupItems,
|
||||
type SelectHaexPasswordsGroups,
|
||||
} from '~~/src-tauri/database/schemas/vault'
|
||||
|
||||
export const trashId = 'trash'
|
||||
|
||||
export const usePasswordGroupStore = defineStore('passwordGroupStore', () => {
|
||||
const groups = ref<SelectHaexPasswordsGroups[]>([])
|
||||
|
||||
const currentGroupId = computed<string | null | undefined>({
|
||||
get: () =>
|
||||
getSingleRouteParam(useRouter().currentRoute.value.params.groupId) ||
|
||||
undefined,
|
||||
set: (newGroupId) => {
|
||||
console.log('set groupId', newGroupId)
|
||||
useRouter().currentRoute.value.params.groupId = newGroupId ?? ''
|
||||
},
|
||||
})
|
||||
|
||||
const currentGroup = computedAsync(() =>
|
||||
currentGroupId.value ? readGroupAsync(currentGroupId.value) : null,
|
||||
)
|
||||
|
||||
const selectedGroupItems = ref<IPasswordMenuItem[]>()
|
||||
|
||||
const breadCrumbs = computed(() => getParentChain(currentGroupId.value))
|
||||
|
||||
const getParentChain = (
|
||||
groupId?: string | null,
|
||||
chain: SelectHaexPasswordsGroups[] = [],
|
||||
) => {
|
||||
const group = groups.value.find((group) => group.id === groupId)
|
||||
console.log('getParentChain1: found group', group, chain)
|
||||
/* if (group) {
|
||||
chain.push(group)
|
||||
console.log('getParentChain: found group', group, chain)
|
||||
return getParentChain(group.parentId, chain)
|
||||
}
|
||||
|
||||
return chain.reverse() */
|
||||
return []
|
||||
}
|
||||
|
||||
const syncGroupItemsAsync = async () => {
|
||||
const { syncItemsAsync } = usePasswordItemStore()
|
||||
|
||||
groups.value = (await readGroupsAsync()) ?? []
|
||||
await syncItemsAsync()
|
||||
/* currentGroup.value = groups.value?.find(
|
||||
(group) => group.id === currentGroupId.value,
|
||||
)
|
||||
|
||||
try {
|
||||
currentGroupItems.groups =
|
||||
(await getByParentIdAsync(currentGroupId)) ?? []
|
||||
currentGroupItems.items = (await readByGroupIdAsync(currentGroupId)) ?? []
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
currentGroupItems.groups = []
|
||||
currentGroupItems.items = []
|
||||
await addNotificationAsync({
|
||||
type: 'log',
|
||||
text: JSON.stringify(error),
|
||||
})
|
||||
} */
|
||||
}
|
||||
|
||||
watch(currentGroupId, () => syncGroupItemsAsync(), {
|
||||
immediate: true,
|
||||
})
|
||||
|
||||
const inTrashGroup = computed(() =>
|
||||
breadCrumbs.value?.some((item) => item.id === trashId),
|
||||
)
|
||||
|
||||
return {
|
||||
addGroupAsync,
|
||||
areGroupsEqual,
|
||||
breadCrumbs,
|
||||
createTrashIfNotExistsAsync,
|
||||
currentGroup,
|
||||
currentGroupId,
|
||||
// currentGroupItems,
|
||||
deleteGroupAsync,
|
||||
getChildGroupsRecursiveAsync,
|
||||
groups,
|
||||
inTrashGroup,
|
||||
insertGroupItemsAsync,
|
||||
navigateToGroupAsync,
|
||||
navigateToGroupItemsAsync,
|
||||
readGroupAsync,
|
||||
readGroupItemsAsync,
|
||||
readGroupsAsync,
|
||||
selectedGroupItems,
|
||||
syncGroupItemsAsync,
|
||||
trashId,
|
||||
updateAsync,
|
||||
}
|
||||
})
|
||||
|
||||
const addGroupAsync = async (group: Partial<InsertHaexPasswordsGroups>) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
const { syncGroupItemsAsync } = usePasswordGroupStore()
|
||||
|
||||
const newGroup: InsertHaexPasswordsGroups = {
|
||||
id: group.id || crypto.randomUUID(),
|
||||
parentId: group.parentId,
|
||||
color: group.color,
|
||||
icon: group.icon,
|
||||
name: group.name,
|
||||
order: group.order,
|
||||
}
|
||||
await currentVault?.drizzle?.insert(haexPasswordsGroups).values(newGroup)
|
||||
await syncGroupItemsAsync()
|
||||
return newGroup
|
||||
}
|
||||
|
||||
const readGroupAsync = async (groupId: string) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
const group = await currentVault?.drizzle.query.haexPasswordsGroups.findFirst(
|
||||
{
|
||||
where: eq(haexPasswordsGroups.id, groupId),
|
||||
},
|
||||
)
|
||||
console.log('readGroupAsync', groupId, group)
|
||||
return group
|
||||
}
|
||||
|
||||
const readGroupsAsync = async (filter?: { parentId?: string | null }) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
if (filter?.parentId) {
|
||||
return await currentVault?.drizzle
|
||||
.select()
|
||||
.from(haexPasswordsGroups)
|
||||
.where(eq(haexPasswordsGroups.id, filter.parentId))
|
||||
} else {
|
||||
return await currentVault?.drizzle
|
||||
.select()
|
||||
.from(haexPasswordsGroups)
|
||||
.orderBy(sql`${haexPasswordsGroups.order} nulls last`)
|
||||
}
|
||||
}
|
||||
|
||||
const readGroupItemsAsync = async (
|
||||
groupId?: string | null,
|
||||
): Promise<SelectHaexPasswordsGroupItems[]> => {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
if (groupId) {
|
||||
return (
|
||||
currentVault?.drizzle
|
||||
?.select()
|
||||
.from(haexPasswordsGroupItems)
|
||||
.where(eq(haexPasswordsGroupItems.groupId, groupId)) ?? []
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
currentVault?.drizzle
|
||||
?.select()
|
||||
.from(haexPasswordsGroupItems)
|
||||
.where(isNull(haexPasswordsGroupItems.groupId)) ?? []
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const getChildGroupsRecursiveAsync = async (
|
||||
groupId: string,
|
||||
groups: SelectHaexPasswordsGroups[] = [],
|
||||
) => {
|
||||
const childGroups = (await getByParentIdAsync(groupId)) ?? []
|
||||
for (const child of childGroups) {
|
||||
groups.push(...(await getChildGroupsRecursiveAsync(child.id)))
|
||||
}
|
||||
|
||||
return groups
|
||||
}
|
||||
|
||||
const getByParentIdAsync = async (
|
||||
parentId?: string | null,
|
||||
): Promise<SelectHaexPasswordsGroups[]> => {
|
||||
try {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
console.log('getByParentIdAsync', parentId)
|
||||
if (parentId) {
|
||||
const groups = await currentVault?.drizzle
|
||||
?.select()
|
||||
.from(haexPasswordsGroups)
|
||||
.where(eq(haexPasswordsGroups.parentId, parentId))
|
||||
.orderBy(sql`${haexPasswordsGroups.order} nulls last`)
|
||||
|
||||
return groups ?? []
|
||||
} else {
|
||||
const groups = await currentVault?.drizzle
|
||||
?.select()
|
||||
.from(haexPasswordsGroups)
|
||||
.where(isNull(haexPasswordsGroups.parentId))
|
||||
.orderBy(sql`${haexPasswordsGroups.order} nulls last`)
|
||||
|
||||
return groups ?? []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
const navigateToGroupAsync = (groupId?: string | null) =>
|
||||
navigateTo(
|
||||
useLocaleRoute()({
|
||||
name: 'passwordGroupEdit',
|
||||
params: {
|
||||
vaultId: useRouter().currentRoute.value.params.vaultId,
|
||||
groupId,
|
||||
},
|
||||
query: {
|
||||
...useRouter().currentRoute.value.query,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
const updateAsync = async (group: InsertHaexPasswordsGroups) => {
|
||||
console.log('updateAsync', group)
|
||||
const { currentVault } = useVaultStore()
|
||||
if (!group.id) return
|
||||
|
||||
const newGroup: InsertHaexPasswordsGroups = {
|
||||
id: group.id,
|
||||
color: group.color,
|
||||
description: group.description,
|
||||
icon: group.icon,
|
||||
name: group.name,
|
||||
order: group.order,
|
||||
parentId: group.parentId,
|
||||
}
|
||||
|
||||
return currentVault?.drizzle
|
||||
.update(haexPasswordsGroups)
|
||||
.set(newGroup)
|
||||
.where(eq(haexPasswordsGroups.id, newGroup.id))
|
||||
}
|
||||
|
||||
const navigateToGroupItemsAsync = (groupId: string) => {
|
||||
return navigateTo(
|
||||
useLocaleRoute()({
|
||||
name: 'passwordGroupItems',
|
||||
params: {
|
||||
groupId,
|
||||
},
|
||||
query: {
|
||||
...useRouter().currentRoute.value.query,
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const insertGroupItemsAsync = async (
|
||||
items: IPasswordMenuItem[],
|
||||
groupdId?: string | null,
|
||||
) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
const { groups } = usePasswordGroupStore()
|
||||
const { syncGroupItemsAsync } = usePasswordGroupStore()
|
||||
|
||||
const targetGroup = groups.find((group) => group.id === groupdId)
|
||||
|
||||
for (const item of items) {
|
||||
if (item.type === 'group') {
|
||||
const updateGroup = groups.find((group) => group.id === item.id)
|
||||
|
||||
if (updateGroup?.parentId === targetGroup?.id) return
|
||||
|
||||
if (updateGroup) {
|
||||
updateGroup.parentId = targetGroup?.id ?? null
|
||||
await currentVault?.drizzle
|
||||
.update(haexPasswordsGroups)
|
||||
.set(updateGroup)
|
||||
.where(eq(haexPasswordsGroups.id, updateGroup.id))
|
||||
}
|
||||
} else {
|
||||
if (targetGroup)
|
||||
await currentVault?.drizzle
|
||||
.update(haexPasswordsGroupItems)
|
||||
.set({ groupId: targetGroup.id, itemId: item.id })
|
||||
.where(eq(haexPasswordsGroupItems.itemId, item.id))
|
||||
}
|
||||
}
|
||||
return syncGroupItemsAsync()
|
||||
}
|
||||
|
||||
const createTrashIfNotExistsAsync = async () => {
|
||||
const exists = await readGroupAsync(trashId)
|
||||
console.log('found trash', exists)
|
||||
if (exists) return true
|
||||
|
||||
return addGroupAsync({
|
||||
name: 'Trash',
|
||||
id: trashId,
|
||||
icon: 'mdi:trash-outline',
|
||||
parentId: null,
|
||||
})
|
||||
}
|
||||
|
||||
const deleteGroupAsync = async (groupId: string, final: boolean = false) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
const { readByGroupIdAsync, deleteAsync } = usePasswordItemStore()
|
||||
|
||||
console.log('deleteGroupAsync', groupId, final)
|
||||
|
||||
if (final || groupId === trashId) {
|
||||
const childGroups = await getByParentIdAsync(groupId)
|
||||
|
||||
for (const child of childGroups) {
|
||||
await deleteGroupAsync(child.id, true)
|
||||
}
|
||||
|
||||
const items = (await readByGroupIdAsync(groupId)) ?? []
|
||||
console.log('deleteGroupAsync delete Items', items)
|
||||
for (const item of items) {
|
||||
if (item) await deleteAsync(item.id, true)
|
||||
}
|
||||
|
||||
return await currentVault?.drizzle
|
||||
.delete(haexPasswordsGroups)
|
||||
.where(eq(haexPasswordsGroups.id, groupId))
|
||||
} else {
|
||||
if (await createTrashIfNotExistsAsync())
|
||||
await updateAsync({ id: groupId, parentId: trashId })
|
||||
}
|
||||
}
|
||||
|
||||
const areGroupsEqual = (
|
||||
groupA: unknown | unknown[] | null,
|
||||
groupB: unknown | unknown[] | null,
|
||||
) => {
|
||||
if (groupA === null && groupB === null) return true
|
||||
|
||||
if (Array.isArray(groupA) && Array.isArray(groupB)) {
|
||||
console.log('compare object arrays', groupA, groupB)
|
||||
if (groupA.length === groupB.length) return true
|
||||
|
||||
return groupA.some((group, index) => {
|
||||
return areObjectsEqual(group, groupA[index])
|
||||
})
|
||||
}
|
||||
return areObjectsEqual(groupA, groupB)
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { haexPasswordsItemHistory } from '~~/src-tauri/database/schemas/vault'
|
||||
|
||||
export const usePasswordHistoryStore = defineStore(
|
||||
'passwordHistoryStore',
|
||||
() => {
|
||||
return { getAsync }
|
||||
},
|
||||
)
|
||||
|
||||
const getAsync = async (itemId: string | null) => {
|
||||
if (!itemId) return null
|
||||
|
||||
try {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
const history = await currentVault?.drizzle
|
||||
?.select()
|
||||
.from(haexPasswordsItemHistory)
|
||||
.where(eq(haexPasswordsItemHistory.itemId, itemId))
|
||||
|
||||
console.log('found history ', history)
|
||||
return history
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@ -1,362 +0,0 @@
|
||||
import { eq, isNull } from 'drizzle-orm'
|
||||
import {
|
||||
haexPasswordsGroupItems,
|
||||
haexPasswordsItemDetails,
|
||||
haexPasswordsItemHistory,
|
||||
haexPasswordsItemKeyValues,
|
||||
type InsertHaexPasswordsItemDetails,
|
||||
type InserthaexPasswordsItemKeyValues,
|
||||
type SelectHaexPasswordsGroupItems,
|
||||
type SelectHaexPasswordsGroups,
|
||||
type SelectHaexPasswordsItemDetails,
|
||||
type SelectHaexPasswordsItemKeyValues,
|
||||
} from '~~/src-tauri/database/schemas/vault'
|
||||
|
||||
export const usePasswordItemStore = defineStore('passwordItemStore', () => {
|
||||
const currentItemId = computed({
|
||||
get: () =>
|
||||
getSingleRouteParam(useRouter().currentRoute.value.params.itemId),
|
||||
set: (entryId) => {
|
||||
console.log('set entryId', entryId)
|
||||
useRouter().currentRoute.value.params.entryId = entryId ?? ''
|
||||
},
|
||||
})
|
||||
|
||||
const currentItem = computedAsync(() => readAsync(currentItemId.value))
|
||||
|
||||
const items = ref<
|
||||
{
|
||||
haex_passwords_item_details: SelectHaexPasswordsItemDetails
|
||||
haex_passwords_group_items: SelectHaexPasswordsGroupItems
|
||||
}[]
|
||||
>([])
|
||||
|
||||
const syncItemsAsync = async () => {
|
||||
const { currentVault } = useVaultStore()
|
||||
items.value =
|
||||
(await currentVault?.drizzle
|
||||
.select()
|
||||
.from(haexPasswordsItemDetails)
|
||||
.innerJoin(
|
||||
haexPasswordsGroupItems,
|
||||
eq(haexPasswordsItemDetails.id, haexPasswordsGroupItems.itemId),
|
||||
)) ?? []
|
||||
}
|
||||
|
||||
return {
|
||||
currentItemId,
|
||||
currentItem,
|
||||
addAsync,
|
||||
addKeyValueAsync,
|
||||
addKeyValuesAsync,
|
||||
deleteAsync,
|
||||
deleteKeyValueAsync,
|
||||
items,
|
||||
readByGroupIdAsync,
|
||||
readAsync,
|
||||
readKeyValuesAsync,
|
||||
syncItemsAsync,
|
||||
updateAsync,
|
||||
}
|
||||
})
|
||||
|
||||
const addAsync = async (
|
||||
details: SelectHaexPasswordsItemDetails,
|
||||
keyValues: SelectHaexPasswordsItemKeyValues[],
|
||||
group?: SelectHaexPasswordsGroups | null,
|
||||
) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
console.log('addItem', details, group)
|
||||
|
||||
const newDetails: InsertHaexPasswordsItemDetails = {
|
||||
id: crypto.randomUUID(),
|
||||
icon: details.icon || group?.icon || null,
|
||||
note: details.note,
|
||||
password: details.password,
|
||||
tags: details.tags,
|
||||
title: details.title,
|
||||
url: details.url,
|
||||
username: details.username,
|
||||
}
|
||||
|
||||
const newKeyValues: InserthaexPasswordsItemKeyValues[] = keyValues.map(
|
||||
(keyValue) => ({
|
||||
id: crypto.randomUUID(),
|
||||
itemId: newDetails.id,
|
||||
key: keyValue.key,
|
||||
value: keyValue.value,
|
||||
}),
|
||||
)
|
||||
|
||||
try {
|
||||
await currentVault?.drizzle.transaction(async (tx) => {
|
||||
await tx.insert(haexPasswordsItemDetails).values(newDetails)
|
||||
|
||||
await tx
|
||||
.insert(haexPasswordsGroupItems)
|
||||
.values({ itemId: newDetails.id, groupId: group?.id ?? null })
|
||||
|
||||
if (newKeyValues.length)
|
||||
await tx.insert(haexPasswordsItemKeyValues).values(newKeyValues)
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('ERROR addItem', error)
|
||||
}
|
||||
|
||||
return newDetails.id
|
||||
}
|
||||
|
||||
const addKeyValueAsync = async (
|
||||
item?: InserthaexPasswordsItemKeyValues | null,
|
||||
itemId?: string,
|
||||
) => {
|
||||
const newKeyValue: InserthaexPasswordsItemKeyValues = {
|
||||
id: crypto.randomUUID(),
|
||||
itemId: item?.itemId || itemId,
|
||||
key: item?.key,
|
||||
value: item?.value,
|
||||
}
|
||||
try {
|
||||
const { currentVault } = useVaultStore()
|
||||
return await currentVault?.drizzle
|
||||
.insert(haexPasswordsItemKeyValues)
|
||||
.values(newKeyValue)
|
||||
} catch (error) {
|
||||
console.error('ERROR addItem', error)
|
||||
}
|
||||
}
|
||||
|
||||
const addKeyValuesAsync = async (
|
||||
items: InserthaexPasswordsItemKeyValues[],
|
||||
itemId?: string,
|
||||
) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
console.log('addKeyValues', items, itemId)
|
||||
|
||||
const newKeyValues: InserthaexPasswordsItemKeyValues[] = items?.map(
|
||||
(item) => ({
|
||||
id: crypto.randomUUID(),
|
||||
itemId: item.itemId || itemId,
|
||||
key: item.key,
|
||||
value: item.value,
|
||||
}),
|
||||
)
|
||||
|
||||
try {
|
||||
return await currentVault?.drizzle
|
||||
.insert(haexPasswordsItemKeyValues)
|
||||
.values(newKeyValues)
|
||||
} catch (error) {
|
||||
console.error('ERROR addItem', error)
|
||||
}
|
||||
}
|
||||
|
||||
const readByGroupIdAsync = async (groupId?: string | null) => {
|
||||
try {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
console.log('get entries by groupId', groupId || null)
|
||||
|
||||
if (groupId) {
|
||||
const entries = await currentVault?.drizzle
|
||||
.select()
|
||||
.from(haexPasswordsGroupItems)
|
||||
.innerJoin(
|
||||
haexPasswordsItemDetails,
|
||||
eq(haexPasswordsItemDetails.id, haexPasswordsGroupItems.itemId),
|
||||
)
|
||||
.where(eq(haexPasswordsGroupItems.groupId, groupId))
|
||||
|
||||
console.log('found entries by groupId', entries)
|
||||
return entries?.map((entry) => entry.haex_passwords_item_details)
|
||||
} else {
|
||||
const entries = await currentVault?.drizzle
|
||||
.select()
|
||||
.from(haexPasswordsGroupItems)
|
||||
.innerJoin(
|
||||
haexPasswordsItemDetails,
|
||||
eq(haexPasswordsItemDetails.id, haexPasswordsGroupItems.itemId),
|
||||
)
|
||||
.where(isNull(haexPasswordsGroupItems.groupId))
|
||||
|
||||
console.log('found entries', entries)
|
||||
return entries?.map((entry) => entry.haex_passwords_item_details)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
const readAsync = async (itemId: string | null) => {
|
||||
if (!itemId) return null
|
||||
|
||||
try {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
const details =
|
||||
await currentVault?.drizzle.query.haexPasswordsItemDetails.findFirst({
|
||||
where: eq(haexPasswordsItemDetails.id, itemId),
|
||||
})
|
||||
|
||||
console.log('readAsync details', details)
|
||||
|
||||
if (!details) return null
|
||||
|
||||
const history = (await usePasswordHistoryStore().getAsync(itemId)) ?? []
|
||||
const keyValues = (await readKeyValuesAsync(itemId)) ?? []
|
||||
|
||||
console.log('found item by id', { details, history, keyValues })
|
||||
return { details, history, keyValues }
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const readKeyValuesAsync = async (itemId: string | null) => {
|
||||
if (!itemId) return null
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
const keyValues =
|
||||
await currentVault?.drizzle.query.haexPasswordsItemKeyValues.findMany({
|
||||
where: eq(haexPasswordsGroupItems.itemId, itemId),
|
||||
})
|
||||
return keyValues
|
||||
}
|
||||
|
||||
const updateAsync = async ({
|
||||
details,
|
||||
keyValues,
|
||||
keyValuesAdd,
|
||||
keyValuesDelete,
|
||||
groupId,
|
||||
}: {
|
||||
details: SelectHaexPasswordsItemDetails
|
||||
keyValues: SelectHaexPasswordsItemKeyValues[]
|
||||
keyValuesAdd: SelectHaexPasswordsItemKeyValues[]
|
||||
keyValuesDelete: SelectHaexPasswordsItemKeyValues[]
|
||||
groupId: string | null
|
||||
}) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
|
||||
if (!details.id) return
|
||||
|
||||
const newDetails: InsertHaexPasswordsItemDetails = {
|
||||
id: details.id,
|
||||
icon: details.icon,
|
||||
note: details.note,
|
||||
password: details.password,
|
||||
tags: details.tags,
|
||||
title: details.title,
|
||||
url: details.url,
|
||||
username: details.username,
|
||||
}
|
||||
|
||||
const newKeyValues: InserthaexPasswordsItemKeyValues[] = keyValues
|
||||
.map((keyValue) => ({
|
||||
id: keyValue.id,
|
||||
itemId: newDetails.id,
|
||||
key: keyValue.key,
|
||||
value: keyValue.value,
|
||||
}))
|
||||
.filter((keyValue) => keyValue.id)
|
||||
|
||||
const newKeyValuesAdd: InserthaexPasswordsItemKeyValues[] = keyValuesAdd.map(
|
||||
(keyValue) => ({
|
||||
id: keyValue.id || crypto.randomUUID(),
|
||||
itemId: newDetails.id,
|
||||
key: keyValue.key,
|
||||
value: keyValue.value,
|
||||
}),
|
||||
)
|
||||
|
||||
console.log('update item', newDetails, newKeyValues, newKeyValuesAdd, groupId)
|
||||
|
||||
return await currentVault?.drizzle.transaction(async (tx) => {
|
||||
await tx
|
||||
.update(haexPasswordsItemDetails)
|
||||
.set(newDetails)
|
||||
.where(eq(haexPasswordsItemDetails.id, newDetails.id))
|
||||
|
||||
await tx
|
||||
.update(haexPasswordsGroupItems)
|
||||
.set({ itemId: newDetails.id, groupId })
|
||||
.where(eq(haexPasswordsGroupItems.itemId, newDetails.id))
|
||||
|
||||
const promises = newKeyValues.map((keyValue) =>
|
||||
tx
|
||||
.update(haexPasswordsItemKeyValues)
|
||||
.set(keyValue)
|
||||
.where(eq(haexPasswordsItemKeyValues.id, keyValue.id)),
|
||||
)
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
if (newKeyValuesAdd.length)
|
||||
await tx.insert(haexPasswordsItemKeyValues).values(newKeyValuesAdd)
|
||||
|
||||
const promisesDelete = keyValuesDelete.map((keyValue) =>
|
||||
tx
|
||||
.delete(haexPasswordsItemKeyValues)
|
||||
.where(eq(haexPasswordsItemKeyValues.id, keyValue.id)),
|
||||
)
|
||||
await Promise.all(promisesDelete)
|
||||
|
||||
return newDetails.id
|
||||
})
|
||||
}
|
||||
|
||||
const deleteAsync = async (itemId: string, final: boolean = false) => {
|
||||
const { currentVault } = useVaultStore()
|
||||
const { createTrashIfNotExistsAsync, trashId } = usePasswordGroupStore()
|
||||
|
||||
console.log('deleteAsync', itemId, final)
|
||||
if (final)
|
||||
await currentVault?.drizzle.transaction(async (tx) => {
|
||||
await tx
|
||||
.delete(haexPasswordsItemKeyValues)
|
||||
.where(eq(haexPasswordsItemKeyValues.itemId, itemId))
|
||||
await tx
|
||||
.delete(haexPasswordsItemHistory)
|
||||
.where(eq(haexPasswordsItemHistory.itemId, itemId))
|
||||
await tx
|
||||
.delete(haexPasswordsGroupItems)
|
||||
.where(eq(haexPasswordsGroupItems.itemId, itemId))
|
||||
await tx
|
||||
.delete(haexPasswordsItemDetails)
|
||||
.where(eq(haexPasswordsItemDetails.id, itemId))
|
||||
})
|
||||
else {
|
||||
if (await createTrashIfNotExistsAsync())
|
||||
await currentVault?.drizzle
|
||||
.update(haexPasswordsGroupItems)
|
||||
.set({ groupId: trashId })
|
||||
.where(eq(haexPasswordsGroupItems.itemId, itemId))
|
||||
}
|
||||
}
|
||||
|
||||
const deleteKeyValueAsync = async (id: string) => {
|
||||
console.log('deleteKeyValueAsync', id)
|
||||
const { currentVault } = useVaultStore()
|
||||
return await currentVault?.drizzle
|
||||
.delete(haexPasswordsItemKeyValues)
|
||||
.where(eq(haexPasswordsItemKeyValues.id, id))
|
||||
}
|
||||
|
||||
/* const areItemsEqual = (
|
||||
groupA: unknown | unknown[] | null,
|
||||
groupB: unknown | unknown[] | null,
|
||||
) => {
|
||||
if (groupA === null && groupB === null) return true
|
||||
|
||||
if (Array.isArray(groupA) && Array.isArray(groupB)) {
|
||||
console.log('compare object arrays', groupA, groupB)
|
||||
if (groupA.length === groupB.length) return true
|
||||
|
||||
return groupA.some((group, index) => {
|
||||
return areObjectsEqual(group, groupA[index])
|
||||
})
|
||||
}
|
||||
return areObjectsEqual(groupA, groupB)
|
||||
} */
|
||||
@ -1,9 +1,14 @@
|
||||
import { load } from '@tauri-apps/plugin-store'
|
||||
import { hostname as tauriHostname } from '@tauri-apps/plugin-os'
|
||||
import {
|
||||
hostname as tauriHostname,
|
||||
platform as tauriPlatform,
|
||||
} from '@tauri-apps/plugin-os'
|
||||
|
||||
export const useDeviceStore = defineStore('vaultInstanceStore', () => {
|
||||
const deviceId = ref<string>()
|
||||
|
||||
const platform = computedAsync(() => tauriPlatform())
|
||||
|
||||
const hostname = computedAsync(() => tauriHostname())
|
||||
|
||||
const deviceName = ref<string>()
|
||||
@ -95,6 +100,7 @@ export const useDeviceStore = defineStore('vaultInstanceStore', () => {
|
||||
deviceName,
|
||||
hostname,
|
||||
isKnownDeviceAsync,
|
||||
platform,
|
||||
readDeviceNameAsync,
|
||||
setDeviceIdAsync,
|
||||
setDeviceIdIfNotExistsAsync,
|
||||
|
||||
Reference in New Issue
Block a user