valaxy 0.14.45 → 0.14.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/components/ValaxyDecrypt.vue +98 -0
- package/client/components/ValaxyMd.vue +8 -5
- package/client/composables/decrypt.ts +66 -0
- package/client/composables/index.ts +3 -0
- package/client/main.ts +2 -0
- package/dist/chunk-AJXGVRTW.cjs +123 -0
- package/dist/chunk-MU6JAKRJ.mjs +123 -0
- package/dist/{config-d86201dd.d.ts → config-c7e66265.d.ts} +15 -0
- package/dist/node/cli.cjs +1 -1
- package/dist/node/cli.mjs +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.cts +1 -1
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.mjs +1 -1
- package/dist/types/index.d.cts +13 -1
- package/dist/types/index.d.ts +13 -1
- package/package.json +16 -16
- package/types/config.ts +20 -0
- package/types/posts.ts +13 -0
- package/dist/chunk-Q6MCN5H3.cjs +0 -123
- package/dist/chunk-QBAMRZW4.mjs +0 -123
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useDecrypt, useFrontmatter } from 'valaxy'
|
|
3
|
+
import type { Ref } from 'vue'
|
|
4
|
+
import { defineComponent, h, inject, ref } from 'vue'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
encryptedContent: string
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
const password = ref('')
|
|
11
|
+
const decryptedContent = ref('')
|
|
12
|
+
|
|
13
|
+
const hasError = ref(false)
|
|
14
|
+
|
|
15
|
+
const onContentUpdated = inject('onContentUpdated') as Ref<() => void>
|
|
16
|
+
|
|
17
|
+
const { decrypt } = useDecrypt()
|
|
18
|
+
async function decryptContent() {
|
|
19
|
+
const ciphertext = props.encryptedContent
|
|
20
|
+
if (!ciphertext)
|
|
21
|
+
return
|
|
22
|
+
try {
|
|
23
|
+
const result = await decrypt(password.value, ciphertext)
|
|
24
|
+
decryptedContent.value = result || ''
|
|
25
|
+
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
onContentUpdated.value?.()
|
|
28
|
+
}, 16)
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
hasError.value = true
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function encryptAgain() {
|
|
36
|
+
decryptedContent.value = ''
|
|
37
|
+
password.value = ''
|
|
38
|
+
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
onContentUpdated.value?.()
|
|
41
|
+
}, 16)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const ValaxyDeprecatedContent = defineComponent({
|
|
45
|
+
name: 'ValaxyDeprecatedContent',
|
|
46
|
+
props: {
|
|
47
|
+
html: String,
|
|
48
|
+
},
|
|
49
|
+
render() {
|
|
50
|
+
const content = `<div>${this.html}</div>`
|
|
51
|
+
return h({
|
|
52
|
+
setup: () => {
|
|
53
|
+
const fm = useFrontmatter()
|
|
54
|
+
return {
|
|
55
|
+
frontmatter: fm,
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
template: content,
|
|
59
|
+
})
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<template>
|
|
65
|
+
<div>
|
|
66
|
+
<div v-if="!decryptedContent" w-full pt-14 pb-10>
|
|
67
|
+
<div
|
|
68
|
+
class="decrypt-password-container w-full sm:w-1/2"
|
|
69
|
+
flex-center m-auto relative
|
|
70
|
+
>
|
|
71
|
+
<input
|
|
72
|
+
v-model="password"
|
|
73
|
+
w-full
|
|
74
|
+
border pl-5 pr-11 py-3 rounded hover:shadow transition
|
|
75
|
+
type="password" placeholder="Enter password"
|
|
76
|
+
:class="hasError && 'border-red'"
|
|
77
|
+
@input="hasError = false"
|
|
78
|
+
@keyup.enter="decryptContent"
|
|
79
|
+
>
|
|
80
|
+
<div
|
|
81
|
+
cursor-pointer
|
|
82
|
+
absolute text-2xl
|
|
83
|
+
i-ri-arrow-right-circle-line right-3
|
|
84
|
+
text-gray hover:text-black
|
|
85
|
+
@click="decryptContent"
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
<div v-else>
|
|
90
|
+
<ValaxyDeprecatedContent :html="decryptedContent" />
|
|
91
|
+
<div w-full text-center mt-8>
|
|
92
|
+
<button m-auto class="btn" font-bold @click="encryptAgain">
|
|
93
|
+
Encrypt Again
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</template>
|
|
@@ -14,9 +14,9 @@ const onContentUpdated = inject('onContentUpdated') as Ref<() => void>
|
|
|
14
14
|
|
|
15
15
|
const { t } = useI18n()
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const contentRef = ref()
|
|
18
18
|
function updateDom() {
|
|
19
|
-
wrapTable(
|
|
19
|
+
wrapTable(contentRef.value)
|
|
20
20
|
onContentUpdated.value?.()
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -39,11 +39,14 @@ if (typeof props.frontmatter.medium_zoom === 'undefined' || props.frontmatter.me
|
|
|
39
39
|
|
|
40
40
|
<template>
|
|
41
41
|
<article v-if="$slots.default" :class="frontmatter.markdown !== false && 'markdown-body'">
|
|
42
|
-
<
|
|
42
|
+
<template v-if="frontmatter.encryptedContent">
|
|
43
|
+
<ValaxyDecrypt :encrypted-content="frontmatter.encryptedContent" />
|
|
44
|
+
</template>
|
|
45
|
+
<slot v-else ref="contentRef" @vue:updated="updateDom" />
|
|
43
46
|
|
|
44
|
-
<div text="center">
|
|
47
|
+
<div v-if="frontmatter.url" text="center">
|
|
45
48
|
<a
|
|
46
|
-
|
|
49
|
+
|
|
47
50
|
:href="frontmatter.url"
|
|
48
51
|
class="post-link-btn shadow hover:shadow-md"
|
|
49
52
|
rounded
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useSiteConfig } from 'valaxy'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/SubtleCrypto/deriveKey#pbkdf2_2
|
|
5
|
+
* @param password
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export function getKeyMaterial(password: string) {
|
|
9
|
+
const enc = new TextEncoder()
|
|
10
|
+
return window.crypto.subtle.importKey(
|
|
11
|
+
'raw',
|
|
12
|
+
enc.encode(password),
|
|
13
|
+
'PBKDF2',
|
|
14
|
+
false,
|
|
15
|
+
['deriveBits', 'deriveKey'],
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getKey(keyMaterial: CryptoKey, salt: Uint8Array) {
|
|
20
|
+
return window.crypto.subtle.deriveKey(
|
|
21
|
+
{
|
|
22
|
+
name: 'PBKDF2',
|
|
23
|
+
salt,
|
|
24
|
+
iterations: 100000,
|
|
25
|
+
hash: 'SHA-256',
|
|
26
|
+
},
|
|
27
|
+
keyMaterial,
|
|
28
|
+
{
|
|
29
|
+
name: 'AES-CBC',
|
|
30
|
+
length: 256,
|
|
31
|
+
},
|
|
32
|
+
true,
|
|
33
|
+
['encrypt', 'decrypt'],
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function useDecrypt() {
|
|
38
|
+
const siteConfig = useSiteConfig()
|
|
39
|
+
|
|
40
|
+
const { encrypt } = siteConfig.value
|
|
41
|
+
const iv = Uint8Array.from(Object.values(encrypt.iv))
|
|
42
|
+
const salt = Uint8Array.from(Object.values(encrypt.salt))
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
decrypt: async (password: string, ciphertext: string) => {
|
|
46
|
+
if (!password)
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
const keyMaterial = await getKeyMaterial(password)
|
|
50
|
+
const key = await getKey(keyMaterial, salt)
|
|
51
|
+
|
|
52
|
+
const ciphertextData = Uint8Array.from(ciphertext, c => c.charCodeAt(0))
|
|
53
|
+
|
|
54
|
+
const decrypted = await window.crypto.subtle.decrypt(
|
|
55
|
+
{
|
|
56
|
+
name: 'AES-CBC',
|
|
57
|
+
iv,
|
|
58
|
+
},
|
|
59
|
+
key,
|
|
60
|
+
ciphertextData,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return new TextDecoder().decode(decrypted)
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
}
|
package/client/main.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { ViteSSG } from 'vite-ssg'
|
|
|
2
2
|
import generatedRoutes from 'virtual:generated-pages'
|
|
3
3
|
import { setupLayouts } from 'virtual:generated-layouts'
|
|
4
4
|
import App from './App.vue'
|
|
5
|
+
import AppLinkVue from './components/AppLink.vue'
|
|
5
6
|
|
|
6
7
|
import '@unocss/reset/tailwind.css'
|
|
7
8
|
|
|
@@ -31,6 +32,7 @@ export const createApp = ViteSSG(
|
|
|
31
32
|
},
|
|
32
33
|
},
|
|
33
34
|
(ctx) => {
|
|
35
|
+
ctx.app.component('AppLink', AppLinkVue)
|
|
34
36
|
setupMain(ctx)
|
|
35
37
|
},
|
|
36
38
|
)
|