Skip to content

Edit README with battalion information - #4

Open
MateuszKosowski wants to merge 69 commits into
zzpj:mainfrom
MateuszKosowski:main
Open

MateuszKosowski wants to merge 69 commits into
zzpj:mainfrom
MateuszKosowski:main

Conversation

@MateuszKosowski

Copy link
Copy Markdown

Mission accomplished, General

MateuszKosowski and others added 10 commits March 2, 2026 19:31
Initial configuration for microservices and Docker setup
Add JaCoCo coverage reporting and SonarQube integration. Closes #4
* Add GitHub Actions CI for tests

* Fix Gradle wrapper permissions in CI
)

* Add JWT secret key and Eureka URL to environment example

* Add PostgreSQL configuration to Docker and update environment variables

* Add PostgreSQL and JWT dependencies, update Docker environment variables, and create users table

* Add health checks and service dependencies to Docker Compose configuration

* Implement authentication with JWT: add AuthController, JwtService, and user login functionality

* Add token validation and authentication error handling: implement validateToken method, add custom exceptions for bad credentials and email not found

* Add JWT authentication and security configuration: implement JwtFilter, SecurityConfig, and AuthClient; update application structure for watermark service

* Refactor JWT filter and security configuration: improve error handling in JwtFilter and update permitted endpoints in SecurityConfig

* Add PostgreSQL integration for tests: configure Testcontainers for PostgreSQL in ApplicationTests and update build.gradle.kts for test dependencies
@gitguardian

gitguardian Bot commented Mar 28, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

Since your pull request originates from a forked repository, GitGuardian is not able to associate the secrets uncovered with secret incidents on your GitGuardian dashboard.
Skipping this check run and merging your pull request will create secret incidents on your GitGuardian dashboard.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
- - Generic Password 243510f .env.example View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

NikodemNowak and others added 19 commits May 7, 2026 14:49
* Rebase onto main

* fix: disable Eureka/Config discovery in tests for CI compatibility

* Clean up

* Move .yaml properties to config-server + WATERMARK_APP_KEY

* Preserve RGB colors in watermark embedding

Update steganography to preserve original RGB colors when writing updated luminance. WatermarkImageData now stores an rgb matrix and withUpdatedLuminance builds a TYPE_INT_RGB image, using a new colorWithLuminance routine that adjusts RGB channels to match the target luminance. Removed unused WritableRaster import.

Tests updated to set a test watermark app-key and disable MVC filters, and to assert embedded image dimensions and that color pixels are preserved (added containsColorPixels helper).

* Instead of manual ownerId we retrieve data from JWT

* Rename ownerId to ownerIdentity in watermark embedding and extraction processes

* fix: preserve original colors when embedding watermark

* fix: read pixels via getRGB and lower DELTA to 50

Raster band order depends on BufferedImage type (BGR for many PNGs),
which swapped R/B channels. getRGB returns ARGB regardless. Lowering
DELTA reduces blockiness in flat regions while keeping JPEG q>=0.5.

* fix: bump DELTA to 70 for CI JPEG robustness

Linux JDK JPEG encoder is more aggressive than Windows; DELTA=50 made
the q>=0.7 round-trip pass locally but fail on CI. 70 keeps headroom
on CI while still reducing blockiness vs the original 80.

---------

