-
Notifications
You must be signed in to change notification settings - Fork 14
Frontend Overview
Related topics: Overall System Architecture
Relevant source files
The Harbinger frontend is a modern web application built with the Quasar framework, which is based on Vue.js. It provides a user-friendly interface for interacting with the Harbinger backend, allowing operators to manage playbooks, view data, and monitor C2 activities. The frontend is designed to be responsive and intuitive, with a clear separation of concerns between layout, pages, and routing.
- Quasar Framework: A high-performance Vue.js framework for building responsive websites, PWAs, SSR apps, mobile apps, and desktop apps.
- Vue.js: A progressive JavaScript framework for building user interfaces.
- TypeScript: A typed superset of JavaScript that compiles to plain JavaScript, enhancing code quality and maintainability.
- Axios: A promise-based HTTP client for making requests to the Harbinger backend API.
- Pinia: A state management library for Vue.js, used for managing application-level state.
The frontend source code is located in the harbinger/interface/ directory. Key subdirectories include:
-
src/: Contains the main application source code.-
layouts/: Defines the main layout components of the application. -
pages/: Contains the individual page components. -
router/: Manages the application's routing configuration. -
models.ts: Defines the TypeScript interfaces for data models used throughout the application. -
boot/: Contains Quasar boot files for initialization tasks, such as configuring Axios.
-
The main layout of the application is defined in harbinger/interface/src/layouts/MainLayout.vue. This component sets up the primary structure of the user interface, including the header, drawer (sidebar), and the main content area where pages are rendered.
<!-- harbinger/interface/src/layouts/MainLayout.vue -->
<template>
<q-layout view="lHh Lpr lFf">
<q-header elevated>
<q-toolbar>
<q-btn
flat
dense
round
icon="menu"
aria-label="Menu"
@click="toggleLeftDrawer"
/>
<q-toolbar-title>
Harbinger
</q-toolbar-title>
<div>v{{ version }}</div>
</q-toolbar>
</q-header>
<q-drawer
v-model="leftDrawerOpen"
show-if-above
bordered
>
<q-list>
<q-item-label
header
>
Essential Links
</q-item-label>
<EssentialLink
v-for="link in essentialLinks"
:key="link.title"
v-bind="link"
/>
</q-list>
</q-drawer>
<q-page-container>
<router-view />
</q-page-container>
</q-layout>
</template>Sources: harbinger/interface/src/layouts/MainLayout.vue:1-50
The layout includes a toggleable left drawer for navigation, a header with the application title, and a router-view component that displays the content of the current page based on the URL.
Application routes are defined in harbinger/interface/src/router/routes.ts. This file maps URL paths to specific Vue components.
// harbinger/interface/src/router/routes.ts
import { RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
},
{
path: '/:catchAll(.*)*',
component: () => import('pages/ErrorNotFound.vue'),
},
];
export default routes;Sources: harbinger/interface/src/router/routes.ts:1-15
The main route / loads the MainLayout and renders the IndexPage as its child component. A catch-all route is also defined to handle 404 errors.
The main landing page of the application is harbinger/interface/src/pages/IndexPage.vue. This page serves as the central dashboard for the user.
<!-- harbinger/interface/src/pages/IndexPage.vue -->
<template>
<q-page class="row items-center justify-evenly">
<example-component
title="Example component"
active
:todos="todos"
:meta="meta"
></example-component>
</q-page>
</template>Sources: harbinger/interface/src/pages/IndexPage.vue:1-11
This page currently displays an ExampleComponent with some sample data, which would be replaced by actual dashboard components in a full implementation.
The frontend uses TypeScript interfaces defined in harbinger/interface/src/models.ts to ensure type safety when working with data from the backend API. These models correspond to the Pydantic schemas used in the FastAPI backend.
Example of a Todo and Meta interface:
// harbinger/interface/src/models.ts
export interface Todo {
id: number;
content: string;
}
export interface Meta {
totalCount: number;
}Sources: harbinger/interface/src/models.ts:1-8
These models provide clear data structures for components and services, improving developer experience and reducing runtime errors.
API communication with the backend is handled by Axios. The configuration for Axios is set up in a Quasar boot file, harbinger/interface/src/boot/axios.ts.
// harbinger/interface/src/boot/axios.ts
import { boot } from 'quasar/wrappers';
import axios, { AxiosInstance } from 'axios';
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$axios: AxiosInstance;
$api: AxiosInstance;
}
}
const api = axios.create({ baseURL: 'https://api.example.com' });
export default boot(({ app }) => {
app.config.globalProperties.$axios = axios;
app.config.globalProperties.$api = api;
});
export { api };Sources: harbinger/interface/src/boot/axios.ts:1-20
This boot file creates an Axios instance and makes it available globally within the Vue application as $axios and $api. The $api instance is pre-configured with a base URL for the backend API, simplifying API calls from within components.
The Harbinger frontend is a well-structured Quasar application that provides a solid foundation for building a comprehensive user interface for the Harbinger C2 framework. Its use of modern web technologies like Vue.js and TypeScript, combined with a clear project structure, makes it a maintainable and extensible platform for red team operators.