Feature: webdav picbed now support digest auth

This commit is contained in:
萌萌哒赫萝
2023-09-12 19:27:59 -07:00
parent 09a636f414
commit 2e655a4ebd
15 changed files with 408 additions and 94 deletions

View File

@@ -23,6 +23,8 @@
import { ref, onMounted, watch, computed } from 'vue'
import { getFileIconPath } from '@/manage/utils/common'
import { Loading } from '@element-plus/icons-vue'
import { getAuthHeader } from '@/manage/utils/digestAuth'
import { formatEndpoint } from '~/main/manage/utils/common'
const base64Url = ref('')
const success = ref(false)
@@ -41,7 +43,7 @@ const props = defineProps(
type: String,
required: true
},
headers: {
config: {
type: Object,
required: true
}
@@ -56,9 +58,31 @@ const imageSource = computed(() => {
const iconPath = computed(() => require(`../manage/pages/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`))
async function getheaderOfWebdav (key: string) {
let headers = {} as any
if (props.config.authType === 'digest') {
const authHeader = await getAuthHeader(
'GET',
formatEndpoint(props.config.endpoint, props.config.sslEnabled || false),
`/${key.replace(/^\//, '')}`,
props.config.username,
props.config.password
)
headers = {
Authorization: authHeader
}
} else {
headers = {
Authorization: 'Basic ' + Buffer.from(`${props.config.username}:${props.config.password}`).toString('base64')
}
}
return headers
}
const fetchImage = async () => {
try {
const res = await fetch(props.url, { method: 'GET', headers: props.headers })
const headers = await getheaderOfWebdav(props.item.key)
const res = await fetch(props.url, { method: 'GET', headers })
if (res.status >= 200 && res.status < 300) {
const blob = await res.blob()
success.value = true
@@ -72,7 +96,7 @@ const fetchImage = async () => {
}
}
watch(() => [props.url, props.headers], fetchImage, { deep: true })
watch(() => [props.url, props.item], fetchImage, { deep: true })
onMounted(fetchImage)

View File

@@ -0,0 +1,102 @@
import { defineComponent, ref, onMounted, watch, computed } from 'vue'
import { getFileIconPath } from '@/manage/utils/common'
import { Loading } from '@element-plus/icons-vue'
import { getAuthHeader } from '@/manage/utils/digestAuth'
import { formatEndpoint } from '~/main/manage/utils/common'
import { ElImage, ElIcon } from 'element-plus'
export default defineComponent({
props: {
isShowThumbnail: {
type: Boolean,
required: true
},
item: {
type: Object,
required: true
},
url: {
type: String,
required: true
},
config: {
type: Object,
required: true
}
},
setup (props) {
const base64Url = ref('')
const success = ref(false)
const imageSource = computed(() => {
return (props.isShowThumbnail && props.item.isImage && success.value)
? base64Url.value
: require(`../manage/pages/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
})
const iconPath = computed(() => require(`../manage/pages/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`))
async function getheaderOfWebdav (key: string) {
let headers = {} as any
if (props.config.authType === 'digest') {
const authHeader = await getAuthHeader(
'GET',
formatEndpoint(props.config.endpoint, props.config.sslEnabled || false),
`/${key.replace(/^\//, '')}`,
props.config.username,
props.config.password
)
headers = {
Authorization: authHeader
}
} else {
headers = {
Authorization: 'Basic ' + Buffer.from(`${props.config.username}:${props.config.password}`).toString('base64')
}
}
return headers
}
const fetchImage = async () => {
try {
const headers = await getheaderOfWebdav(props.item.key)
const res = await fetch(props.url, { method: 'GET', headers })
if (res.status >= 200 && res.status < 300) {
const blob = await res.blob()
success.value = true
base64Url.value = URL.createObjectURL(blob)
} else {
throw new Error('Network response was not ok.')
}
} catch (err) {
success.value = false
console.log(err)
}
}
watch(() => [props.url, props.item], fetchImage, { deep: true })
onMounted(fetchImage)
return () => (
<ElImage
src={imageSource.value}
fit="contain"
style="height: 100px;width: 100%;margin: 0 auto;"
>
{{
placeholder: () => (
<ElIcon>
<Loading />
</ElIcon>
),
error: () => (
<ElImage
src={iconPath.value}
fit="contain"
style="height: 100px;width: 100%;margin: 0 auto;"
/>
)
}}
</ElImage>
)
}
})