fix(push): InternalPushController 补传 deviceId;设备换绑时驱逐原用户
- InternalPushController.testOffline 补传 deviceId=null,修复编译失败 - DeviceTokenRepository 新增 findByAppKeyAndDeviceId / findByAppKeyAndToken - registerToken 在同 appKey 下同设备/同 token 被新用户注册时, 自动删除旧用户的 push token,防止旧用户继续收到新用户的消息 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
68f6145c71
当前提交
b4c236d234
@ -96,6 +96,7 @@ public class InternalPushController {
|
|||||||
PushDiagnosticsService.TestPushResult result = diagnosticsService.sendTestOfflineMessage(
|
PushDiagnosticsService.TestPushResult result = diagnosticsService.sendTestOfflineMessage(
|
||||||
request.appKey(),
|
request.appKey(),
|
||||||
request.userId(),
|
request.userId(),
|
||||||
|
null,
|
||||||
request.title(),
|
request.title(),
|
||||||
request.body(),
|
request.body(),
|
||||||
request.payload());
|
request.payload());
|
||||||
|
|||||||
@ -19,4 +19,8 @@ public interface DeviceTokenRepository extends JpaRepository<DeviceTokenEntity,
|
|||||||
List<DeviceTokenEntity> findByAppKeyAndUserIdOrderByLastLoginAtDescUpdatedAtDesc(String appKey, String userId);
|
List<DeviceTokenEntity> findByAppKeyAndUserIdOrderByLastLoginAtDescUpdatedAtDesc(String appKey, String userId);
|
||||||
void deleteByAppKeyAndUserIdAndVendor(String appKey, String userId, DeviceTokenEntity.Vendor vendor);
|
void deleteByAppKeyAndUserIdAndVendor(String appKey, String userId, DeviceTokenEntity.Vendor vendor);
|
||||||
void deleteByAppKeyAndUserIdAndDeviceId(String appKey, String userId, String deviceId);
|
void deleteByAppKeyAndUserIdAndDeviceId(String appKey, String userId, String deviceId);
|
||||||
|
// Find device by appKey+deviceId regardless of userId (for cross-user eviction)
|
||||||
|
Optional<DeviceTokenEntity> findByAppKeyAndDeviceId(String appKey, String deviceId);
|
||||||
|
// Find device by appKey+token regardless of userId (token rotation detection)
|
||||||
|
Optional<DeviceTokenEntity> findByAppKeyAndToken(String appKey, String token);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -246,6 +246,23 @@ public class PushDispatcher {
|
|||||||
String appVersion,
|
String appVersion,
|
||||||
String romVersion) {
|
String romVersion) {
|
||||||
String resolvedDeviceId = normalizeDeviceId(deviceId, vendor, token);
|
String resolvedDeviceId = normalizeDeviceId(deviceId, vendor, token);
|
||||||
|
|
||||||
|
// Evict previous owner: if this device (by deviceId OR token) is registered to another user, remove it
|
||||||
|
tokenRepository.findByAppKeyAndDeviceId(appKey, resolvedDeviceId)
|
||||||
|
.filter(prev -> !userId.equals(prev.getUserId()))
|
||||||
|
.ifPresent(prev -> {
|
||||||
|
log.info("Device {} re-registered by new user={}, evicting previous user={}", resolvedDeviceId, userId, prev.getUserId());
|
||||||
|
recordLog(prev, DeviceLoginLogEntity.EventType.UNREGISTER);
|
||||||
|
tokenRepository.delete(prev);
|
||||||
|
});
|
||||||
|
tokenRepository.findByAppKeyAndToken(appKey, token)
|
||||||
|
.filter(prev -> !userId.equals(prev.getUserId()))
|
||||||
|
.ifPresent(prev -> {
|
||||||
|
log.info("Token re-registered by new user={}, evicting previous user={} deviceId={}", userId, prev.getUserId(), prev.getDeviceId());
|
||||||
|
recordLog(prev, DeviceLoginLogEntity.EventType.UNREGISTER);
|
||||||
|
tokenRepository.delete(prev);
|
||||||
|
});
|
||||||
|
|
||||||
Optional<DeviceTokenEntity> existing = tokenRepository.findByAppKeyAndUserIdAndDeviceId(appKey, userId, resolvedDeviceId);
|
Optional<DeviceTokenEntity> existing = tokenRepository.findByAppKeyAndUserIdAndDeviceId(appKey, userId, resolvedDeviceId);
|
||||||
if (existing.isEmpty() && (deviceId == null || deviceId.isBlank())) {
|
if (existing.isEmpty() && (deviceId == null || deviceId.isBlank())) {
|
||||||
existing = tokenRepository.findByAppKeyAndUserIdAndVendor(appKey, userId, vendor);
|
existing = tokenRepository.findByAppKeyAndUserIdAndVendor(appKey, userId, vendor);
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户