Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 67 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,46 @@
<template>
<router-view></router-view>
<div class="app-shell">
<Banner
v-if="!isLoginPage && bannerConfig && bannerConfig.activateBanner"
:key="bannerInstanceKey"
class="app-banner"
:dismissable="bannerConfig.makeBannerDismissable"
:color-scheme="bannerConfig.colorScheme"
:message="bannerConfig.message"
:custom-mode="bannerConfig.customMode"
:html="bannerConfig.html"
/>
<main class="app-content">
<router-view />
</main>
</div>
</template>

<script>
// bootstrap-table still relies on jQuery for ajax calls, even though there's a supported Vue wrapper for it.
import $ from 'jquery';
import { getUrlVar } from './shared/utils';
import { getToken } from './shared/permissions';
import EventBus from './shared/eventbus';
import VueRouter from 'vue-router';
import Banner from './views/components/Banner.vue';

export default {
name: 'app',
components: {
Banner,
},
data() {
return {
bannerConfig: null,
bannerInstanceKey: 0,
};
},
computed: {
isLoginPage() {
const loginRoutes = ['/login'];
return loginRoutes.includes(this.$route.path);
},
},
created() {
const setJwtForAjax = (jwt) => {
if (jwt) {
Expand All @@ -24,21 +53,42 @@
};

EventBus.$on('authenticated', (jwt) => {
sessionStorage.removeItem('banner-dismissed');
if (jwt) {
sessionStorage.setItem('token', jwt);
} else {
sessionStorage.removeItem('token');
}
setJwtForAjax(jwt);

if (jwt) {
this.fetchBannerConfig();
} else {
this.bannerConfig = null;
this.bannerInstanceKey++;
}
});

EventBus.$on('banner-updated', async () => {
sessionStorage.removeItem('banner-dismissed');
await this.fetchBannerConfig();
this.bannerInstanceKey++;
});

// ensure $.ajaxSettings.headers exists
$.ajaxSetup({
headers: {},
});

const token = getToken();
setJwtForAjax(getToken());

if (token) {
this.fetchBannerConfig();
} else {
this.bannerConfig = null;
}

// Send XHR cross-site cookie credentials
if (this.$api.WITH_CREDENTIALS) {
this.axios.interceptors.request.use(function (config) {
Expand Down Expand Up @@ -84,7 +134,7 @@
error.response.headers['content-type'] === 'application/json' &&
error.response.data &&
Array.isArray(error.response.data) &&
error.response.data[0].hasOwnProperty('invalidValue')

Check failure on line 137 in src/App.vue

View workflow job for this annotation

GitHub Actions / lint

Do not access Object.prototype method 'hasOwnProperty' from target object
) {
let validationError = error.response.data
.map((failure) => `${failure.path}: ${failure.message}`)
Expand Down Expand Up @@ -164,6 +214,17 @@
}
});
},
methods: {
async fetchBannerConfig() {
try {
const response = await this.axios.get(this.$api.URL_BANNER);
this.bannerConfig = response.data || null;
} catch (e) {
console.error('Failed to load banner config:', e);
this.bannerConfig = null;
}
},
},
};
</script>

Expand All @@ -175,4 +236,8 @@
@import '~simple-line-icons/scss/simple-line-icons.scss';
@import '~bootstrap-vue/dist/bootstrap-vue.css';
@import 'assets/scss/style';

.app-content {
padding-top: var(--banner-offset, 0px);
}
</style>
9 changes: 9 additions & 0 deletions src/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "API-Schlüssel",
"api_token": "API-Token",
"api_token_header": "Header des API-Tokens",
"banner_activate": "Banner aktivieren",
"banner_color_scheme": "Farbschema",
"banner_custom_mode": "Benutzerdefiniertes HTML",
"banner_dismissable": "Per Klick schließen",
"banner_enable_custom": "Aktivieren",
"banner_explanation": "Konfigurieren Sie ein Banner, das über der Seite angezeigt wird.",
"banner_explanation_html_text": "Formatieren Sie Ihre Bannerbotschaft und Ihr Erscheinungsbild mithilfe von HTML-Tags.",
"banner_html_text": "HTML-Text",
"banner_message": "Nachricht",
"base_url": "Basis-URL",
"bearer_token_auth_enable": "Authentifizieren mit einem persönlichen Zugriffstoken",
"bom_formats": "BOM-Formate",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "API Keys",
"api_token": "API token",
"api_token_header": "API token header",
"banner_activate": "Activate banner",
"banner_color_scheme": "Color scheme",
"banner_custom_mode": "Custom HTML",
"banner_dismissable": "Dismissable",
"banner_enable_custom": "Enable",
"banner_explanation": "Configure a banner which is shown above the page.",
"banner_explanation_html_text": "Format your banner message and appearance using HTML tags.",
"banner_html_text": "HTML text",
"banner_message": "Message",
"base_url": "Base URL",
"bearer_token_auth_enable": "Authenticate with a personal access token",
"bom_formats": "BOM Formats",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Claves API",
"api_token": "Token API",
"api_token_header": "Cabecera de la clave API",
"banner_activate": "Activar banner",
"banner_color_scheme": "esquema de color",
"banner_custom_mode": "HTML personalizado",
"banner_dismissable": "Desestimable",
"banner_enable_custom": "Permitir",
"banner_explanation": "Configure un banner que se muestra encima de la página.",
"banner_explanation_html_text": "Formatee el mensaje y la apariencia de su banner usando etiquetas HTML.",
"banner_html_text": "texto HTML",
"banner_message": "Mensaje",
"base_url": "URL base",
"bearer_token_auth_enable": "Autenticarse con un token de acceso personal",
"bom_formats": "Formatos de lista de materiales",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Clés d'API",
"api_token": "Jeton d'API",
"api_token_header": "Entête du jeton d'API",
"banner_activate": "Activer la bannière",
"banner_color_scheme": "Jeu de couleurs",
"banner_custom_mode": "HTML personnalisé",
"banner_dismissable": "Licenciable",
"banner_enable_custom": "Activer",
"banner_explanation": "Configurez une bannière qui s'affiche au-dessus de la page.",
"banner_explanation_html_text": "Formatez votre message de bannière et votre apparence à l'aide de balises HTML.",
"banner_html_text": "Texte HTML",
"banner_message": "Message",
"base_url": "URL de base",
"bearer_token_auth_enable": "S'authentifier avec un jeton d'accès personnel",
"bom_formats": "Formats de nomenclature (BOM)",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "एपीआई कुंजियाँ",
"api_token": "एपीआई टोकन",
"api_token_header": "api_token_header",
"banner_activate": "बैनर सक्रिय करें",
"banner_color_scheme": "रंग योजना",
"banner_custom_mode": "कस्टम HTML",
"banner_dismissable": "खारिज करने योग्य",
"banner_enable_custom": "सक्षम",
"banner_explanation": "एक बैनर कॉन्फ़िगर करें जो पृष्ठ के ऊपर दिखाया गया है।",
"banner_explanation_html_text": "HTML टैग का उपयोग करके अपने बैनर संदेश और स्वरूप को प्रारूपित करें।",
"banner_html_text": "HTML पाठ",
"banner_message": "संदेश",
"base_url": "आधार यूआरएल",
"bearer_token_auth_enable": "व्यक्तिगत एक्सेस टोकन से प्रमाणीकरण करें",
"bom_formats": "बीओएम प्रारूप",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Chiavi API",
"api_token": "Token API",
"api_token_header": "api_token_header",
"banner_activate": "Attiva il banner",
"banner_color_scheme": "Combinazione di colori",
"banner_custom_mode": "HTML personalizzato",
"banner_dismissable": "Ignorabile",
"banner_enable_custom": "Abilitare",
"banner_explanation": "Configura un banner che viene mostrato sopra la pagina.",
"banner_explanation_html_text": "Formatta il messaggio e l'aspetto del banner utilizzando i tag HTML.",
"banner_html_text": "Testo HTML",
"banner_message": "Messaggio",
"base_url": "URL di base",
"bearer_token_auth_enable": "Autenticarsi con un token di accesso personale",
"bom_formats": "Formati distinta base",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "APIキー",
"api_token": "APIトークン",
"api_token_header": "api_token_header",
"banner_activate": "バナーをアクティブにする",
"banner_color_scheme": "配色",
"banner_custom_mode": "カスタムHTML",
"banner_dismissable": "却下可能",
"banner_enable_custom": "有効にする",
"banner_explanation": "ページ上部に表示されるバナーを設定します。",
"banner_explanation_html_text": "HTML タグを使用して、バナー メッセージと外観をフォーマットします。",
"banner_html_text": "HTMLテキスト",
"banner_message": "メッセージ",
"base_url": "ベースURL",
"bearer_token_auth_enable": "パーソナルアクセストークンで認証する",
"bom_formats": "BOM 形式",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Klucze API",
"api_token": "Token API",
"api_token_header": "api_token_header",
"banner_activate": "Aktywuj baner",
"banner_color_scheme": "Schemat kolorów",
"banner_custom_mode": "Niestandardowy kod HTML",
"banner_dismissable": "Do odrzucenia",
"banner_enable_custom": "Włączać",
"banner_explanation": "Skonfiguruj baner wyświetlany nad stroną.",
"banner_explanation_html_text": "Sformatuj treść i wygląd banera za pomocą tagów HTML.",
"banner_html_text": "Tekst HTML",
"banner_message": "Wiadomość",
"base_url": "Bazowy adres URL",
"bearer_token_auth_enable": "Uwierzytelnij się za pomocą osobistego tokena dostępu",
"bom_formats": "Formaty BOM-ów",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Chaves de API",
"api_token": "Token de API",
"api_token_header": "api_token_header",
"banner_activate": "Ativar banner",
"banner_color_scheme": "Esquema de cores",
"banner_custom_mode": "HTML personalizado",
"banner_dismissable": "Dispensável",
"banner_enable_custom": "Habilitar",
"banner_explanation": "Configure um banner que é mostrado acima da página.",
"banner_explanation_html_text": "Formate a mensagem e a aparência do seu banner usando tags HTML.",
"banner_html_text": "Texto HTML",
"banner_message": "Mensagem",
"base_url": "URL base",
"bearer_token_auth_enable": "Autenticar com um token de acesso pessoal",
"bom_formats": "Formatos de lista de materiais",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Chaves de API",
"api_token": "Token de API",
"api_token_header": "api_token_header",
"banner_activate": "Ativar banner",
"banner_color_scheme": "Esquema de cores",
"banner_custom_mode": "HTML personalizado",
"banner_dismissable": "Dispensável",
"banner_enable_custom": "Habilitar",
"banner_explanation": "Configure um banner que é mostrado acima da página.",
"banner_explanation_html_text": "Formate a mensagem e a aparência do seu banner usando tags HTML.",
"banner_html_text": "Texto HTML",
"banner_message": "Mensagem",
"base_url": "URL base",
"bearer_token_auth_enable": "Autenticar com um token de acesso pessoal",
"bom_formats": "Formatos de lista de materiais",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Ключи API",
"api_token": "Токен API",
"api_token_header": "Заголовок токена API",
"banner_activate": "Активировать баннер",
"banner_color_scheme": "Цветовая гамма",
"banner_custom_mode": "Пользовательский HTML",
"banner_dismissable": "Увольняемый",
"banner_enable_custom": "Давать возможность",
"banner_explanation": "Настройте баннер, который отображается над страницей.",
"banner_explanation_html_text": "Отформатируйте сообщение и внешний вид баннера с помощью HTML-тегов.",
"banner_html_text": "HTML-текст",
"banner_message": "Сообщение",
"base_url": "Базовый URL",
"bearer_token_auth_enable": "Аутентификация с помощью токена доступа",
"bom_formats": "Форматы BOM",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/uk-UA.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "Ключі API",
"api_token": "Токен API",
"api_token_header": "Заголовок токена API",
"banner_activate": "Активувати банер",
"banner_color_scheme": "Колірна гамма",
"banner_custom_mode": "Спеціальний HTML",
"banner_dismissable": "Можна відкинути",
"banner_enable_custom": "Увімкнути",
"banner_explanation": "Налаштуйте банер, який буде показано над сторінкою.",
"banner_explanation_html_text": "Відформатуйте повідомлення та вигляд банера за допомогою тегів HTML.",
"banner_html_text": "текст HTML",
"banner_message": "повідомлення",
"base_url": "Базова URL-адреса",
"bearer_token_auth_enable": "Автентифікація за допомогою персонального токена доступу",
"bom_formats": "Формати BOM",
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
"api_keys": "API 密钥",
"api_token": "API 令牌",
"api_token_header": "API Token Header",
"banner_activate": "激活横幅",
"banner_color_scheme": "配色方案",
"banner_custom_mode": "自定义 HTML",
"banner_dismissable": "可驳回",
"banner_enable_custom": "使能够",
"banner_explanation": "配置显示在页面上方的横幅。",
"banner_explanation_html_text": "使用 HTML 标签设置横幅消息和外观的格式。",
"banner_html_text": "HTML 文本",
"banner_message": "信息",
"base_url": "基本 URL",
"bearer_token_auth_enable": "使用个人访问令牌进行身份验证",
"bom_formats": "BOM 格式",
Expand Down
13 changes: 13 additions & 0 deletions src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import('@/views/administration/configuration/BomFormats');
const WelcomeMessage = () =>
import('@/views/administration/configuration/WelcomeMessage');
const Banner = () =>
import('@/views/administration/configuration/BannerConfigurationModal');
const Email = () => import('@/views/administration/configuration/Email');
const Jira = () => import('@/views/administration/configuration/JiraConfig');
const InternalComponents = () =>
Expand Down Expand Up @@ -398,6 +400,17 @@
permission: 'SYSTEM_CONFIGURATION',
},
},
{
path: 'configuration/banner',
component: Banner,
meta: {
title: i18n.t('message.administration'),
i18n: 'message.administration',
sectionPath: '/admin',
sectionName: 'Admin',
permission: 'SYSTEM_CONFIGURATION',
},
},
{
path: 'configuration/email',
component: Email,
Expand Down Expand Up @@ -869,7 +882,7 @@
path: 'project',
props: (route) => ({ uuid: route.query.uuid }),
redirect: (to) => {
let { hash, params, query } = to;

Check failure on line 885 in src/router/index.js

View workflow job for this annotation

GitHub Actions / lint

'params' is assigned a value but never used

Check failure on line 885 in src/router/index.js

View workflow job for this annotation

GitHub Actions / lint

'hash' is assigned a value but never used
if (query.uuid) {
let uuid = query.uuid;
return { path: '/projects/' + uuid, query: null };
Expand All @@ -882,7 +895,7 @@
path: 'component',
props: (route) => ({ uuid: route.query.uuid }),
redirect: (to) => {
let { hash, params, query } = to;

Check failure on line 898 in src/router/index.js

View workflow job for this annotation

GitHub Actions / lint

'hash' is assigned a value but never used
if (query.uuid) {
let uuid = query.uuid;
return { path: '/components/' + uuid, query: null };
Expand Down
1 change: 1 addition & 0 deletions src/shared/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"URL_ACL_MAPPING": "api/v1/acl/mapping",
"URL_ACL_TEAM": "api/v1/acl/team",
"URL_ANALYSIS": "api/v1/analysis",
"URL_BANNER": "api/v1/banner",
"URL_BOM": "api/v1/bom",
"URL_CALCULATOR_CVSS": "api/v1/calculator/cvss",
"URL_CALCULATOR_OWASP": "api/v1/calculator/owasp",
Expand Down
36 changes: 36 additions & 0 deletions src/shared/bannerColorSchemes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export const BANNER_SCHEMES = {
red: {
backgroundColor: '#e91640',
textColor: '#ffffff',
borderColor: '#bb1133',
name: 'Red Banner',
},
orange: {
backgroundColor: '#ff9933',
textColor: '#ffffff',
borderColor: '#be660dff',
name: 'Orange Banner',
},
green: {
backgroundColor: '#2eb82e',
textColor: '#ffffff',
borderColor: '#1f7a1f',
name: 'Green Banner',
},
blue: {
backgroundColor: '#4d88ff',
textColor: '#ffffff',
borderColor: '#003399',
name: 'Blue Banner',
},
lilac: {
backgroundColor: '#d699ff',
textColor: '#ffffff',
borderColor: '#a64dff',
name: 'Lilac Banner',
},
};

export function getBannerSchemes(presetName) {
return BANNER_SCHEMES[presetName] || BANNER_SCHEMES.green;
}
Loading
Loading