From b88ee26628f8d91ddfb318d25f830207eab8a81f Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 25 Sep 2025 16:57:30 +0300
Subject: [PATCH 01/13] Set maven compiler source and target version
---
qlack-base-application-server/pom.xml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/qlack-base-application-server/pom.xml b/qlack-base-application-server/pom.xml
index ece101c..dd8952a 100644
--- a/qlack-base-application-server/pom.xml
+++ b/qlack-base-application-server/pom.xml
@@ -23,6 +23,8 @@
2.18.00.8.123.13.0
+ 21
+ 21
From 370ef6cdec21e98c8f64f690e502192da2faf9ea Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 25 Sep 2025 16:59:39 +0300
Subject: [PATCH 02/13] Updated README.md
---
README.md | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 3d480a0..c47bc47 100644
--- a/README.md
+++ b/README.md
@@ -55,16 +55,6 @@ start your new project by cloning this repo and then built on top of it.

-## Development setup
-
-To start the back-end component, issue:
-
-`mvn spring-boot:run`
-
-To start the front-end component, issue:
-
-`npm start`
-
## Containers support
Both the front-end and the back-end component come with a `Dockerfile` allowing you to build Docker
@@ -77,7 +67,7 @@ The supplied build scripts provide two interesting features:
any additional setup.
* Image building follows a multi-stage approach. Expensive operations (such as downloading Maven
- artifacts or NodeJS packages) takes place in a previous phase of your build, allowing you to skip
+ artifacts or NodeJS packages) take place in a previous phase of your build, allowing you to skip
those phases in future builds (provided your dependencies remain the same).
A top-level Docker Compose file is also provided, allowing you to build and run the complete application
@@ -87,6 +77,20 @@ stack in just a single command:
The application becomes accessible on port 6565, i.e. http://localhost:6565.
+## Development setup
+
+To start the back-end component, install Java 21+ and Apache Maven 3.9.9+ and then issue:
+
+`mvn spring-boot:run`
+
+To start the front-end component, install Node.js and issue:
+
+`npm install`
+
+then
+
+`npm start`
+
## Extra Security Feature CustomCookieFilter
The `CustomCookieFilter` is a filter designed to create a token and place it in a cookie, subsequently validating this
@@ -108,7 +112,7 @@ To implement this functionality, the following line of code should be added to y
`SecurityFilterChain`:
```java
-.addFilterBefore(customCookieFilter, BasicAuthenticationFilter .class)
+.addFilterBefore(customCookieFilter, BasicAuthenticationFilter.class);
```
Additionally, the following properties should be added to your application file:
@@ -129,12 +133,12 @@ Ensure these configurations are in place for the filter to function correctly.
There are 25 Angular unit tests as examples to demonstrate testing for Components and Services. The unit tests are the
files with naming ending with .spec.ts. You can find the tests at folders "login", "logout", "employee".
+### Karma unit tests report
+
The unit tests are using Jasmine and Karma. All the configurations to use Jasmine and Karma are located inside the
`karma.conf.js` file. Open a terminal in `qlack-base-application-ui` folder and run the unit tests by typing the
command `npm run test`.
-### Karma unit tests report
-
The report of unit tests will be as shown in the screenshot.

@@ -143,11 +147,10 @@ The report of unit tests will be as shown in the screenshot.
In the same terminal you can run the command "npm run karma_coverage" to get the code coverage.
The report of code coverage will be as shown in the screenshot.

-The karma code coverage module will also create a code coverage report which you will find it in the path "
-coverage/qlack_base_application_ui".
+The karma code coverage module will also create a code coverage report which you will find it in the path `coverage/qlack_base_application_ui`.
The html report of the code coverage will be as shown in the screenshot.

