mirror of
https://github.com/langgenius/dify.git
synced 2026-04-15 09:57:03 +08:00
feat(web): add ALLOW_INLINE_STYLES env var to opt-in inline CSS in Markdown rendering (#34719)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
546062d2cd
commit
0e0bb3582f
@ -1176,6 +1176,11 @@ TEXT_GENERATION_TIMEOUT_MS=60000
|
||||
# Enable the experimental vinext runtime shipped in the image.
|
||||
EXPERIMENTAL_ENABLE_VINEXT=false
|
||||
|
||||
# Allow inline style attributes in Markdown rendering.
|
||||
# Enable this if your workflows use Jinja2 templates with styled HTML.
|
||||
# Only recommended for self-hosted deployments with trusted content.
|
||||
ALLOW_INLINE_STYLES=false
|
||||
|
||||
# Allow rendering unsafe URLs which have "data:" scheme.
|
||||
ALLOW_UNSAFE_DATA_SCHEME=false
|
||||
|
||||
|
||||
@ -165,6 +165,7 @@ services:
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
||||
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
||||
ALLOW_INLINE_STYLES: ${ALLOW_INLINE_STYLES:-false}
|
||||
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||
|
||||
@ -510,6 +510,7 @@ x-shared-env: &shared-api-worker-env
|
||||
MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-99}
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
EXPERIMENTAL_ENABLE_VINEXT: ${EXPERIMENTAL_ENABLE_VINEXT:-false}
|
||||
ALLOW_INLINE_STYLES: ${ALLOW_INLINE_STYLES:-false}
|
||||
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
MAX_TREE_DEPTH: ${MAX_TREE_DEPTH:-50}
|
||||
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
|
||||
@ -875,6 +876,7 @@ services:
|
||||
TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
|
||||
CSP_WHITELIST: ${CSP_WHITELIST:-}
|
||||
ALLOW_EMBED: ${ALLOW_EMBED:-false}
|
||||
ALLOW_INLINE_STYLES: ${ALLOW_INLINE_STYLES:-false}
|
||||
ALLOW_UNSAFE_DATA_SCHEME: ${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
|
||||
MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
|
||||
|
||||
@ -48,6 +48,9 @@ NEXT_PUBLIC_CSP_WHITELIST=
|
||||
# Default is not allow to embed into iframe to prevent Clickjacking: https://owasp.org/www-community/attacks/Clickjacking
|
||||
NEXT_PUBLIC_ALLOW_EMBED=
|
||||
|
||||
# Allow inline style attributes in Markdown rendering (self-hosted opt-in).
|
||||
NEXT_PUBLIC_ALLOW_INLINE_STYLES=false
|
||||
|
||||
# Allow rendering unsafe URLs which have "data:" scheme.
|
||||
NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME=false
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
ThinkBlock,
|
||||
VideoBlock,
|
||||
} from '@/app/components/base/markdown-blocks'
|
||||
import { ENABLE_SINGLE_DOLLAR_LATEX } from '@/config'
|
||||
import { ALLOW_INLINE_STYLES, ENABLE_SINGLE_DOLLAR_LATEX } from '@/config'
|
||||
import dynamic from '@/next/dynamic'
|
||||
import { customUrlTransform } from './markdown-utils'
|
||||
import 'katex/dist/katex.min.css'
|
||||
@ -118,6 +118,11 @@ function buildRehypePlugins(extraPlugins?: PluggableList): PluggableList {
|
||||
// component validates names with `isSafeName()`, so remove it.
|
||||
const clobber = (defaultSanitizeSchema.clobber ?? []).filter(k => k !== 'name')
|
||||
|
||||
if (ALLOW_INLINE_STYLES) {
|
||||
const globalAttrs = mergedAttributes['*'] ?? []
|
||||
mergedAttributes['*'] = [...globalAttrs, 'style']
|
||||
}
|
||||
|
||||
const customSchema: SanitizeSchema = {
|
||||
...defaultSanitizeSchema,
|
||||
tagNames: [...tagNamesSet],
|
||||
|
||||
@ -304,6 +304,7 @@ export const LOOP_NODE_MAX_COUNT = env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT
|
||||
export const MAX_ITERATIONS_NUM = env.NEXT_PUBLIC_MAX_ITERATIONS_NUM
|
||||
export const MAX_TREE_DEPTH = env.NEXT_PUBLIC_MAX_TREE_DEPTH
|
||||
|
||||
export const ALLOW_INLINE_STYLES = env.NEXT_PUBLIC_ALLOW_INLINE_STYLES
|
||||
export const ALLOW_UNSAFE_DATA_SCHEME = env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME
|
||||
export const ENABLE_WEBSITE_JINAREADER = env.NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER
|
||||
export const ENABLE_WEBSITE_FIRECRAWL = env.NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL
|
||||
|
||||
@ -30,6 +30,7 @@ export NEXT_PUBLIC_AMPLITUDE_API_KEY=${AMPLITUDE_API_KEY}
|
||||
export NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS=${TEXT_GENERATION_TIMEOUT_MS}
|
||||
export NEXT_PUBLIC_CSP_WHITELIST=${CSP_WHITELIST}
|
||||
export NEXT_PUBLIC_ALLOW_EMBED=${ALLOW_EMBED}
|
||||
export NEXT_PUBLIC_ALLOW_INLINE_STYLES=${ALLOW_INLINE_STYLES:-false}
|
||||
export NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME=${ALLOW_UNSAFE_DATA_SCHEME:-false}
|
||||
export NEXT_PUBLIC_TOP_K_MAX_VALUE=${TOP_K_MAX_VALUE}
|
||||
export NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH}
|
||||
|
||||
@ -19,6 +19,11 @@ const clientSchema = {
|
||||
* Default is not allow to embed into iframe to prevent Clickjacking: https://owasp.org/www-community/attacks/Clickjacking
|
||||
*/
|
||||
NEXT_PUBLIC_ALLOW_EMBED: coercedBoolean.default(false),
|
||||
/**
|
||||
* Allow inline style attributes in Markdown rendering.
|
||||
* Self-hosted opt-in for workflows using styled Jinja2 templates.
|
||||
*/
|
||||
NEXT_PUBLIC_ALLOW_INLINE_STYLES: coercedBoolean.default(false),
|
||||
/**
|
||||
* Allow rendering unsafe URLs which have "data:" scheme.
|
||||
*/
|
||||
@ -153,6 +158,7 @@ export const env = createEnv({
|
||||
client: clientSchema,
|
||||
experimental__runtimeEnv: {
|
||||
NEXT_PUBLIC_ALLOW_EMBED: isServer ? process.env.NEXT_PUBLIC_ALLOW_EMBED : getRuntimeEnvFromBody('allowEmbed'),
|
||||
NEXT_PUBLIC_ALLOW_INLINE_STYLES: isServer ? process.env.NEXT_PUBLIC_ALLOW_INLINE_STYLES : getRuntimeEnvFromBody('allowInlineStyles'),
|
||||
NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME: isServer ? process.env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME : getRuntimeEnvFromBody('allowUnsafeDataScheme'),
|
||||
NEXT_PUBLIC_AMPLITUDE_API_KEY: isServer ? process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY : getRuntimeEnvFromBody('amplitudeApiKey'),
|
||||
NEXT_PUBLIC_API_PREFIX: isServer ? process.env.NEXT_PUBLIC_API_PREFIX : getRuntimeEnvFromBody('apiPrefix'),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user