Anthony Stirling 552f2ced4d
Auditing support (#3739)
# Description of Changes

This pull request introduces a comprehensive auditing system to the
application, along with minor updates to existing utilities and
dependencies. The most significant changes include the addition of
audit-related classes and enums, updates to the `ApplicationProperties`
model to support auditing configuration, and enhancements to utility
methods for handling static and trackable resources.

### Audit System Implementation:

* **Audit Aspect for Method Annotations**: Added `AuditAspect` to
process the new `@Audited` annotation, enabling detailed logging of
method execution, HTTP requests, and operation results based on
configurable audit levels.
(`proprietary/src/main/java/stirling/software/proprietary/audit/AuditAspect.java`)
* **Audit Event Types**: Introduced `AuditEventType` enum to define
standardized event types for auditing, such as authentication events,
file operations, and HTTP requests.
(`proprietary/src/main/java/stirling/software/proprietary/audit/AuditEventType.java`)
* **Audit Levels**: Added `AuditLevel` enum to define different levels
of audit logging (OFF, BASIC, STANDARD, VERBOSE), providing granular
control over the amount of data logged.
(`proprietary/src/main/java/stirling/software/proprietary/audit/AuditLevel.java`)

### Application Properties Update:

* **Audit Configuration in `ProFeatures`**: Updated the `ProFeatures`
class in `ApplicationProperties` to include support for auditing with
configurable retention days, levels, and enablement flags.
(`common/src/main/java/stirling/software/common/model/ApplicationProperties.java`)

### Utility Enhancements:

* **Static and Trackable Resource Handling**: Extended `RequestUriUtils`
methods (`isStaticResource` and `isTrackableResource`) to recognize
`.txt` files as valid static and trackable resources.
(`common/src/main/java/stirling/software/common/util/RequestUriUtils.java`)
[[1]](diffhunk://#diff-de3599037908683f2cd8f170939547612c6fc2203e9207eb4d7966508f92bbcbR22)
[[2]](diffhunk://#diff-de3599037908683f2cd8f170939547612c6fc2203e9207eb4d7966508f92bbcbR39)

### Dependency Update:

* **Spring Validation Starter**: Added `spring-boot-starter-validation`
to project dependencies to support validation mechanisms required for
auditing features. (`proprietary/build.gradle`)


Dashboard WIP

![image](https://github.com/user-attachments/assets/20d86809-63b0-44d6-82d3-bdce2ac77aa3)


![image](https://github.com/user-attachments/assets/53a5ba69-71ab-4247-9a66-7ef86e462b13)

![image](https://github.com/user-attachments/assets/9a53eaed-ebc7-463c-81da-8b1c140f8a8c)


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: a <a>
Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
2025-06-18 13:11:36 +01:00

239 lines
5.8 KiB
CSS

.dashboard-card {
margin-bottom: 20px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
background-color: var(--md-sys-color-surface-container);
color: var(--md-sys-color-on-surface);
border: 1px solid var(--md-sys-color-outline-variant);
}
.card-header {
background-color: var(--md-sys-color-surface-container-high);
color: var(--md-sys-color-on-surface);
border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.card-body {
background-color: var(--md-sys-color-surface-container);
}
.stat-card {
text-align: center;
padding: 20px;
}
.stat-number {
font-size: 2rem;
font-weight: bold;
}
.stat-label {
font-size: 1rem;
color: var(--md-sys-color-on-surface-variant);
}
.chart-container {
position: relative;
height: 300px;
width: 100%;
}
.filter-card {
margin-bottom: 20px;
padding: 15px;
background-color: var(--md-sys-color-surface-container-low);
border: 1px solid var(--md-sys-color-outline-variant);
border-radius: 4px;
}
.loading-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--md-sys-color-surface-container-high, rgba(229, 232, 241, 0.8));
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.level-indicator {
display: inline-block;
padding: 5px 10px;
border-radius: 15px;
color: white;
font-weight: bold;
}
.level-0 {
background-color: var(--md-sys-color-error, #dc3545); /* Red */
}
.level-1 {
background-color: var(--md-sys-color-secondary, #fd7e14); /* Orange */
}
.level-2 {
background-color: var(--md-nav-section-color-other, #28a745); /* Green */
}
.level-3 {
background-color: var(--md-sys-color-tertiary, #17a2b8); /* Teal */
}
/* Custom data table styling */
.audit-table {
font-size: 0.9rem;
color: var(--md-sys-color-on-surface);
border-color: var(--md-sys-color-outline-variant);
}
.audit-table tbody tr {
background-color: var(--md-sys-color-surface-container-low);
}
.audit-table tbody tr:nth-child(even) {
background-color: var(--md-sys-color-surface-container);
}
.audit-table tbody tr:hover {
background-color: var(--md-sys-color-surface-container-high);
}
.audit-table th {
background-color: var(--md-sys-color-surface-container-high);
color: var(--md-sys-color-on-surface);
position: sticky;
top: 0;
z-index: 10;
font-weight: bold;
}
.table-responsive {
max-height: 600px;
}
.pagination-container {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
padding: 10px 0;
border-top: 1px solid var(--md-sys-color-outline-variant);
color: var(--md-sys-color-on-surface);
}
.pagination .page-item.active .page-link {
background-color: var(--bs-primary);
border-color: var(--bs-primary);
color: white;
}
.pagination .page-link {
color: var(--bs-primary);
}
.pagination .page-link.disabled {
pointer-events: none;
color: var(--bs-secondary);
background-color: var(--bs-light);
}
.json-viewer {
background-color: var(--md-sys-color-surface-container-low);
color: var(--md-sys-color-on-surface);
border-radius: 4px;
padding: 15px;
max-height: 350px;
overflow-y: auto;
font-family: monospace;
font-size: 0.9rem;
white-space: pre-wrap;
border: 1px solid var(--md-sys-color-outline-variant);
margin-top: 10px;
}
/* Simple, minimal radio styling - no extras */
.form-check {
padding: 8px 0;
}
#debug-console {
position: fixed;
bottom: 0;
right: 0;
width: 400px;
height: 200px;
background: var(--md-sys-color-surface-container-highest, rgba(0,0,0,0.8));
color: var(--md-sys-color-tertiary, #0f0);
font-family: monospace;
font-size: 12px;
z-index: 9999;
overflow-y: auto;
padding: 10px;
border: 1px solid var(--md-sys-color-outline);
display: none; /* Changed to none by default, enable with key command */
}
/* Enhanced styling for radio buttons as buttons */
label.btn-outline-primary {
cursor: pointer;
transition: all 0.2s;
border-color: var(--md-sys-color-primary);
color: var(--md-sys-color-primary);
}
label.btn-outline-primary.active {
background-color: var(--md-sys-color-primary);
color: var(--md-sys-color-on-primary);
border-color: var(--md-sys-color-primary);
}
label.btn-outline-primary input[type="radio"] {
cursor: pointer;
}
/* Modal overrides for dark mode */
.modal-content {
background-color: var(--md-sys-color-surface-container);
color: var(--md-sys-color-on-surface);
border-color: var(--md-sys-color-outline);
}
.modal-header {
border-bottom-color: var(--md-sys-color-outline-variant);
}
.modal-footer {
border-top-color: var(--md-sys-color-outline-variant);
}
/* Improved modal positioning */
.modal-dialog-centered {
display: flex;
align-items: center;
min-height: calc(100% - 3.5rem);
}
.modal {
z-index: 1050;
}
/* Button overrides for theme consistency */
.btn-outline-primary {
color: var(--md-sys-color-primary);
border-color: var(--md-sys-color-primary);
}
.btn-outline-primary:hover {
background-color: var(--md-sys-color-primary);
color: var(--md-sys-color-on-primary);
}
.btn-outline-secondary {
color: var(--md-sys-color-secondary);
border-color: var(--md-sys-color-secondary);
}
.btn-outline-secondary:hover {
background-color: var(--md-sys-color-secondary);
color: var(--md-sys-color-on-secondary);
}
.btn-primary {
background-color: var(--md-sys-color-primary);
color: var(--md-sys-color-on-primary);
border-color: var(--md-sys-color-primary);
}
.btn-secondary {
background-color: var(--md-sys-color-secondary);
color: var(--md-sys-color-on-secondary);
border-color: var(--md-sys-color-secondary);
}