christianselig-apollo-backend/internal/api/receipt.go

79 lines
1.9 KiB
Go

package api
import (
"context"
"encoding/json"
"io/ioutil"
"net/http"
"time"
"github.com/gorilla/mux"
"go.uber.org/zap"
"github.com/christianselig/apollo-backend/internal/domain"
"github.com/christianselig/apollo-backend/internal/itunes"
)
func (a *api) checkReceiptHandler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithCancel(r.Context())
defer cancel()
vars := mux.Vars(r)
apns := vars["apns"]
body, _ := ioutil.ReadAll(r.Body)
iapr, err := itunes.NewIAPResponse(string(body), true)
if err != nil {
// treat as if it's a valid subscription, given that this is not the user's fault
if apns != "" {
dev, err := a.deviceRepo.GetByAPNSToken(ctx, apns)
if err != nil {
a.errorResponse(w, r, 500, err)
return
}
dev.ExpiresAt = time.Now().Add(domain.DeviceActiveAfterReceitCheckDuration)
dev.GracePeriodExpiresAt = dev.ExpiresAt.Add(domain.DeviceGracePeriodAfterReceiptExpiry)
_ = a.deviceRepo.Update(ctx, &dev)
}
a.logger.Info("failed to verify receipt", zap.Error(err))
a.errorResponse(w, r, 500, err)
return
}
if apns != "" {
dev, err := a.deviceRepo.GetByAPNSToken(ctx, apns)
if err != nil {
a.errorResponse(w, r, 500, err)
return
}
if iapr.DeleteDevice {
if dev.GracePeriodExpiresAt.Before(time.Now()) {
accs, err := a.accountRepo.GetByAPNSToken(ctx, apns)
if err != nil {
a.errorResponse(w, r, 500, err)
return
}
for _, acc := range accs {
_ = a.accountRepo.Disassociate(ctx, &acc, &dev)
}
_ = a.deviceRepo.Delete(ctx, apns)
}
} else {
dev.ExpiresAt = time.Now().Add(domain.DeviceActiveAfterReceitCheckDuration)
dev.GracePeriodExpiresAt = dev.ExpiresAt.Add(domain.DeviceGracePeriodAfterReceiptExpiry)
_ = a.deviceRepo.Update(ctx, &dev)
}
}
w.WriteHeader(http.StatusOK)
bb, _ := json.Marshal(iapr.VerificationInfo)
_, _ = w.Write(bb)
}