Unify the native JSONB query and findAllBy dual path through
JpaSpecificationExecutor:
- add ModificationSpecification for firearm and tag filters
- eagerly fetch the firearm association via entity graph
- filter by the firearm id attribute instead of a missing top-level field
- Introduce ModificationStatus enum with integer codes and a JPA converter
- Record the creating user on new modifications
- Rebuild the modification table with status, creator and audit columns
- Simplify user_role to a single-column primary key
- Add POST /auth/verification-code endpoint to email a code
- Store codes in Redis and verify them during registration
- Send verification emails asynchronously via Thymeleaf
- Replace email_verified column with code-based verification
- Group dependencies into version catalogue bundles
- Validate username, email and password on register
- Reject duplicate usernames and email addresses
- Create user with LOCAL credential and default USER role
Closes#3
- Load the user's role during authentication and expose it as
a granted authority on the authenticated token
- Add @RequiresAdmin and @RequiresSuperUser method-level
annotations for role-gated endpoints
- Introduce a shared BaseRepository with specification support
- Replace Example-based credential queries with JPA specifications
- Rename GitHubWebhookController to WebhookController
- Move class-level mapping from /webhooks/github to /webhooks
- Scope the GitHub endpoint to /webhooks/github via @PostMapping
- remove custom RequiresRole annotation and RoleBasedAuthorizationManager
- replace @RequiresRole with @PreAuthorize("hasRole('SUPER_USER')") in AdminController
- remove requiresRoleAdvisor bean from SecurityConfig
- add GET/PUT /user/me endpoints for profile viewing and editing
- add PUT /user/me/password endpoint for password changes
- add GET /user/me/builds skeleton endpoint for future CustomModification
- add user_role table with ROLE_USER, ROLE_ADMIN, and ROLE_SUPER_USER roles
- add @RequiresRole annotation with custom AuthorizationManager enforcement
- extend User entity with nickname, avatarUrl, emailVerified, enabled,
createdAt, and updatedAt columns
- load user roles into SecurityContext authorities via TokenAuthenticationFilter
- add @CurrentUser annotation and argument resolver for controller injection
- add PUT/DELETE /admin/users/{id}/roles for SUPER_USER role management
- add V6 and V7 Flyway migrations for schema changes
Closes#5Closes#8
Replace default Spring Security 403 responses with custom 401 (not logged in)
and 403 (insufficient permissions) JSON error responses via exception handling
and global exception handler. Also bump API version to 1.4.0 and add Swagger
annotations for the GitHub webhook controller.
Replace hardcoded AppProperties values with Gradle ${} placeholders,
allowing version/channel/vendor to be configured via gradle.properties
or -P flags at build time.
Also refactor webhook configuration to flatten the properties hierarchy
by removing the intermediate WebhookProperties wrapper.
When firearmId is absent from the YAML block, resolveFirearmId falls back
to firearmName lookup via FirearmRepository.findByName(). If both are
present, firearmId takes precedence.
Only issues submitted by users in the allowed-users list are processed.
An empty or null list allows all senders (no filtering). Checks
sender.login from the webhook payload against the configured list.
GitLab webhook has been superseded by the GitHub webhook implementation.
Remove WebhookController (formerly GitLabWebhookController),
GitLabWebhookRequest DTO, and GitLabWebhookInterceptor.
WebhookService parses YAML-fenced issue body, filters by "weapon-mod"
label, deduplicates via Redis SETNX with 12h TTL, and delegates to
ModificationManager for single/batch creation.
GitHubWebhookController verifies X-GitHub-Event=issues and action=opened
before delegating to the service.
Register GitHubWebhookInterceptor for /webhooks/github in AppConfig.
Move create/batchCreate transactional logic from ModificationService into
a dedicated ModificationManager. Both ModificationService and WebhookService
delegate to the manager, respecting the Controller -> Service -> Manager
layering rule.
Verify X-Hub-Signature-256 header using CryptoUtil.hmacSha256 from
onixbyte crypto-toolbox. Signature check is skipped when no secret is
configured. Uses MessageDigest.isEqual for constant-time comparison.
Replace GitLabWebhookProperties with GitHubWebhookProperties (secret, allowed-users).
Update WebhookProperties and WebhookManager to use GitHub-only configuration.
Add app.webhook.github defaults to application.yaml.
Replace GitHubIssueLabeledWebhookRequest with GitHubIssueRequest.
Add number and repository fields for dedup key construction.
Add Jackson @JsonNaming/@JsonIgnoreProperties for GitHub payload deserialisation.
Add GitHubWebhookHeader constants for webhook header names.