passphrase prompt
This commit is contained in:
@@ -2,7 +2,7 @@ import { doc, getDoc } from 'firebase/firestore'
|
||||
import { user, db } from '@/composables/useFirebase'
|
||||
import { decrypt, calculateClientKey } from '@/utils/crypto'
|
||||
|
||||
function getClientKeysFromLocalStorage() {
|
||||
function getClientKeysFromLocalStorage(): { [uid: string]: string } {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem('clientKeys') || '{}')
|
||||
} catch (e) {
|
||||
@@ -10,24 +10,58 @@ function getClientKeysFromLocalStorage() {
|
||||
}
|
||||
}
|
||||
|
||||
export const getClientKey = (): ClientKey | void => {
|
||||
export const clientKey = ref<ClientKey>()
|
||||
|
||||
export const getClientKey = () => {
|
||||
if (!user.value) return
|
||||
const clientKeys = getClientKeysFromLocalStorage()
|
||||
const clientKey = clientKeys[user.value?.uid] || calculateClientKey('test')
|
||||
return clientKey
|
||||
clientKey.value = clientKeys[user.value?.uid]
|
||||
}
|
||||
|
||||
export async function getEncryptionKey(): Promise<EncryptionKey | void> {
|
||||
if (!user.value) return
|
||||
const clientKey = getClientKey()
|
||||
if (!db.value || !clientKey) return
|
||||
const data = (await getDoc(doc(db.value, 'encryptionKeys', user.value?.uid || ''))).data()
|
||||
if (!data) return
|
||||
const { key } = data
|
||||
const encryptionKey: EncryptionKey = decrypt(key, clientKey)
|
||||
return encryptionKey
|
||||
export const setClientKey = (passphrase: string) => {
|
||||
const calculatedClientKey = calculateClientKey(passphrase)
|
||||
const verified = verifyClientKey(calculatedClientKey)
|
||||
if (!user.value || !verified) return
|
||||
const clientKeys = getClientKeysFromLocalStorage()
|
||||
clientKeys[user.value.uid] = calculatedClientKey
|
||||
localStorage.setItem('clientKeys', JSON.stringify(clientKeys))
|
||||
clientKey.value = calculatedClientKey
|
||||
getEncryptionKey()
|
||||
return true
|
||||
}
|
||||
|
||||
export const verifyClientKey = (clientKey: ClientKey) => {
|
||||
try {
|
||||
if (!encryptedEncryptionKey.value) throw new Error('Encryption key is null')
|
||||
if (!clientKey) throw new Error('Client key is null')
|
||||
decrypt(encryptedEncryptionKey.value, clientKey)
|
||||
return true
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const encryptedEncryptionKey = ref<EncryptedEncryptionKey>()
|
||||
|
||||
async function getEncryptedEncryptionKey(): Promise<EncryptedEncryptionKey | void> {
|
||||
if (!user.value || !db.value) return
|
||||
const data = (await getDoc(doc(db.value, 'encryptionKeys', user.value?.uid || ''))).data()
|
||||
return data?.key
|
||||
}
|
||||
|
||||
export const encryptionKey = ref<EncryptionKey | null>()
|
||||
|
||||
export async function getEncryptionKey() {
|
||||
encryptedEncryptionKey.value = (await getEncryptedEncryptionKey()) || undefined
|
||||
if (!encryptedEncryptionKey.value || !clientKey.value) return
|
||||
encryptionKey.value = decrypt(encryptedEncryptionKey.value, clientKey.value)
|
||||
}
|
||||
|
||||
export const passphraseRequired = computed(() => {
|
||||
return Boolean(encryptedEncryptionKey.value && !clientKey.value)
|
||||
})
|
||||
|
||||
const decryptNote = (note: BaseNote, key: EncryptionKey) => {
|
||||
return {
|
||||
...note,
|
||||
|
||||
@@ -3,19 +3,19 @@ import { useTitle } from '@vueuse/core'
|
||||
import { doc, getDoc } from 'firebase/firestore'
|
||||
import { viewModes, activeViewMode } from '@/composables/useViewMode'
|
||||
import { initialized, user, db } from '@/composables/useFirebase'
|
||||
import { decryptNotes, getEncryptionKey } from '@/composables/useEncryption'
|
||||
import { decryptNotes, encryptionKey } from '@/composables/useEncryption'
|
||||
import { defaultNotes } from '@/utils/defaultNotes'
|
||||
import { mdToHtml } from '@/utils/markdown'
|
||||
import { getAllMatches } from '@/utils/helpers'
|
||||
|
||||
const notesSources = computed(() => ({
|
||||
export const notesSources = computed(() => ({
|
||||
local: true,
|
||||
firebase: initialized.value && user.value
|
||||
}))
|
||||
|
||||
type notesSourceValues = keyof typeof notesSources.value | null
|
||||
|
||||
const activeNotesSource = ref<notesSourceValues>(null)
|
||||
export const activeNotesSource = ref<notesSourceValues>(null)
|
||||
|
||||
watchEffect(() => {
|
||||
const getSource = (): notesSourceValues => {
|
||||
@@ -29,14 +29,14 @@ const baseNotes = ref<{ [noteId: string]: BaseNote }>({})
|
||||
watch(
|
||||
baseNotes,
|
||||
() => {
|
||||
console.log(`Sync base notes with ${activeNotesSource.value}`, baseNotes.value)
|
||||
if (!activeNotesSource.value) return
|
||||
if (!activeNotesSource.value || Object.keys(baseNotes.value).length === 0) return
|
||||
if (activeNotesSource.value === 'local') {
|
||||
console.log('sync with local')
|
||||
localStorage.setItem('notes', JSON.stringify(baseNotes.value))
|
||||
} else if (activeNotesSource.value === 'firebase') {
|
||||
console.log('sync with firebase')
|
||||
}
|
||||
console.log(`Sync base notes with ${activeNotesSource.value}`, baseNotes.value)
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
@@ -209,7 +209,7 @@ const parseBaseNotes = (notes: BaseNotes): BaseNotes => {
|
||||
}
|
||||
|
||||
watch(
|
||||
activeNotesSource,
|
||||
[activeNotesSource, encryptionKey],
|
||||
async () => {
|
||||
if (!activeNotesSource.value) return
|
||||
baseNotes.value = {}
|
||||
@@ -221,11 +221,11 @@ watch(
|
||||
console.log(error)
|
||||
}
|
||||
} else if (activeNotesSource.value === 'firebase' && db.value) {
|
||||
if (encryptionKey.value === undefined) return
|
||||
const firebaseNotes = (
|
||||
await getDoc(doc(db.value, 'pages', user.value?.uid || ''))
|
||||
).data() as { [noteId: string]: any }
|
||||
const encryptionKey = await getEncryptionKey()
|
||||
notes = encryptionKey ? decryptNotes(firebaseNotes, encryptionKey) : firebaseNotes
|
||||
notes = encryptionKey.value ? decryptNotes(firebaseNotes, encryptionKey.value) : firebaseNotes
|
||||
console.log('get notes from firebase', notes)
|
||||
}
|
||||
baseNotes.value = parseBaseNotes(notes)
|
||||
|
||||
Reference in New Issue
Block a user