From bfc27def5763b5fb58f70630fef2b1e81d49f2a4 Mon Sep 17 00:00:00 2001 From: Kailash Nadh Date: Sat, 30 Jul 2022 20:11:59 +0530 Subject: [PATCH] Fix regression of public subscriber page behaviour. --- cmd/public.go | 12 +++++++++++- cmd/subscribers.go | 4 ++-- internal/core/subscribers.go | 7 ++++--- queries.sql | 11 ++++++++--- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/cmd/public.go b/cmd/public.go index f906119..60a9b32 100644 --- a/cmd/public.go +++ b/cmd/public.go @@ -325,9 +325,19 @@ func handleSubscriptionForm(c echo.Context) error { // Insert the subscriber into the DB. req.Status = models.SubscriberStatusEnabled req.ListUUIDs = pq.StringArray(req.SubListUUIDs) - _, hasOptin, err := app.core.CreateSubscriber(req.SubReq.Subscriber, nil, req.ListUUIDs, false) + _, hasOptin, err := app.core.InsertSubscriber(req.SubReq.Subscriber, nil, req.ListUUIDs, false) if err != nil { + // Subscriber already exists. Update subscriptions. if e, ok := err.(*echo.HTTPError); ok && e.Code == http.StatusConflict { + sub, err := app.core.GetSubscriber(0, "", req.Email) + if err != nil { + return err + } + + if _, err := app.core.UpdateSubscriber(sub.ID, sub, nil, req.ListUUIDs, false); err != nil { + return err + } + return c.Render(http.StatusOK, tplMessage, makeMsgTpl(app.i18n.T("public.subTitle"), "", app.i18n.Ts(msg))) } diff --git a/cmd/subscribers.go b/cmd/subscribers.go index 30e39f5..4ac9781 100644 --- a/cmd/subscribers.go +++ b/cmd/subscribers.go @@ -212,7 +212,7 @@ func handleCreateSubscriber(c echo.Context) error { } // Insert the subscriber into the DB. - sub, _, err := app.core.CreateSubscriber(req.Subscriber, req.Lists, req.ListUUIDs, req.PreconfirmSubs) + sub, _, err := app.core.InsertSubscriber(req.Subscriber, req.Lists, req.ListUUIDs, req.PreconfirmSubs) if err != nil { return err } @@ -251,7 +251,7 @@ func handleUpdateSubscriber(c echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("subscribers.invalidName")) } - out, err := app.core.UpdateSubscriber(id, req.Subscriber, req.Lists, req.PreconfirmSubs) + out, err := app.core.UpdateSubscriber(id, req.Subscriber, req.Lists, nil, req.PreconfirmSubs) if err != nil { return err } diff --git a/internal/core/subscribers.go b/internal/core/subscribers.go index 2ce48cd..597ad44 100644 --- a/internal/core/subscribers.go +++ b/internal/core/subscribers.go @@ -235,10 +235,10 @@ func (c *Core) ExportSubscribers(query string, subIDs, listIDs []int, batchSize }, nil } -// insertSubscriber inserts a subscriber and returns the ID. The first bool indicates if +// InsertSubscriber inserts a subscriber and returns the ID. The first bool indicates if // it was a new subscriber, and the second bool indicates if the subscriber was sent an optin confirmation. // bool = optinSent? -func (c *Core) CreateSubscriber(sub models.Subscriber, listIDs []int, listUUIDs []string, preconfirm bool) (models.Subscriber, bool, error) { +func (c *Core) InsertSubscriber(sub models.Subscriber, listIDs []int, listUUIDs []string, preconfirm bool) (models.Subscriber, bool, error) { uu, err := uuid.NewV4() if err != nil { c.log.Printf("error generating UUID: %v", err) @@ -302,7 +302,7 @@ func (c *Core) CreateSubscriber(sub models.Subscriber, listIDs []int, listUUIDs } // UpdateSubscriber updates a subscriber's properties. -func (c *Core) UpdateSubscriber(id int, sub models.Subscriber, listIDs []int, preconfirm bool) (models.Subscriber, error) { +func (c *Core) UpdateSubscriber(id int, sub models.Subscriber, listIDs []int, listUUIDs []string, preconfirm bool) (models.Subscriber, error) { subStatus := models.SubscriptionStatusUnconfirmed if preconfirm { subStatus = models.SubscriptionStatusConfirmed @@ -326,6 +326,7 @@ func (c *Core) UpdateSubscriber(id int, sub models.Subscriber, listIDs []int, pr sub.Status, json.RawMessage(attribs), pq.Array(listIDs), + pq.Array(listUUIDs), subStatus) if err != nil { c.log.Printf("error updating subscriber: %v", err) diff --git a/queries.sql b/queries.sql index ce5a4ec..c021778 100644 --- a/queries.sql +++ b/queries.sql @@ -55,7 +55,7 @@ SELECT id as subscriber_id, WITH sub AS ( INSERT INTO subscribers (uuid, email, name, status, attribs) VALUES($1, $2, $3, $4, $5) - returning id, status + RETURNING id, status ), listIDs AS ( SELECT id FROM lists WHERE @@ -128,12 +128,17 @@ WITH s AS ( ), d AS ( DELETE FROM subscriber_lists WHERE subscriber_id = $1 AND list_id != ALL($6) +), +listIDs AS ( + SELECT id FROM lists WHERE + (CASE WHEN CARDINALITY($6::INT[]) > 0 THEN id=ANY($6) + ELSE uuid=ANY($7::UUID[]) END) ) INSERT INTO subscriber_lists (subscriber_id, list_id, status) VALUES( (SELECT id FROM s), - UNNEST($6), - (CASE WHEN $4='blocklisted' THEN 'unsubscribed'::subscription_status ELSE $7::subscription_status END) + UNNEST(ARRAY(SELECT id FROM listIDs)), + (CASE WHEN $4='blocklisted' THEN 'unsubscribed'::subscription_status ELSE $8::subscription_status END) ) ON CONFLICT (subscriber_id, list_id) DO UPDATE SET status = (CASE WHEN $4='blocklisted' THEN 'unsubscribed'::subscription_status ELSE subscriber_lists.status END);