## Springboot Backend
-There are 16 unit tests for the Backend. **Jacoco** plugin for code coverage is also included in the pom.xml.
\ No newline at end of file
+There are 16 unit tests for the Backend. **Jacoco** plugin for code coverage is also included in the pom.xml.
From 15c361ae2cb3831f27823f18be471e5906a49445 Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 25 Sep 2025 17:01:10 +0300
Subject: [PATCH 03/13] Added file delete functionality to the ui
---
.../files/files-list/files-list.component.ts | 31 ++++++++++++++++---
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/qlack-base-application-ui/src/app/files/files-list/files-list.component.ts b/qlack-base-application-ui/src/app/files/files-list/files-list.component.ts
index a972093..66924f2 100644
--- a/qlack-base-application-ui/src/app/files/files-list/files-list.component.ts
+++ b/qlack-base-application-ui/src/app/files/files-list/files-list.component.ts
@@ -14,6 +14,9 @@ import {MatPaginator} from "@angular/material/paginator";
import {QFormsService} from "@qlack/forms";
import {CdkCell, CdkCellDef, CdkColumnDef, CdkHeaderCell, CdkTable} from "@angular/cdk/table";
import {RouterLink} from "@angular/router";
+import {MatDialog} from "@angular/material/dialog";
+import {OkCancelModalComponent} from "../../shared/component/ok-cancel-modal/ok-cancel-modal.component";
+import {UtilityService} from "../../shared/service/utility.service";
@Component({
selector: "app-files",
@@ -27,7 +30,8 @@ export class FilesListComponent implements AfterViewInit {
@ViewChild(MatSort, {static: true}) sort!: MatSort;
@ViewChild(MatPaginator, {static: true}) paginator!: MatPaginator;
- constructor(private filesService: FilesService, private qForms: QFormsService) {
+ constructor(private filesService: FilesService, private qForms: QFormsService,
+ private dialog: MatDialog, private utilityService: UtilityService) {
}
ngAfterViewInit(): void {
@@ -42,7 +46,6 @@ export class FilesListComponent implements AfterViewInit {
}
fetchData(page: number, size: number, sort: string, sortDirection: string) {
-
this.filesService.getAll(this.qForms.makeQueryStringForData(null, [], false, page, size,
sort, sortDirection)).subscribe({
next: onNext => {
@@ -53,12 +56,32 @@ export class FilesListComponent implements AfterViewInit {
}
changePage() {
- this.fetchData(this.paginator.pageIndex, this.paginator.pageSize, this.sort.active,
- this.sort.start);
+ this.fetchData(this.paginator.pageIndex, this.paginator.pageSize, this.sort.active, this.sort.start);
}
download(id: string) {
this.filesService.download(id);
}
+
+ delete(id: any) {
+ const dialogRef = this.dialog.open(OkCancelModalComponent, {
+ data: {
+ title: "Delete file",
+ question: "Do you really want to delete this file?",
+ buttons: {
+ ok: true, cancel: true, reload: false
+ }
+ }
+ });
+ dialogRef.afterClosed().subscribe((result: boolean) => {
+ if (result) {
+ this.filesService.delete(id).subscribe(() => {
+ this.utilityService.popupSuccess("File successfully deleted.");
+ this.ngAfterViewInit();
+ });
+ }
+ });
+ }
+
}
From 15e67db583c3c7c9af6cc613f1b7ddb0caf069d2 Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 25 Sep 2025 17:01:55 +0300
Subject: [PATCH 04/13] Added file delete button to the ui
---
.../src/app/files/files-list/files-list.component.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/qlack-base-application-ui/src/app/files/files-list/files-list.component.html b/qlack-base-application-ui/src/app/files/files-list/files-list.component.html
index 385cc81..7aa85a9 100644
--- a/qlack-base-application-ui/src/app/files/files-list/files-list.component.html
+++ b/qlack-base-application-ui/src/app/files/files-list/files-list.component.html
@@ -27,6 +27,7 @@
+
From 6bb4134de38e590e5fa9e5cd9fbd180bac084418 Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 25 Sep 2025 18:07:39 +0300
Subject: [PATCH 05/13] fixed docker build issue
---
docker-compose.yml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/docker-compose.yml b/docker-compose.yml
index 024a8d0..9a5bdc4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,7 +2,8 @@ version: '3'
services:
ui:
- build: qlack-base-application-ui
+ build:
+ context: ./qlack-base-application-ui
image: qlack/qba-ui:3.2.2-SNAPSHOT
container_name: qba-ui
restart: unless-stopped
@@ -11,7 +12,8 @@ services:
ports:
- "6565:80"
server:
- build: qlack-base-application-server
+ build:
+ context: ./qlack-base-application-server
image: qlack/qba-server:3.2.2-SNAPSHOT
container_name: qba-server
restart: unless-stopped
From d5fd7ac843761032544e1978b72aa52745ffc066 Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 25 Sep 2025 18:10:35 +0300
Subject: [PATCH 06/13] Update README.md with docker command
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c47bc47..741b7f3 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,7 @@ The supplied build scripts provide two interesting features:
A top-level Docker Compose file is also provided, allowing you to build and run the complete application
stack in just a single command:
-`docker compose up --build`
+`docker compose up`
The application becomes accessible on port 6565, i.e. http://localhost:6565.
From 5e68ee85b1fe3921191b12292d62166e72dd8ce5 Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 25 Sep 2025 19:31:04 +0300
Subject: [PATCH 07/13] Updated pom.xml with maven.compiler.release
---
qlack-base-application-server/pom.xml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/qlack-base-application-server/pom.xml b/qlack-base-application-server/pom.xml
index dd8952a..b1ce56b 100644
--- a/qlack-base-application-server/pom.xml
+++ b/qlack-base-application-server/pom.xml
@@ -23,8 +23,7 @@
2.18.00.8.123.13.0
- 21
- 21
+ 21
From 1fe188290d58d5c4b5d71a048deb9c310c589364 Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Wed, 1 Oct 2025 17:28:46 +0300
Subject: [PATCH 08/13] fixed bug with PUBLIC_URIS by also adding them to
ignore-paths of CustomCookieFilter
---
.../src/main/resources/application.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/qlack-base-application-server/src/main/resources/application.yml b/qlack-base-application-server/src/main/resources/application.yml
index 65ab7b3..ba2003f 100644
--- a/qlack-base-application-server/src/main/resources/application.yml
+++ b/qlack-base-application-server/src/main/resources/application.yml
@@ -32,13 +32,14 @@ qlack:
util:
jwt:
issuer: qlack_demo
- validity: 1440
+ validity: 1440 # in minutes, default validity is 1 day
csrf:
cookie-name: COOKIE-TOKEN # the name of the cookie
cookie-timer: 60 # per seconds, the timer for keep old cookies alive for multiple requests
cookie-cache-clean-timer: 0 * * ? * * # the scheduler where we clean cache from non-valid cookies
login-path: '/users/auth'
logout-path: '/users/logout'
+ ignore-paths: '/users/auth, /i18n/*, /error'
logging:
level:
From 6be82e0e8148fca9fd98cf02816f9b337b06931b Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Wed, 1 Oct 2025 17:34:03 +0300
Subject: [PATCH 09/13] fixed bug with PUBLIC_URIS by also adding them to
ignore-paths of CustomCookieFilter
---
.../config/WebSecurityConfig.java | 46 ++++++++++---------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java b/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java
index f1d76c3..97dcc76 100644
--- a/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java
+++ b/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java
@@ -1,6 +1,8 @@
package com.eurodyn.qlack.baseapplication.config;
+import com.eurodyn.qlack.util.csrf.filter.CustomCookieFilter;
import com.eurodyn.qlack.util.jwt.filter.JwtAuthenticationFilter;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -9,33 +11,33 @@
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
-import com.eurodyn.qlack.util.csrf.filter.CustomCookieFilter;
@Configuration
public class WebSecurityConfig {
- private static final String[] PUBLIC_URIS =
- {"/users/auth", "/ping", "/i18n/*","/error"};
- private final JwtAuthenticationFilter jwtAuthenticationFilter;
-
- private final CustomCookieFilter customCookieFilter;
-
- public WebSecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter, CustomCookieFilter customCsrfCookieFilter) {
- this.jwtAuthenticationFilter = jwtAuthenticationFilter;
- this.customCookieFilter = customCsrfCookieFilter;
- }
+ @Value("${qlack.util.csrf.ignore-paths:#{null}}")
+ private List IGNORED_PATHS;
- @Bean
- public SecurityFilterChain configure(HttpSecurity http) throws Exception {
- http.csrf(AbstractHttpConfigurer::disable)
- .authorizeHttpRequests(requests -> requests
- .requestMatchers(PUBLIC_URIS).permitAll()
- .anyRequest().authenticated())
- .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
- .addFilterBefore(customCookieFilter, BasicAuthenticationFilter.class)
- .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+ private final JwtAuthenticationFilter jwtAuthenticationFilter;
- return http.build();
+ private final CustomCookieFilter customCookieFilter;
- }
+ public WebSecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter, CustomCookieFilter customCsrfCookieFilter) {
+ this.jwtAuthenticationFilter = jwtAuthenticationFilter;
+ this.customCookieFilter = customCsrfCookieFilter;
+ }
+
+ @Bean
+ public SecurityFilterChain configure(HttpSecurity http) throws Exception {
+ final String[] PUBLIC_URIS = IGNORED_PATHS!=null ? IGNORED_PATHS.toArray(new String[IGNORED_PATHS.size()]) : new String[0];
+ http.csrf(AbstractHttpConfigurer::disable)
+ .authorizeHttpRequests(requests -> requests
+ .requestMatchers(PUBLIC_URIS).permitAll()
+ .anyRequest().authenticated())
+ .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .addFilterBefore(customCookieFilter, BasicAuthenticationFilter.class)
+ .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+
+ return http.build();
+ }
}
From 309f27ed081fce2a9818bb751564b59f42873070 Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Wed, 1 Oct 2025 17:36:59 +0300
Subject: [PATCH 10/13] fixed liquibase script error when connecting to MariaDB
(initializing not null column with null value)
---
.../src/main/resources/db/changelog/changes/qba_00003.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qlack-base-application-server/src/main/resources/db/changelog/changes/qba_00003.xml b/qlack-base-application-server/src/main/resources/db/changelog/changes/qba_00003.xml
index f120a2a..5978764 100644
--- a/qlack-base-application-server/src/main/resources/db/changelog/changes/qba_00003.xml
+++ b/qlack-base-application-server/src/main/resources/db/changelog/changes/qba_00003.xml
@@ -25,7 +25,7 @@
-
+
From d3d94dcaf8e88f43209ecb552b3b26625d4e684b Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Wed, 1 Oct 2025 17:43:33 +0300
Subject: [PATCH 11/13] Updated README.md with Contributing section
---
README.md | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/README.md b/README.md
index 741b7f3..94afb44 100644
--- a/README.md
+++ b/README.md
@@ -154,3 +154,39 @@ The html report of the code coverage will be as shown in the screenshot.
## Springboot Backend
There are 16 unit tests for the Backend. **Jacoco** plugin for code coverage is also included in the pom.xml.
+
+## Contributing
+
+We welcome contributions and appreciate your effort to help improve this project!
+To keep things organized please follow the steps below:
+
+1. **Fork the repository** to your own GitHub account.
+
+2. **Clone** your fork to your local machine:
+
+ ```bash
+ git clone https://github.com//.git
+ cd
+ ```
+
+3. **Make your changes** and **Commit** your work:
+
+4. **Push** the branch to your fork.
+
+5. **Open a Pull Request (PR)** against the main repository:
+ - A Pull Request (PR) is a GitHub feature that lets you propose changes from your fork back to the original repository.
+ - To create one:
+ 1. Log in to your GitHub account.
+ 2. Navigate to your forked repository.
+ 3. Click the **"Contribute"** button (usually near the top of the repo page).
+ 4. Select **"Open pull request"**.
+ 5. Make sure the base repository is the original project and the base branch (`master`) is correct.
+ 6. Confirm that the “compare” branch is the branch you pushed.
+
+6. In the PR form:
+ - Provide a clear description of the changes and why they are needed
+ - Reference related issues if applicable
+ - Request a review from maintainers
+ - Be open to feedback and ready to make revisions
+
+You can also watch an overview of how to contribute to OSS via Pull Requests here: [GitHub Pull Request Tutorial](https://www.youtube.com/watch?v=dLRA1lffWBw)
From dfab0d29a55318adc9147b31932f21141292bb6e Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 2 Oct 2025 19:38:22 +0300
Subject: [PATCH 12/13] fixed bug with PUBLIC_URIS by removing login-path from
ignore-paths of CustomCookieFilter
---
.../config/WebSecurityConfig.java | 24 ++++++++++++-------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java b/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java
index 97dcc76..de8bad6 100644
--- a/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java
+++ b/qlack-base-application-server/src/main/java/com/eurodyn/qlack/baseapplication/config/WebSecurityConfig.java
@@ -15,9 +15,12 @@
@Configuration
public class WebSecurityConfig {
- @Value("${qlack.util.csrf.ignore-paths:#{null}}")
+ @Value("${qlack.util.csrf.ignore-paths:#{new ArrayList()}}")
private List IGNORED_PATHS;
+ @Value("${qlack.util.csrf.login-path:#{null}}")
+ private String LOGIN_PATH;
+
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final CustomCookieFilter customCookieFilter;
@@ -29,15 +32,18 @@ public WebSecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter, Custom
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
- final String[] PUBLIC_URIS = IGNORED_PATHS!=null ? IGNORED_PATHS.toArray(new String[IGNORED_PATHS.size()]) : new String[0];
+ if (LOGIN_PATH != null) {
+ IGNORED_PATHS.add(LOGIN_PATH);
+ }
+ final String[] PUBLIC_URIS = IGNORED_PATHS.stream().toArray(String[]::new);
http.csrf(AbstractHttpConfigurer::disable)
- .authorizeHttpRequests(requests -> requests
- .requestMatchers(PUBLIC_URIS).permitAll()
- .anyRequest().authenticated())
- .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
- .addFilterBefore(customCookieFilter, BasicAuthenticationFilter.class)
- .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
-
+ .authorizeHttpRequests(requests -> requests
+ .requestMatchers(PUBLIC_URIS).permitAll()
+ .anyRequest().authenticated()
+ )
+ .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .addFilterBefore(customCookieFilter, BasicAuthenticationFilter.class)
+ .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
From 6e32c1616df02f8f3fc0f11c3f2dbaa3ad704d4c Mon Sep 17 00:00:00 2001
From: Kostis Tsitsas <37558185+ktsitsas@users.noreply.github.com>
Date: Thu, 2 Oct 2025 19:39:07 +0300
Subject: [PATCH 13/13] fixed bug with PUBLIC_URIS by removing login-path from
ignore-paths of CustomCookieFilter
---
.../src/main/resources/application.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qlack-base-application-server/src/main/resources/application.yml b/qlack-base-application-server/src/main/resources/application.yml
index ba2003f..64d6a8b 100644
--- a/qlack-base-application-server/src/main/resources/application.yml
+++ b/qlack-base-application-server/src/main/resources/application.yml
@@ -39,7 +39,7 @@ qlack:
cookie-cache-clean-timer: 0 * * ? * * # the scheduler where we clean cache from non-valid cookies
login-path: '/users/auth'
logout-path: '/users/logout'
- ignore-paths: '/users/auth, /i18n/*, /error'
+ ignore-paths: '/i18n/*, /error'
logging:
level: