Create PassphraseDialog.vue with create/enter passphrase flows, glass morphism styling, and skip option. Wire into App.vue to prompt on startup when crypto is enabled. Salt stored in localStorage, key derived via PBKDF2 and held in memory for the session only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
1.5 KiB
Vue
60 lines
1.5 KiB
Vue
<template>
|
|
<div class="h-dvh flex flex-col" :class="currentTheme">
|
|
<RouterView />
|
|
<ArticleOverlay />
|
|
<PassphraseDialog
|
|
:visible="showPassphrase"
|
|
:is-creating="isCreatingPassphrase"
|
|
@submit="handlePassphraseSubmit"
|
|
@skip="showPassphrase = false"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { RouterView } from 'vue-router'
|
|
import { useTheme } from '@/composables/useTheme'
|
|
import ArticleOverlay from '@/components/content/ArticleOverlay.vue'
|
|
import PassphraseDialog from '@/components/ui/PassphraseDialog.vue'
|
|
import {
|
|
isCryptoEnabled,
|
|
deriveKey,
|
|
generateSalt,
|
|
setSessionKey,
|
|
} from '@/utils/crypto'
|
|
|
|
const { currentTheme, initTheme } = useTheme()
|
|
|
|
const showPassphrase = ref(false)
|
|
const isCreatingPassphrase = ref(false)
|
|
|
|
const SALT_KEY = 'aiui-crypto-salt'
|
|
|
|
async function handlePassphraseSubmit(passphrase: string) {
|
|
let saltHex = localStorage.getItem(SALT_KEY)
|
|
let salt: Uint8Array
|
|
|
|
if (saltHex) {
|
|
salt = new Uint8Array(saltHex.match(/.{2}/g)!.map(b => parseInt(b, 16)))
|
|
} else {
|
|
salt = await generateSalt()
|
|
saltHex = Array.from(salt).map(b => b.toString(16).padStart(2, '0')).join('')
|
|
localStorage.setItem(SALT_KEY, saltHex)
|
|
}
|
|
|
|
const key = await deriveKey(passphrase, salt)
|
|
setSessionKey(key, salt)
|
|
showPassphrase.value = false
|
|
}
|
|
|
|
onMounted(() => {
|
|
initTheme()
|
|
if (isCryptoEnabled()) {
|
|
const hasSalt = !!localStorage.getItem(SALT_KEY)
|
|
isCreatingPassphrase.value = !hasSalt
|
|
showPassphrase.value = true
|
|
}
|
|
})
|
|
</script>
|