diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 29ba252..0afe7bf 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -1,4 +1,4 @@ -name: SharePulse Build +name: SharePulse build on: push: @@ -42,11 +42,29 @@ jobs: with: name: jar-artifact path: build/libs/*.jar + build-docker-image: - needs: build-jar runs-on: ubuntu-22.04 + needs: build-jar steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract tag name + run: | + git fetch --tags + GIT_TAG=$(git tag --points-at HEAD) + if [[ "$GIT_TAG" == v* ]]; then + VERSION=${GIT_TAG#v} + echo "Version tag found. Initializing docker image build for version: $VERSION" + echo "VERSION=$VERSION" >> $GITHUB_ENV + else + echo "No version tag found. Skipping subsequent steps. (Version tag format: vX.X.X)" + echo "SKIP_SUBSEQUENT_STEPS=true" >> $GITHUB_ENV + fi + - name: Initialize Docker runtime + if: env.SKIP_SUBSEQUENT_STEPS != 'true' run: | apt-get update apt-get install ca-certificates curl gnupg lsb-release -y @@ -60,23 +78,27 @@ jobs: apt-get update apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin -y - - name: Checkout - uses: actions/checkout@v4 - - name: Download Artifact + if: env.SKIP_SUBSEQUENT_STEPS != 'true' uses: actions/download-artifact@v3 with: name: jar-artifact path: build/libs - name: Build Docker Image - run: docker build . -t walzen665/sharepulse:latest + if: env.SKIP_SUBSEQUENT_STEPS != 'true' + run: docker build . -t walzen665/sharepulse:$VERSION - name: Tag Docker image - run: docker tag walzen665/sharepulse:latest git.walzen665.de/walzen665/sharepulse:latest + if: env.SKIP_SUBSEQUENT_STEPS != 'true' + run: docker tag walzen665/sharepulse:latest git.walzen665.de/walzen665/sharepulse:$VERSION - name: Log in to Gitea Docker Registry + if: env.SKIP_SUBSEQUENT_STEPS != 'true' run: echo ${{ secrets.GITEAREGISTRYTOKEN }} | docker login -u ${{ secrets.GITEAREGISTRYUSERNAME }} --password-stdin https://git.walzen665.de - name: Push Docker Image to Gitea - run: docker push git.walzen665.de/walzen665/sharepulse:latest \ No newline at end of file + if: env.SKIP_SUBSEQUENT_STEPS != 'true' + run: docker push git.walzen665.de/walzen665/sharepulse:$VERSION + + diff --git a/README.md b/README.md index 6596347..1896f80 100644 --- a/README.md +++ b/README.md @@ -12,4 +12,49 @@ Requirements: 1. Update `spring.profiles.active` in `application.properties` to `development` 2. Start external Backend and Database -3. Run `./gradlew bootRun ` in the root directory \ No newline at end of file +3. Run `./gradlew bootRun ` in the root directory + +# Running SharePulse using Docker +```yml +version: '3.8' + +services: + sharepulse: + image: git.walzen665.de/walzen665/sharepulse:latest + ports: + - "80:80" + environment: + # All Configurable parameters with default values + # Can be deleted if default values are used + RETHINKDB_HOST: rethinkdb + RETHINKDB_PORT: 28015 + RETHINKDB_DATABASE: sharepulse + SHAREPULSE_FILEPASSWORD_LENGTH: "6" + SHAREPULSE_FILEID_LENGTH: "6" + SHAREPULSE_TEMP_FILESTORE_PATH: "/temp-filestore" + SHAREPULSE_AUTO_RESET_ON_STARTUP: "true" + MAX_FILE_SIZE: "1GB" + MAX_REQUEST_SIZE: "1GB" + depends_on: + - rethinkdb + networks: + - sharepulse-net + + rethinkdb: + image: rethinkdb:latest + volumes: + - rethinkdb_data:/data + ports: + - "28015:28015" +# - "8080:8080" Webinterface of rethinkdb (optional and only accessible from localhost) + networks: + - sharepulse-net + +networks: + sharepulse-net: + external: false + +volumes: + rethinkdb_data: + +``` \ No newline at end of file diff --git a/build.gradle b/build.gradle index d59f36b..c082c3d 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,9 @@ dependencies { bootJar { manifest { + attributes( + 'Application-Version': project.version + ) } } diff --git a/frontend/src/app/credits/credits.component.html b/frontend/src/app/credits/credits.component.html index b65b6b4..6a83fd0 100644 --- a/frontend/src/app/credits/credits.component.html +++ b/frontend/src/app/credits/credits.component.html @@ -15,11 +15,15 @@

Version:

-

1.0.0

+

+ + {{ version }} +

API-Status:

-

online

+ +

online

Libraries:

diff --git a/frontend/src/app/credits/credits.component.ts b/frontend/src/app/credits/credits.component.ts index f23db40..2aacf5b 100644 --- a/frontend/src/app/credits/credits.component.ts +++ b/frontend/src/app/credits/credits.component.ts @@ -1,19 +1,26 @@ import { Component } from '@angular/core'; import {RouterLink} from "@angular/router"; import {LegalService} from "../../service/legalService"; +import axios from "axios"; +import {DevelopmentStore} from "../../store/DevelopmentStore"; +import {NgIf} from "@angular/common"; @Component({ selector: 'app-credits', standalone: true, - imports: [ - RouterLink - ], + imports: [ + RouterLink, + NgIf + ], templateUrl: './credits.component.html', styleUrl: './credits.component.scss' }) export class CreditsComponent { - constructor(private legalService: LegalService) { + version: string = ''; + + constructor(private legalService: LegalService, private developmentStore: DevelopmentStore) { + this.getVersion(); } openPrivacyPolicyModal() { @@ -23,4 +30,14 @@ export class CreditsComponent { openTermsOfUseModal() { this.legalService.openTermsOfUse(); } + + getVersion() { + axios.get(this.developmentStore.getBaseUrl() + 'api/v1/version') + .then((response) => { + this.version = response.data; + }) + .catch((error) => { + console.log(error); + }); + } } diff --git a/frontend/src/app/download/download.component.ts b/frontend/src/app/download/download.component.ts index bc9e3b5..ca70a4c 100644 --- a/frontend/src/app/download/download.component.ts +++ b/frontend/src/app/download/download.component.ts @@ -101,9 +101,6 @@ export class DownloadComponent { method: 'get', url: this.developmentStore.getBaseUrl() + 'api/v1/speed-test', responseType: 'arraybuffer', - headers: { - 'Access-Control-Allow-Origin': '*', // Allow CORS - } }) .then(response => { const end = new Date().getTime(); // End timer @@ -124,9 +121,6 @@ export class DownloadComponent { method: 'get', url: this.developmentStore.getBaseUrl() + 'api/v1/download-info?fileId=' + this.fileId, responseType: 'json', - headers: { - 'Access-Control-Allow-Origin': '*', // Allow CORS - } }) .then(response => { this.downloadInfo = response.data; @@ -146,9 +140,6 @@ export class DownloadComponent { method: 'get', url: this.developmentStore.getBaseUrl() + 'api/v1/download?fileId=' + this.fileId + '&password=' + this.filePassword, responseType: 'arraybuffer', - headers: { - 'Access-Control-Allow-Origin': '*', // Allow CORS - }, onDownloadProgress: (progressEvent) => { const endTime = new Date().getTime(); const duration = (endTime - startTime) / 1000; diff --git a/frontend/src/app/upload/upload.component.ts b/frontend/src/app/upload/upload.component.ts index 783101a..df1cce8 100644 --- a/frontend/src/app/upload/upload.component.ts +++ b/frontend/src/app/upload/upload.component.ts @@ -85,7 +85,6 @@ export class UploadComponent { const config = { headers: { 'Content-Type': 'multipart/form-data', - 'Access-Control-Allow-Origin': '*', // Allow CORS }, onUploadProgress: (progressEvent: AxiosProgressEvent) => { if (progressEvent.total) { @@ -156,7 +155,6 @@ export class UploadComponent { data: uint8View, headers: { 'Content-Type': 'application/octet-stream', - 'Access-Control-Allow-Origin': '*', // Allow CORS }, onUploadProgress: function(progressEvent) { // Optional: handle progress events for feedback diff --git a/src/main/java/de/w665/sharepulse/rest/ErrorRestController.java b/src/main/java/de/w665/sharepulse/rest/ErrorRestController.java new file mode 100644 index 0000000..487a54e --- /dev/null +++ b/src/main/java/de/w665/sharepulse/rest/ErrorRestController.java @@ -0,0 +1,19 @@ +package de.w665.sharepulse.rest; + +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * This class is used to redirect the user to the home page if an endpoint is not found. + */ +@RestController +public class ErrorRestController implements ErrorController { + @RequestMapping("/error") + public String handleError() { + return ""; + } +} diff --git a/src/main/java/de/w665/sharepulse/rest/mappings/Version.java b/src/main/java/de/w665/sharepulse/rest/mappings/Version.java new file mode 100644 index 0000000..df31b41 --- /dev/null +++ b/src/main/java/de/w665/sharepulse/rest/mappings/Version.java @@ -0,0 +1,37 @@ +package de.w665.sharepulse.rest.mappings; + +import com.rethinkdb.net.Response; +import de.w665.sharepulse.rest.ApiRestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +@RestController +public class Version extends ApiRestController { + + private final ResourceLoader resourceLoader; + + @Autowired + public Version(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + @GetMapping("/version") + public ResponseEntity getVersion() throws Exception { + Resource resource = resourceLoader.getResource("classpath:META-INF/MANIFEST.MF"); + Manifest manifest = new Manifest(resource.getInputStream()); + Attributes attr = manifest.getMainAttributes(); + String version = attr.getValue("Application-Version"); + String response = version != null ? version : "Version is only available in production builds"; + return new ResponseEntity<>(response, HttpStatus.OK); + } +}