Display private images in WYSIWYG editor (#7583)

* image is displaying in WYSIWYG

* remove access token before deletion

* remove token is being returned

* preview image displaying correctly

* added image token props handling

* imageToken added as params correctly

* refactor

* Fix regex, fix life's problems

* Remove eslint disable

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
Jay Cammarano
2021-08-24 18:55:51 -04:00
committed by GitHub
parent c208c74fcf
commit db9020b378
4 changed files with 37 additions and 6 deletions

View File

@@ -95,7 +95,7 @@ api.interceptors.response.use(onResponse, onError);
export default api;
function getToken() {
export function getToken() {
return api.defaults.headers?.['Authorization']?.split(' ')[1] || null;
}

View File

@@ -100,10 +100,8 @@ export default defineComponent({
if (image.value.type.includes('svg')) {
return addTokenToURL(getRootPath() + `assets/${image.value.id}`);
}
if (image.value.type.includes('image')) {
const url = getRootPath() + `assets/${image.value.id}?key=system-large-cover&cache-buster=${cacheBuster.value}`;
return addTokenToURL(url);
}

View File

@@ -59,7 +59,7 @@
<v-drawer v-model="imageDrawerOpen" :title="t('wysiwyg_options.image')" icon="image" @cancel="closeImageDrawer">
<div class="content">
<template v-if="imageSelection">
<img class="image-preview" :src="imageSelection.imageUrl" />
<img class="image-preview" :src="imageSelection.previewUrl" />
<div class="grid">
<div class="field half">
<div class="type-label">{{ t('image_url') }}</div>
@@ -166,11 +166,13 @@ import 'tinymce/icons/default';
import Editor from '@tinymce/tinymce-vue';
import getEditorStyles from './get-editor-styles';
import { escapeRegExp } from 'lodash';
import useImage from './useImage';
import useMedia from './useMedia';
import useLink from './useLink';
import useSourceCode from './useSourceCode';
import { getToken } from '@/api';
import { getPublicURL } from '@/utils/get-root-path';
type CustomFormat = {
title: string;
@@ -260,13 +262,41 @@ export default defineComponent({
const { codeDrawerOpen, code, closeCodeDrawer, saveCode, sourceCodeButton } = useSourceCode(editorRef);
const replaceTokens = (value: string, token: string | null) => {
const url = getPublicURL();
const regex = new RegExp(
`(<[^=]+=")(${escapeRegExp(
url
)}assets/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(?:\\??[^#"]+)?(?:#[^"]*)?)("[^>]*>)`,
'gi'
);
return value.replace(regex, (_, pre, matchedUrl, post) => {
const matched = new URL(matchedUrl);
const params = new URLSearchParams(matched.search);
if (!token) {
params.delete('access_token');
} else {
params.set('access_token', token);
}
return `${pre}${matched.origin}${matched.pathname}?${params.toString()}${post}`;
});
};
const internalValue = computed({
get() {
if (props.value) {
return replaceTokens(props.value, getToken());
}
return props.value;
},
set(newValue: string) {
if (newValue !== props.value && (props.value === null && newValue === '') === false) {
emit('input', newValue);
const removeToken = replaceTokens(newValue, props.imageToken ?? null);
emit('input', removeToken);
}
},
});

View File

@@ -8,6 +8,7 @@ type ImageSelection = {
alt: string;
width?: number;
height?: number;
previewUrl?: string;
};
type ImageButton = {
@@ -50,6 +51,7 @@ export default function useImage(editor: Ref<any>, imageToken: Ref<string | unde
alt,
width: Number(node.getAttribute('width')) || undefined,
height: Number(node.getAttribute('height')) || undefined,
previewUrl: addTokenToURL(imageUrl),
};
} else {
imageSelection.value = null;
@@ -87,6 +89,7 @@ export default function useImage(editor: Ref<any>, imageToken: Ref<string | unde
alt: image.title,
width: image.width,
height: image.height,
previewUrl: addTokenToURL(imageUrl),
};
}