SdkConfigController: require packageName param; reject with 403 if it doesn't
match the platform-specific name registered for the app (skipped when app has
no name configured yet).
LicensePublicController: add required packageName to register/verify requests.
DeviceService: validatePackageName() checks against android/ios/harmony names
stored on AppLicenseEntity; rejects if any are configured and none match.
AppLicenseEntity: add android_package_name, ios_bundle_id, harmony_bundle_name
columns (auto-migrated via ddl-auto=update).
LicenseInternalController/AppLicenseService: accept and persist package names
via upsert endpoint.
LicenseServiceClient/FeatureServiceManager: pass app package names when syncing
license records to license-service.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
application.yml — all services:
- Replace hardcoded jdbc:mysql://39.107.53.187 with ${SPRING_DATASOURCE_URL:fallback}
- Same for SPRING_DATASOURCE_USERNAME/PASSWORD
- im-service: replace hardcoded redisdev.xuqinmin.com with ${SPRING_DATA_REDIS_*}
This ensures docker-compose environment overrides take effect; without these
placeholders, Spring Boot's relaxed binding couldn't override the YAML values
and the private deployment connected to production databases.
StoreSubmissionService.refreshStoreReviewStatus — two bugs fixed:
1. MI/UNDER_REVIEW_XIAOMI branch now guards against downgrading APPROVED state.
Xiaomi's poll API returns UNDER_REVIEW_XIAOMI when the submitted version is
not yet the live version, even after the store approves it. Previously this
caused the manual refresh to overwrite a webhook-confirmed APPROVED with
UNDER_REVIEW on every click.
2. When the poll returns APPROVED but currentSubmissionLive=false (another version
is live on the store), no longer overwrite an existing APPROVED (from webhook)
with nonCurrentRelease=true. The webhook is authoritative; the live version
difference just means distribution is pending, not that this is a non-current
release. Only adds nonCurrentRelease when transitioning FROM a non-APPROVED
state (true pre-existing detection).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Spring Security's default Http403ForbiddenEntryPoint was returning 403
for all auth failures. Frontend clients treat 403 as a permission error
(not an auth error), so silent loops occurred instead of proper re-login.
Adding a custom AuthenticationEntryPoint that returns 401 makes clients
handle auth failures correctly (show login page on 401).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- LicenseDeviceService: update app_key on re-registration if blank,
fixing devices that registered before the app_key column was added
- FeatureServiceManager: send activation IM notification in afterCommit()
hook so the frontend refresh sees the committed DB state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>