fix(clients): handle delayed-start expiry in bulk adjust

Negative ExpiryTime encodes a delay duration (magnitude = ms until
the trial begins on first use). Adding positive addDays was simply
arithmetically added, so e.g. a -7d delay + 30d turned into +23d
since epoch (1970), making the client instantly expired.

Branch on sign now: positive ExpiryTime extends additively, negative
extends by subtracting so the value stays negative (more delay).
Cross-sign reductions are skipped with an explicit reason instead of
silently corrupting the field.
This commit is contained in:
MHSanaei 2026-05-23 16:09:52 +02:00
parent e8dc7192e1
commit d0b388db5b
No known key found for this signature in database
GPG key ID: 7E4060F2FBE5AB7A

View file

@ -846,11 +846,25 @@ func (s *ClientService) BulkAdjust(inboundSvc *InboundService, emails []string,
applied := false
if addDays != 0 {
if rec.ExpiryTime == 0 {
switch {
case rec.ExpiryTime == 0:
result.Skipped = append(result.Skipped, BulkAdjustReport{Email: email, Reason: "unlimited expiry"})
} else {
client.ExpiryTime = rec.ExpiryTime + addExpiryMs
applied = true
case rec.ExpiryTime > 0:
next := rec.ExpiryTime + addExpiryMs
if next <= 0 {
result.Skipped = append(result.Skipped, BulkAdjustReport{Email: email, Reason: "reduction exceeds remaining time"})
} else {
client.ExpiryTime = next
applied = true
}
default:
next := rec.ExpiryTime - addExpiryMs
if next >= 0 {
result.Skipped = append(result.Skipped, BulkAdjustReport{Email: email, Reason: "reduction exceeds delay window"})
} else {
client.ExpiryTime = next
applied = true
}
}
}
if addBytes != 0 {