feat(messages): auto-linkify URLs in message content
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
URLs in messages are now automatically converted to clickable links opening in a new tab. Works for both old plain-text and new Quill HTML messages. Uses linkify Jinja2 filter that only processes text nodes outside existing <a>/<img> tags. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
73d9de8c9c
commit
b8f18c94e5
4
app.py
4
app.py
@ -225,6 +225,10 @@ def ensure_url_filter(url):
|
||||
return f'https://{url}'
|
||||
return url
|
||||
|
||||
# Register linkify filter for messages
|
||||
from utils.helpers import linkify_urls
|
||||
app.jinja_env.filters['linkify'] = linkify_urls
|
||||
|
||||
# Register forum markdown filter
|
||||
from utils.markdown import register_markdown_filter
|
||||
register_markdown_filter(app)
|
||||
|
||||
@ -450,7 +450,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="thread-msg-body">{{ msg.content|safe }}</div>
|
||||
<div class="thread-msg-body">{{ msg.content|linkify }}</div>
|
||||
{% if msg.attachments %}
|
||||
<div class="attachments-section" style="margin: 0 var(--spacing-md) var(--spacing-sm); padding-top: var(--spacing-sm);">
|
||||
{% for att in msg.attachments %}
|
||||
@ -510,7 +510,7 @@
|
||||
</div>
|
||||
|
||||
<div class="message-card-body">
|
||||
<div class="message-body">{{ message.content|safe }}</div>
|
||||
<div class="message-body">{{ message.content|linkify }}</div>
|
||||
|
||||
{% if message.attachments %}
|
||||
<div class="attachments-section">
|
||||
|
||||
@ -33,6 +33,59 @@ def sanitize_html(content):
|
||||
return bleach.clean(content, tags=_ALLOWED_TAGS, attributes=_ALLOWED_ATTRS, strip=True)
|
||||
|
||||
|
||||
def linkify_urls(html):
|
||||
"""
|
||||
Auto-link URLs in HTML content that are not already inside <a> or <img> tags.
|
||||
Links to nordabiznes.pl open in new tab as trusted internal links.
|
||||
"""
|
||||
if not html:
|
||||
return html
|
||||
|
||||
from markupsafe import Markup
|
||||
|
||||
# Split HTML into tags and text, only process text outside <a>/<img> tags
|
||||
url_pattern = re.compile(r'(https?://[^\s<>"\']+)')
|
||||
tag_pattern = re.compile(r'<(/?)(\w+)([^>]*)>')
|
||||
|
||||
result = []
|
||||
pos = 0
|
||||
in_a_tag = False
|
||||
|
||||
for match in tag_pattern.finditer(html):
|
||||
start, end = match.start(), match.end()
|
||||
is_closing = match.group(1) == '/'
|
||||
tag_name = match.group(2).lower()
|
||||
|
||||
# Process text before this tag
|
||||
if start > pos:
|
||||
text_chunk = html[pos:start]
|
||||
if in_a_tag:
|
||||
result.append(text_chunk)
|
||||
else:
|
||||
result.append(url_pattern.sub(
|
||||
lambda m: '<a href="{0}" target="_blank" style="color:var(--primary);word-break:break-all;">{0}</a>'.format(m.group(0)),
|
||||
text_chunk
|
||||
))
|
||||
|
||||
result.append(match.group(0))
|
||||
pos = end
|
||||
|
||||
if tag_name in ('a', 'img'):
|
||||
in_a_tag = not is_closing
|
||||
|
||||
# Process remaining text
|
||||
if pos < len(html):
|
||||
text_chunk = html[pos:]
|
||||
if not in_a_tag:
|
||||
text_chunk = url_pattern.sub(
|
||||
lambda m: '<a href="{0}" target="_blank" style="color:var(--primary);word-break:break-all;">{0}</a>'.format(m.group(0)),
|
||||
text_chunk
|
||||
)
|
||||
result.append(text_chunk)
|
||||
|
||||
return Markup(''.join(result))
|
||||
|
||||
|
||||
def sanitize_input(text, max_length=1000):
|
||||
"""
|
||||
Sanitize user input - remove potentially dangerous characters.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user