fix(webpush): update existing subscriptions with new keys only if the endpoint matches and the auth differs
Signed-off-by: 0xsysr3ll <0xsysr3ll@pm.me>
This commit is contained in:
@@ -204,34 +204,14 @@ router.post<
|
|||||||
return res.status(204).send();
|
return res.status(204).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
// iOS can refresh auth keys but keep same endpoint
|
|
||||||
const existingByEndpoint = await userPushSubRepository.findOne({
|
|
||||||
relations: { user: true },
|
|
||||||
where: { endpoint: req.body.endpoint, user: { id: req.user?.id } },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (existingByEndpoint) {
|
|
||||||
// Update existing subscription with new keys
|
|
||||||
existingByEndpoint.auth = req.body.auth;
|
|
||||||
existingByEndpoint.p256dh = req.body.p256dh;
|
|
||||||
existingByEndpoint.userAgent = req.body.userAgent;
|
|
||||||
|
|
||||||
await userPushSubRepository.save(existingByEndpoint);
|
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
'Updated existing push subscription with new keys for same endpoint.',
|
|
||||||
{ label: 'API' }
|
|
||||||
);
|
|
||||||
return res.status(204).send();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This prevents race conditions where two requests both pass the checks
|
// This prevents race conditions where two requests both pass the checks
|
||||||
await dataSource.transaction(
|
await dataSource.transaction(
|
||||||
async (transactionalEntityManager: EntityManager) => {
|
async (transactionalEntityManager: EntityManager) => {
|
||||||
const transactionalRepo =
|
const transactionalRepo =
|
||||||
transactionalEntityManager.getRepository(UserPushSubscription);
|
transactionalEntityManager.getRepository(UserPushSubscription);
|
||||||
|
|
||||||
const finalCheck = await transactionalRepo.findOne({
|
// Check for existing subscription by auth or endpoint within transaction
|
||||||
|
const existingSubscription = await transactionalRepo.findOne({
|
||||||
relations: { user: true },
|
relations: { user: true },
|
||||||
where: [
|
where: [
|
||||||
{ auth: req.body.auth, user: { id: req.user?.id } },
|
{ auth: req.body.auth, user: { id: req.user?.id } },
|
||||||
@@ -239,7 +219,25 @@ router.post<
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (finalCheck) {
|
if (existingSubscription) {
|
||||||
|
// If endpoint matches but auth is different, update with new keys (iOS refresh case)
|
||||||
|
if (
|
||||||
|
existingSubscription.endpoint === req.body.endpoint &&
|
||||||
|
existingSubscription.auth !== req.body.auth
|
||||||
|
) {
|
||||||
|
existingSubscription.auth = req.body.auth;
|
||||||
|
existingSubscription.p256dh = req.body.p256dh;
|
||||||
|
existingSubscription.userAgent = req.body.userAgent;
|
||||||
|
|
||||||
|
await transactionalRepo.save(existingSubscription);
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
'Updated existing push subscription with new keys for same endpoint.',
|
||||||
|
{ label: 'API' }
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'Duplicate subscription detected. Skipping registration.',
|
'Duplicate subscription detected. Skipping registration.',
|
||||||
{ label: 'API' }
|
{ label: 'API' }
|
||||||
|
|||||||
Reference in New Issue
Block a user