Files
api/web/components/FileViewer.vue
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

83 lines
2.3 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue';
import { useContentHighlighting } from '~/composables/useContentHighlighting';
const props = defineProps<{
content: string;
language?: string;
showLineNumbers?: boolean;
maxHeight?: string;
class?: string;
}>();
const { highlightContent } = useContentHighlighting();
const highlightedContent = computed(() => {
return highlightContent(props.content, props.language);
});
const lines = computed(() => {
return props.content.split('\n');
});
</script>
<template>
<div
:class="[
'file-viewer-container',
'relative rounded border bg-background text-foreground overflow-hidden',
props.class
]"
:style="{ height: maxHeight || '300px' }"
>
<div class="absolute inset-0 overflow-auto">
<div class="flex min-w-full">
<!-- Line numbers -->
<div
v-if="showLineNumbers"
class="flex-shrink-0 select-none border-r bg-muted/50 px-2 py-2 text-xs font-mono text-muted-foreground"
>
<div v-for="(_, index) in lines" :key="index" class="leading-5 text-right pr-2">
{{ index + 1 }}
</div>
</div>
<!-- Content -->
<div class="flex-1 min-w-0">
<pre
class="p-3 text-xs font-mono leading-5 whitespace-pre m-0"
v-html="highlightedContent"
/>
</div>
</div>
</div>
</div>
</template>
<style scoped>
/* Add some basic styling for the highlighted content */
:deep(.hljs) {
background: transparent;
}
/* ANSI color classes */
:deep(.ansi-bright-black) { color: #666; }
:deep(.ansi-bright-red) { color: #ff6b6b; }
:deep(.ansi-bright-green) { color: #51cf66; }
:deep(.ansi-bright-yellow) { color: #ffd43b; }
:deep(.ansi-bright-blue) { color: #339af0; }
:deep(.ansi-bright-magenta) { color: #f06292; }
:deep(.ansi-bright-cyan) { color: #22d3ee; }
:deep(.ansi-bright-white) { color: #f8f9fa; }
/* Standard ANSI colors for dark theme */
:deep(.ansi-black) { color: #000; }
:deep(.ansi-red) { color: #e03131; }
:deep(.ansi-green) { color: #2f9e44; }
:deep(.ansi-yellow) { color: #f59f00; }
:deep(.ansi-blue) { color: #1971c2; }
:deep(.ansi-magenta) { color: #c2255c; }
:deep(.ansi-cyan) { color: #0891b2; }
:deep(.ansi-white) { color: #495057; }
</style>