Files
api/web/composables/useContentHighlighting.ts
Eli Bosley 4e945f5f56 feat(api): enhance OIDC redirect URI handling in service and tests (#1618)
- Updated `getRedirectUri` method in `OidcAuthService` to handle various
edge cases for redirect URIs, including full URIs, malformed URLs, and
default ports.
- Added comprehensive tests for `OidcAuthService` to validate redirect
URI construction and error handling.
- Modified `RestController` to utilize `redirect_uri` query parameter
for authorization requests.
- Updated frontend components to include `redirect_uri` in authorization
URLs, ensuring correct handling of different protocols and ports.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Stronger OIDC redirect_uri validation and an admin GraphQL endpoint to
view full OIDC configuration.
* OIDC Debug Logs UI (panel, button, modal), enhanced log viewer with
presets/filters, ANSI-colored rendering, and a File Viewer component.
* New GraphQL queries to list and fetch config files; API Config
Download page.

* **Refactor**
* Centralized, modular OIDC flows and safer redirect handling;
topic-based log subscriptions with a watcher manager for scalable live
logs.

* **Documentation**
  * Cache TTL guidance clarified to use milliseconds.

* **Chores**
* Added ansi_up and escape-html deps; improved log formatting; added
root codegen script.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-09-02 10:40:20 -04:00

84 lines
2.9 KiB
TypeScript

import hljs from 'highlight.js/lib/core';
import DOMPurify from 'isomorphic-dompurify';
import { AnsiUp } from 'ansi_up';
import 'highlight.js/styles/github-dark.css';
import apache from 'highlight.js/lib/languages/apache';
import bash from 'highlight.js/lib/languages/bash';
import ini from 'highlight.js/lib/languages/ini';
import javascript from 'highlight.js/lib/languages/javascript';
import json from 'highlight.js/lib/languages/json';
import nginx from 'highlight.js/lib/languages/nginx';
import php from 'highlight.js/lib/languages/php';
import plaintext from 'highlight.js/lib/languages/plaintext';
import xml from 'highlight.js/lib/languages/xml';
import yaml from 'highlight.js/lib/languages/yaml';
// Register the languages (only once)
let languagesRegistered = false;
const registerLanguages = () => {
if (!languagesRegistered) {
hljs.registerLanguage('plaintext', plaintext);
hljs.registerLanguage('bash', bash);
hljs.registerLanguage('ini', ini);
hljs.registerLanguage('xml', xml);
hljs.registerLanguage('json', json);
hljs.registerLanguage('yaml', yaml);
hljs.registerLanguage('nginx', nginx);
hljs.registerLanguage('apache', apache);
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('php', php);
languagesRegistered = true;
}
};
export const useContentHighlighting = () => {
// Initialize ANSI to HTML converter with CSS classes
const ansiConverter = new AnsiUp();
ansiConverter.use_classes = true;
ansiConverter.escape_html = true;
// Register languages on first use
registerLanguages();
// Function to highlight content
const highlightContent = (content: string, language?: string): string => {
try {
let highlighted: string;
// Check if content contains ANSI escape sequences
// eslint-disable-next-line no-control-regex
const hasAnsiSequences = /\x1b\[/.test(content);
if (hasAnsiSequences) {
// Use ANSI converter for content with ANSI codes
highlighted = ansiConverter.ansi_to_html(content);
} else if (language) {
// Use highlight.js for specific language if provided
const result = hljs.highlight(content, { language, ignoreIllegals: true });
highlighted = result.value;
} else {
// Use highlight.js auto-detection for non-ANSI content
const result = hljs.highlightAuto(content);
highlighted = result.value;
}
// Sanitize the highlighted HTML while preserving class attributes for syntax highlighting
return DOMPurify.sanitize(highlighted, {
ALLOWED_TAGS: ['span', 'br', 'code', 'pre'],
ALLOWED_ATTR: ['class'] // Allow class attribute for hljs and ANSI color classes
});
} catch (error) {
console.error('Error highlighting content:', error);
// Fallback to sanitized but not highlighted content
return DOMPurify.sanitize(content);
}
};
return {
highlightContent
};
};