Co-authored-by: Mateusz Kosowski <mateuszkosowski03@gmail.com>
* feat: add ai-service for image classification (closes #15)

Introduces a new ai-service microservice that classifies uploaded images
and returns ImageNet labels mapped to broad categories. Integrates it with
watermark-service via a Feign client so the watermark endpoint enriches
responses with classification metadata in headers.

- ai-service: Spring Boot module with ClassificationController/Service and CategoryMapper
- watermark-service: AiServiceFeignClient + ClassificationResult DTO, controller now exposes POST /api/watermark with multipart upload
- docker-compose: ai-service container wiring
- settings.gradle.kts: register ai-service module

* test: mock AiServiceFeignClient in watermark-service integration tests

* Address PR feedback for ai-service

- WatermarkController: catch ai-service failures and fall back to
  'unknown' classification headers so embed still succeeds when AI is
  down. Restore method-level Javadocs that were dropped during the
  earlier refactor.
- CategoryMapper: switch from Map.ofEntries (unspecified iteration
  order) to an ordered List<Map.Entry> so category resolution stays
  deterministic if overlapping keywords are ever added.
- AiServiceApplicationTests: replace deprecated @MockBean with
  @MockitoBean (matches the convention already used in
  watermark-service tests).
- Add ClassificationServiceTest: real smoke test that loads MobileNetV2
  ONNX and classifies a small Samoyed image, asserting top-1 maps to
  the 'dog' category. Bundles the ~14MB ONNX model, ImageNet synset,
  and test image under src/test/resources/model so the test is fully
  hermetic and runs in CI in <1s after model load.

* fix: resolve CI failure by avoiding double-reading MultipartFile and hardening model loading

* feat: add security to ai-service and fix config loading

* style: align ai-service with project-wide practices (exception handling)

* refactor: migrate ai-service config to config-server and enable native search

---------

Co-authored-by: Jakub Rusek <jakub.rusek.01@gmail.com>
* feat: integrate SvelteKit GUI with AI classification and dockerize

Brings the frontend from add-initial-frontend onto current main (which
extracted ai-service into its own microservice) and wires it end to end.

- add gui/ (SvelteKit) and a gui service to docker-compose on :5173
- switch adapter-auto -> adapter-static (SPA) served by nginx
- nginx reverse-proxies /api and /auth to the backend so the browser uses
  same-origin relative paths; removes the need for CORS
- display the detected image class read from the X-Image-* headers that
  watermark-service returns from /embed
- vite dev proxy mirrors the nginx routing for `npm run dev`

Lockfile is intentionally not committed; the Docker build uses npm install.

* fix: forward JWT from watermark-service to ai-service classify

* feat: add detect, extract and visualize tabs to GUI

* fix: friendly notice when extracting from image without watermark
…tiers

Brings the Python watermark-service to parity with the Java implementation
and closes the security regressions left by the original port.

Spring Cloud Config Server integration
  Startup polls config-server (application + watermark-service profiles),
  flattens propertySources, merges into pydantic Settings with env-var
  precedence. Retries with exponential backoff (1s → 16s) per path and
  keeps whatever properties resolved if one path stays unreachable.
  Placeholder resolver (${VAR:default}) is bounded to 16 passes so cyclic
  references can't hang startup.

AES-256-GCM payload encryption
  Watermark payload (owner|text) is sealed with AES-GCM keyed off
  WATERMARK_APP_KEY (SHA-256 derived). Magic bytes WMPY + version byte +
  96-bit nonce per embed + 128-bit auth tag. Without the app key nobody
  can read or forge a watermark — closes the plaintext-payload spoofing
  hole. Service refuses to boot with the public dev default key unless
  WATERMARK_DEV_MODE=true is set explicitly.

Reed-Solomon ECC layer
  16 parity bytes wrap the encrypted envelope so dwtDctSvd's occasional
  bit-flips on threshold-sized images don't fail the GCM auth tag.
  Corrects up to 8 byte errors per watermark. Envelope overhead: 49 bytes
  (17 header + 16 GCM tag + 16 RS parity).

Adaptive length_bits tiers with embed-time verification
  Embed picks the largest watermark capacity an image can carry, verifies
  the round-trip end-to-end (catches any decode/decrypt exception, not
  just CryptoError), falls back to a smaller tier if ECC can't recover.
  Detect tries each known length until one decrypts.
    short ≥ 1080 px AND long ≥ 1600 px → 1024 bit, ~71 bytes of text
    short ≥ 1024 px AND long ≥ 1024 px →  768 bit, ~39 bytes
  Below the smaller tier the image is rejected with a clear 400.

Strict input boundary on /embed
  Server-side PNG magic-byte check rejects JPG/WebP up front so the
  GUI's "PNG-only" promise is enforced at the API boundary, not just
  by the file-picker filter. Image and text payloads are size-capped
  (25 MB / 4 KB) to defang form-data DoS. EXIF orientation is applied
  during decode so portrait photos pick the right tier.

Auth tightening (closed regressions vs Java)
  - JWT required on /detect and /visualize (matches Java SecurityConfig)
  - auth-server validation uses strict `body is True` — schema drift
    fails closed instead of accepting truthy alternatives
  - Principal extracted from JWT is sanitized through an identifier
    regex before being embedded; non-matching identifiers fall back to
    "User" rather than poison the envelope
  - Split connect/read timeouts (2s / 5s) on the validate call

ai-service client made non-blocking
  Switched from sync httpx.Client to AsyncClient with split
  connect/read/write/pool timeouts so a slow ai-service can't park the
  embed handler's event loop. Classification still falls back to
  "unknown" on any error.

New POST /api/watermark/capacity
  Returns maxTextBytes (renamed from maxTextChars — the budget is UTF-8
  bytes, not codepoints) + chosen tier + image dimensions for the
  calling principal. Powers the GUI's live byte counter.

Embed-time errors mapped cleanly
  embed_text can raise RuntimeError when verification fails at every
  tier; routes layer maps it to 422 with the descriptive message
  instead of leaking a stack trace.

Eureka registration
  Passes health_check_url + status_page_url so the dashboard reflects
  real /health state instead of py-eureka-client defaults.

GUI updates (Svelte 5)
  - Embed-tab file picker restricts to image/png (clean source = best
    ECC margin); other tabs still accept JPG so users can see "this
    copy lost the watermark"
  - Live capacity probe on image select with AbortController guarding
    against stale responses from a previous selection; file-signature
    dedup so re-binding the same FileList doesn't re-upload
  - Byte counter under the text input; submit disabled when over budget,
    image too small, OR capacity probe still in flight
  - Subtle PNG-only hints on every tab + explicit "keep as PNG" note
    under the download button (subdued slate-500 styling, WCAG AA)
  - Field rename: capacity.maxTextChars → capacity.maxTextBytes;
    response header X-Max-Text-Chars → X-Max-Text-Bytes

Hardening
  - Dockerfile runs uvicorn as non-root user (uid 10001)
  - LOG_LEVEL actually configures the root logger
  - WATERMARK_DEV_MODE flag wired through docker-compose so the dev
    default key boots locally but production deploys must set a real
    secret or set DEV_MODE explicitly
  - Dropped unused Settings.port + dead PyJWT dependency
  - Removed WATERMARK_LENGTH_BITS env (tier selection is automatic)
  - Bumped service version to 0.2.0-py

Documentation
  README covers config-server integration, crypto design, adaptive tier
  math (with corrected envelope overhead), capacity calculation, and an
  explicit "PNG in, PNG out, do not recompress" user contract explaining
  why the watermark dies on JPG re-encode (DWT-DCT-SVD is a fundamental
  DCT-frequency algorithm).

Tests: 33 passing (incl. 1024-bit/768-bit tier roundtrips, FHD landscape
and portrait, wrong-key returns not-watermarked, auth required on
detect/visualize, capacity reporting per tier, embed verification with
tier downgrade, async ai-client mocks). Removed the all-xfail JPEG
robustness sweep — the limitation is fundamental to DWT-DCT-SVD and now
documented in README.
Harden watermark-service-py: AES-GCM crypto, config-server, adaptive capacity (closes #23)
…acy-java-watermark

chore: remove legacy Java watermark-service and watermark-client (#26)
MateuszKosowski and others added 30 commits June 4, 2026 00:39
* feat(registration): implement user registration endpoint with validation and error handling

* feat(registration): add user registration form with validation and error handling
- Added springdoc-openapi to Java services (ai, auth, subscription)
- Added technical descriptions to FastAPI routes in watermark-service
- Updated README.md with OpenAPI documentation links
- Exposed ai-service port in docker-compose for Swagger access
- Configured security to permit access to Swagger UI endpoints
docs: add OpenAPI documentation to all service endpoints
* docs: add OpenAPI and improve test coverage

* refactor: inject Clock for testability and centralize springdoc version

* fix: provide default values for config-server security credentials

* refactor: simplify token reservation response mapping
docs: consolidate OpenAPI definitions from all services and add inter…
Add project linting and code style checks
* Implement paid subscription upgrade lifecycle

� Conflicts:
�	subscription-service/src/main/java/pl/zzpj/subscription_service/application/PaymentApplicationService.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/application/SubscriptionQueryService.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/application/TokenReservationCommandService.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/controller/MockPaymentController.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/controller/TokenReservationController.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/domain/payment/PaymentProvider.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/domain/subscription/ActiveSubscription.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/domain/subscription/PlanCode.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/domain/token/TokenReservationPolicy.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/domain/token/decision/TokenDecision.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/infrastructure/payment/MockPaymentProvider.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/persistence/SubscriptionStore.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/persistence/repository/ActiveSubscriptionRepository.java
�	subscription-service/src/main/java/pl/zzpj/subscription_service/persistence/repository/PaymentSessionRepository.java
�	subscription-service/src/test/java/pl/zzpj/subscription_service/application/SubscriptionQueryServiceTest.java
�	subscription-service/src/test/java/pl/zzpj/subscription_service/application/TokenReservationCommandServiceTest.java

* Improve subscription and upload feedback in UI

* Document subscription lifecycle and mock payments
Add a source-verified API reference under docs/api/:
- README.md: system map, nginx routing, auth model, token economy, demo
  accounts, error model, and a Known Issues callout
- per-service docs: auth-server, subscription-service, ai-service,
  watermark-service, infrastructure (eureka, config-server, actuator)

Rebuild stegocloud-openapi.json (3.1):
- real on-service paths with per-path servers (executable in api-docs.html)
- add token-reservation endpoints; concrete watermark response schemas
  (image/png + X-* headers, JSON for detect/extract/capacity)
- fix /watermark/health -> /health, register 200 -> 201, typed login
  response, and add 401/403/409/413/422/500 error responses

Wire the new docs into README.md and flag the TokenReservationController
wiring defect (missing @RestController/@RequestMapping -> /api/tokens/
reservations returns 404, breaking watermark paid operations).
A merge dropped @RestController and @RequestMapping from
TokenReservationController, so /api/tokens/reservations was unmapped
and every reservation returned 404. The watermark-service surfaced
this as "Could not reserve tokens for this operation" on embed.
…nsive-testing

test: comprehensive automated testing strategy (#19)
…tation

docs(api): endpoint reference + rebuilt OpenAPI spec
docs: add LaTeX documentation and UML diagrams for StegoCloud
- Render UML diagrams as vector SVG->PDF (sharp at any zoom) with Polish glyphs
- Add document purpose section, fix DCT/DWT-DCT-SVD wording, align AI example, add usage flow
- Replace raster PNG diagrams with vector PDFs
* docs(readme): enhance project overview and technical details, update quick start and demo accounts

* chore(docker): add TESTCONTAINERS_HOST_OVERRIDE for local testing

* delete .idea

* delete WYMAGANIA.md

* docs: update project documentation structure and add README

* feat: refactor watermark console components and improve structure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants